@hkdigital/lib-core 0.4.18 → 0.4.20
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/dist/services/README.md +254 -47
- package/dist/services/manager-plugins/ConfigPlugin.d.ts +68 -0
- package/dist/services/manager-plugins/ConfigPlugin.js +329 -0
- package/dist/services/service-base/ServiceBase.d.ts +59 -22
- package/dist/services/service-base/ServiceBase.js +139 -61
- package/dist/services/service-base/constants.d.ts +30 -14
- package/dist/services/service-base/constants.js +42 -14
- package/dist/services/service-base/typedef.d.ts +15 -9
- package/dist/services/service-base/typedef.js +33 -11
- package/dist/services/service-manager/ServiceManager.d.ts +25 -5
- package/dist/services/service-manager/ServiceManager.js +103 -20
- package/dist/services/service-manager/constants.js +0 -1
- package/dist/services/service-manager/typedef.d.ts +36 -14
- package/dist/services/service-manager/typedef.js +30 -13
- package/dist/util/sveltekit/env/README.md +424 -0
- package/dist/util/sveltekit/env/all.d.ts +54 -0
- package/dist/util/sveltekit/env/all.js +97 -0
- package/dist/util/sveltekit/env/parsers.d.ts +135 -0
- package/dist/util/sveltekit/env/parsers.js +257 -0
- package/dist/util/sveltekit/env/private.d.ts +56 -0
- package/dist/util/sveltekit/env/private.js +87 -0
- package/dist/util/sveltekit/env/public.d.ts +52 -0
- package/dist/util/sveltekit/env/public.js +82 -0
- package/dist/util/sveltekit/env-all.d.ts +1 -0
- package/dist/util/sveltekit/env-all.js +19 -0
- package/dist/util/sveltekit/env-private.d.ts +1 -0
- package/dist/util/sveltekit/env-private.js +18 -0
- package/dist/util/sveltekit/env-public.d.ts +1 -0
- package/dist/util/sveltekit/env-public.js +18 -0
- package/package.json +1 -1
- package/dist/util/index.js__ +0 -20
- package/dist/util/sveltekit/index.d.ts +0 -0
- package/dist/util/sveltekit/index.js +0 -0
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* import { ServiceBase } from './ServiceBase.js';
|
|
12
12
|
*
|
|
13
13
|
* class DatabaseService extends ServiceBase {
|
|
14
|
-
* async
|
|
15
|
-
* this.connectionString = config.
|
|
14
|
+
* async _configure(newConfig, oldConfig) {
|
|
15
|
+
* this.connectionString = config.newConfig;
|
|
16
16
|
* }
|
|
17
17
|
*
|
|
18
18
|
* async _start() {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
*
|
|
27
27
|
* // Usage
|
|
28
28
|
* const db = new DatabaseService('database');
|
|
29
|
-
* await db.
|
|
29
|
+
* await db.configure({ connectionString: 'postgres://...' });
|
|
30
30
|
* await db.start();
|
|
31
31
|
*
|
|
32
32
|
* // Listen to events
|
|
@@ -55,24 +55,27 @@ import { Logger, INFO } from '../../logging/index.js';
|
|
|
55
55
|
import { DetailedError } from '../../generic/errors.js';
|
|
56
56
|
|
|
57
57
|
import {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
STATE_CREATED,
|
|
59
|
+
STATE_CONFIGURING,
|
|
60
|
+
STATE_CONFIGURED,
|
|
61
|
+
STATE_STARTING,
|
|
62
|
+
STATE_RUNNING,
|
|
63
|
+
STATE_STOPPING,
|
|
64
|
+
STATE_STOPPED,
|
|
65
|
+
STATE_DESTROYING,
|
|
66
|
+
STATE_DESTROYED,
|
|
67
|
+
STATE_ERROR,
|
|
68
|
+
STATE_RECOVERING,
|
|
69
|
+
EVENT_STATE_CHANGED,
|
|
70
|
+
EVENT_TARGET_STATE_CHANGED,
|
|
71
|
+
EVENT_HEALTH_CHANGED,
|
|
72
|
+
EVENT_ERROR
|
|
69
73
|
} from './constants.js';
|
|
70
74
|
|
|
71
75
|
/**
|
|
72
|
-
* @typedef {import('./typedef.js').
|
|
73
|
-
* @typedef {import('./typedef.js').StopOptions} StopOptions
|
|
74
|
-
* @typedef {import('./typedef.js').HealthStatus} HealthStatus
|
|
76
|
+
* @typedef {import('./typedef.js').ServiceState} ServiceState
|
|
75
77
|
* @typedef {import('./typedef.js').StateChangeEvent} StateChangeEvent
|
|
78
|
+
* @typedef {import('./typedef.js').TargetStateChangeEvent} TargetStateChangeEvent
|
|
76
79
|
* @typedef {import('./typedef.js').HealthChangeEvent} HealthChangeEvent
|
|
77
80
|
* @typedef {import('./typedef.js').ServiceErrorEvent} ServiceErrorEvent
|
|
78
81
|
*/
|
|
@@ -82,11 +85,14 @@ import {
|
|
|
82
85
|
* @extends EventEmitter
|
|
83
86
|
*/
|
|
84
87
|
export class ServiceBase extends EventEmitter {
|
|
88
|
+
/** @type {*} */
|
|
89
|
+
#lastConfig = null;
|
|
90
|
+
|
|
85
91
|
/**
|
|
86
92
|
* Create a new service instance
|
|
87
93
|
*
|
|
88
94
|
* @param {string} name - Service name
|
|
89
|
-
* @param {ServiceOptions} [options={}] - Service options
|
|
95
|
+
* @param {import('./typedef.js').ServiceOptions} [options={}] - Service options
|
|
90
96
|
*/
|
|
91
97
|
constructor(name, options = {}) {
|
|
92
98
|
super();
|
|
@@ -94,8 +100,11 @@ export class ServiceBase extends EventEmitter {
|
|
|
94
100
|
/** @type {string} */
|
|
95
101
|
this.name = name;
|
|
96
102
|
|
|
97
|
-
/** @type {
|
|
98
|
-
this.state =
|
|
103
|
+
/** @type {ServiceState} */
|
|
104
|
+
this.state = STATE_CREATED;
|
|
105
|
+
|
|
106
|
+
/** @type {ServiceState} */
|
|
107
|
+
this.targetState = STATE_CREATED;
|
|
99
108
|
|
|
100
109
|
/** @type {boolean} */
|
|
101
110
|
this.healthy = false;
|
|
@@ -111,33 +120,39 @@ export class ServiceBase extends EventEmitter {
|
|
|
111
120
|
}
|
|
112
121
|
|
|
113
122
|
/**
|
|
114
|
-
*
|
|
123
|
+
* Configure the service with configuration
|
|
115
124
|
*
|
|
116
125
|
* @param {*} [config={}] - Service-specific configuration
|
|
117
126
|
*
|
|
118
|
-
* @returns {Promise<boolean>} True if
|
|
127
|
+
* @returns {Promise<boolean>} True if configuration succeeded
|
|
119
128
|
*/
|
|
120
|
-
async
|
|
129
|
+
async configure(config = {}) {
|
|
121
130
|
if (
|
|
122
|
-
this.state !==
|
|
123
|
-
this.state !==
|
|
124
|
-
this.state !==
|
|
131
|
+
this.state !== STATE_CREATED &&
|
|
132
|
+
this.state !== STATE_CONFIGURED &&
|
|
133
|
+
this.state !== STATE_RUNNING &&
|
|
134
|
+
this.state !== STATE_STOPPED &&
|
|
135
|
+
this.state !== STATE_DESTROYED
|
|
125
136
|
) {
|
|
126
|
-
this.logger.warn(`Cannot
|
|
137
|
+
this.logger.warn(`Cannot configure from state: ${this.state}`);
|
|
127
138
|
return false;
|
|
128
139
|
}
|
|
129
140
|
|
|
141
|
+
const wasRunning = this.state === STATE_RUNNING;
|
|
142
|
+
|
|
130
143
|
try {
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
144
|
+
this._setTargetState(wasRunning ? STATE_RUNNING : STATE_CONFIGURED);
|
|
145
|
+
this._setState(STATE_CONFIGURING);
|
|
146
|
+
this.logger.debug('Configuring service', { config });
|
|
133
147
|
|
|
134
|
-
await this.
|
|
148
|
+
await this._configure(config, this.#lastConfig);
|
|
149
|
+
this.#lastConfig = config;
|
|
135
150
|
|
|
136
|
-
this._setState(
|
|
137
|
-
this.logger.info('Service
|
|
151
|
+
this._setState(wasRunning ? STATE_RUNNING : STATE_CONFIGURED);
|
|
152
|
+
this.logger.info('Service configured');
|
|
138
153
|
return true;
|
|
139
154
|
} catch (error) {
|
|
140
|
-
this._setError('
|
|
155
|
+
this._setError('configuration', error);
|
|
141
156
|
return false;
|
|
142
157
|
}
|
|
143
158
|
}
|
|
@@ -148,18 +163,19 @@ export class ServiceBase extends EventEmitter {
|
|
|
148
163
|
* @returns {Promise<boolean>} True if the service started successfully
|
|
149
164
|
*/
|
|
150
165
|
async start() {
|
|
151
|
-
if (this.state !==
|
|
166
|
+
if (this.state !== STATE_CONFIGURED && this.state !== STATE_STOPPED) {
|
|
152
167
|
this.logger.warn(`Cannot start from state: ${this.state}`);
|
|
153
168
|
return false;
|
|
154
169
|
}
|
|
155
170
|
|
|
156
171
|
try {
|
|
157
|
-
this.
|
|
172
|
+
this._setTargetState(STATE_RUNNING);
|
|
173
|
+
this._setState(STATE_STARTING);
|
|
158
174
|
this.logger.debug('Starting service');
|
|
159
175
|
|
|
160
176
|
await this._start();
|
|
161
177
|
|
|
162
|
-
this._setState(
|
|
178
|
+
this._setState(STATE_RUNNING);
|
|
163
179
|
this._setHealthy(true);
|
|
164
180
|
this.logger.info('Service started');
|
|
165
181
|
return true;
|
|
@@ -172,12 +188,12 @@ export class ServiceBase extends EventEmitter {
|
|
|
172
188
|
/**
|
|
173
189
|
* Stop the service with optional timeout
|
|
174
190
|
*
|
|
175
|
-
* @param {StopOptions} [options={}] - Stop options
|
|
191
|
+
* @param {import('./typedef.js').StopOptions} [options={}] - Stop options
|
|
176
192
|
*
|
|
177
193
|
* @returns {Promise<boolean>} True if the service stopped successfully
|
|
178
194
|
*/
|
|
179
195
|
async stop(options = {}) {
|
|
180
|
-
if (this.state !==
|
|
196
|
+
if (this.state !== STATE_RUNNING && this.state !== STATE_ERROR) {
|
|
181
197
|
this.logger.warn(`Cannot stop from state: ${this.state}`);
|
|
182
198
|
return true; // Already stopped
|
|
183
199
|
}
|
|
@@ -185,7 +201,8 @@ export class ServiceBase extends EventEmitter {
|
|
|
185
201
|
const timeout = options.timeout ?? this._shutdownTimeout;
|
|
186
202
|
|
|
187
203
|
try {
|
|
188
|
-
this.
|
|
204
|
+
this._setTargetState(STATE_STOPPED);
|
|
205
|
+
this._setState(STATE_STOPPING);
|
|
189
206
|
this._setHealthy(false);
|
|
190
207
|
this.logger.debug('Stopping service');
|
|
191
208
|
|
|
@@ -203,13 +220,13 @@ export class ServiceBase extends EventEmitter {
|
|
|
203
220
|
await stopPromise;
|
|
204
221
|
}
|
|
205
222
|
|
|
206
|
-
this._setState(
|
|
223
|
+
this._setState(STATE_STOPPED);
|
|
207
224
|
this.logger.info('Service stopped');
|
|
208
225
|
return true;
|
|
209
226
|
} catch (error) {
|
|
210
227
|
if (error.message === 'Shutdown timeout' && options.force) {
|
|
211
228
|
this.logger.warn('Forced shutdown after timeout');
|
|
212
|
-
this._setState(
|
|
229
|
+
this._setState(STATE_STOPPED);
|
|
213
230
|
return true;
|
|
214
231
|
}
|
|
215
232
|
this._setError('shutdown', error);
|
|
@@ -223,7 +240,7 @@ export class ServiceBase extends EventEmitter {
|
|
|
223
240
|
* @returns {Promise<boolean>} True if recovery succeeded
|
|
224
241
|
*/
|
|
225
242
|
async recover() {
|
|
226
|
-
if (this.state !==
|
|
243
|
+
if (this.state !== STATE_ERROR) {
|
|
227
244
|
this.logger.warn(
|
|
228
245
|
`Can only recover from ERROR state, current: ${this.state}`
|
|
229
246
|
);
|
|
@@ -231,17 +248,18 @@ export class ServiceBase extends EventEmitter {
|
|
|
231
248
|
}
|
|
232
249
|
|
|
233
250
|
try {
|
|
234
|
-
this.
|
|
251
|
+
this._setTargetState(STATE_RUNNING);
|
|
252
|
+
this._setState(STATE_RECOVERING);
|
|
235
253
|
this.logger.info('Attempting recovery');
|
|
236
254
|
|
|
237
255
|
// Try custom recovery first
|
|
238
256
|
if (this._recover) {
|
|
239
257
|
await this._recover();
|
|
240
|
-
this._setState(
|
|
258
|
+
this._setState(STATE_RUNNING);
|
|
241
259
|
this._setHealthy(true);
|
|
242
260
|
} else {
|
|
243
261
|
// Default: restart
|
|
244
|
-
this._setState(
|
|
262
|
+
this._setState(STATE_STOPPED);
|
|
245
263
|
await this.start();
|
|
246
264
|
}
|
|
247
265
|
|
|
@@ -260,23 +278,24 @@ export class ServiceBase extends EventEmitter {
|
|
|
260
278
|
* @returns {Promise<boolean>} True if destruction succeeded
|
|
261
279
|
*/
|
|
262
280
|
async destroy() {
|
|
263
|
-
if (this.state ===
|
|
281
|
+
if (this.state === STATE_DESTROYED) {
|
|
264
282
|
return true;
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
try {
|
|
268
|
-
if (this.state ===
|
|
286
|
+
if (this.state === STATE_RUNNING) {
|
|
269
287
|
await this.stop();
|
|
270
288
|
}
|
|
271
289
|
|
|
272
|
-
this.
|
|
290
|
+
this._setTargetState(STATE_DESTROYED);
|
|
291
|
+
this._setState(STATE_DESTROYING);
|
|
273
292
|
this.logger.debug('Destroying service');
|
|
274
293
|
|
|
275
294
|
if (this._destroy) {
|
|
276
295
|
await this._destroy();
|
|
277
296
|
}
|
|
278
297
|
|
|
279
|
-
this._setState(
|
|
298
|
+
this._setState(STATE_DESTROYED);
|
|
280
299
|
this._setHealthy(false);
|
|
281
300
|
this.logger.info('Service destroyed');
|
|
282
301
|
|
|
@@ -294,7 +313,8 @@ export class ServiceBase extends EventEmitter {
|
|
|
294
313
|
/**
|
|
295
314
|
* Get the current health status of the service
|
|
296
315
|
*
|
|
297
|
-
* @returns {Promise<HealthStatus>}
|
|
316
|
+
* @returns {Promise<import('./typedef.js').HealthStatus>}
|
|
317
|
+
* Health status object
|
|
298
318
|
*/
|
|
299
319
|
async getHealth() {
|
|
300
320
|
const baseHealth = {
|
|
@@ -334,14 +354,39 @@ export class ServiceBase extends EventEmitter {
|
|
|
334
354
|
// Protected methods to override in subclasses
|
|
335
355
|
|
|
336
356
|
/**
|
|
337
|
-
*
|
|
357
|
+
* Configure the service (handles both initial config and reconfiguration)
|
|
338
358
|
*
|
|
339
359
|
* @protected
|
|
340
|
-
* @param {
|
|
360
|
+
* @param {any} newConfig - Configuration to apply
|
|
361
|
+
* @param {any} [oldConfig=null] - Previous config (null = initial setup)
|
|
341
362
|
*
|
|
342
363
|
* @returns {Promise<void>}
|
|
364
|
+
*
|
|
365
|
+
* @remarks
|
|
366
|
+
* This method is called both for initial setup and reconfiguration.
|
|
367
|
+
* When oldConfig is provided, you should:
|
|
368
|
+
* 1. Compare oldConfig vs newConfig to determine changes
|
|
369
|
+
* 2. Clean up resources that need replacing
|
|
370
|
+
* 3. Apply only the changes that are necessary
|
|
371
|
+
* 4. Preserve resources that don't need changing
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* async _configure(newConfig, oldConfig = null) {
|
|
375
|
+
* if (!oldConfig) {
|
|
376
|
+
* // Initial setup
|
|
377
|
+
* this.connection = new Connection(newConfig.url);
|
|
378
|
+
* return;
|
|
379
|
+
* }
|
|
380
|
+
*
|
|
381
|
+
* // Reconfiguration
|
|
382
|
+
* if (oldConfig.url !== newConfig.url) {
|
|
383
|
+
* await this.connection.close();
|
|
384
|
+
* this.connection = new Connection(newConfig.url);
|
|
385
|
+
* }
|
|
386
|
+
* }
|
|
343
387
|
*/
|
|
344
|
-
|
|
388
|
+
// eslint-disable-next-line no-unused-vars
|
|
389
|
+
async _configure(newConfig, oldConfig = null) {
|
|
345
390
|
// Override in subclass
|
|
346
391
|
}
|
|
347
392
|
|
|
@@ -408,16 +453,41 @@ export class ServiceBase extends EventEmitter {
|
|
|
408
453
|
* Set the service state and emit event
|
|
409
454
|
*
|
|
410
455
|
* @private
|
|
411
|
-
* @param {
|
|
456
|
+
* @param {ServiceState} newState - New state value
|
|
457
|
+
* @emits {StateChangeEvent} EVENT_STATE_CHANGED
|
|
412
458
|
*/
|
|
413
459
|
_setState(newState) {
|
|
414
460
|
const oldState = this.state;
|
|
415
461
|
this.state = newState;
|
|
416
462
|
|
|
417
|
-
|
|
463
|
+
/** @type {StateChangeEvent} */
|
|
464
|
+
const eventData = {
|
|
465
|
+
service: this.name,
|
|
418
466
|
oldState,
|
|
419
467
|
newState
|
|
420
|
-
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
this.emit(EVENT_STATE_CHANGED, eventData);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Set the service target state and emit event
|
|
475
|
+
*
|
|
476
|
+
* @private
|
|
477
|
+
* @param {ServiceState} newTargetState - New target state value
|
|
478
|
+
* @emits {TargetStateChangeEvent} EVENT_TARGET_STATE_CHANGED
|
|
479
|
+
*/
|
|
480
|
+
_setTargetState(newTargetState) {
|
|
481
|
+
const oldTargetState = this.targetState;
|
|
482
|
+
this.targetState = newTargetState;
|
|
483
|
+
|
|
484
|
+
/** @type {TargetStateChangeEvent} */
|
|
485
|
+
const eventData = {
|
|
486
|
+
oldTargetState,
|
|
487
|
+
newTargetState
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
this.emit(EVENT_TARGET_STATE_CHANGED, eventData);
|
|
421
491
|
}
|
|
422
492
|
|
|
423
493
|
/**
|
|
@@ -425,16 +495,20 @@ export class ServiceBase extends EventEmitter {
|
|
|
425
495
|
*
|
|
426
496
|
* @private
|
|
427
497
|
* @param {boolean} healthy - New health status
|
|
498
|
+
* @emits {HealthChangeEvent} EVENT_HEALTH_CHANGED
|
|
428
499
|
*/
|
|
429
500
|
_setHealthy(healthy) {
|
|
430
501
|
const wasHealthy = this.healthy;
|
|
431
502
|
this.healthy = healthy;
|
|
432
503
|
|
|
433
504
|
if (wasHealthy !== healthy) {
|
|
434
|
-
|
|
505
|
+
/** @type {HealthChangeEvent} */
|
|
506
|
+
const eventData = {
|
|
435
507
|
healthy,
|
|
436
508
|
wasHealthy
|
|
437
|
-
}
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
this.emit(EVENT_HEALTH_CHANGED, eventData);
|
|
438
512
|
}
|
|
439
513
|
}
|
|
440
514
|
|
|
@@ -444,20 +518,24 @@ export class ServiceBase extends EventEmitter {
|
|
|
444
518
|
* @private
|
|
445
519
|
* @param {string} operation - Operation that failed
|
|
446
520
|
* @param {Error} error - Error that occurred
|
|
521
|
+
* @emits {ServiceErrorEvent} EVENT_ERROR
|
|
447
522
|
*/
|
|
448
523
|
_setError(operation, error) {
|
|
449
524
|
const detailedError = new DetailedError(`${operation} failed`, null, error);
|
|
450
525
|
|
|
451
526
|
this.error = detailedError;
|
|
452
|
-
this._setState(
|
|
527
|
+
this._setState(STATE_ERROR);
|
|
453
528
|
this._setHealthy(false);
|
|
454
529
|
|
|
455
530
|
this.logger.error(detailedError);
|
|
456
531
|
|
|
457
|
-
|
|
532
|
+
/** @type {ServiceErrorEvent} */
|
|
533
|
+
const eventData = {
|
|
458
534
|
operation,
|
|
459
535
|
error: detailedError
|
|
460
|
-
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
this.emit(EVENT_ERROR, eventData);
|
|
461
539
|
}
|
|
462
540
|
}
|
|
463
541
|
|
|
@@ -39,48 +39,64 @@
|
|
|
39
39
|
/**
|
|
40
40
|
* Service has not been created yet
|
|
41
41
|
*/
|
|
42
|
-
export const
|
|
42
|
+
export const STATE_NOT_CREATED: "not-created";
|
|
43
43
|
/**
|
|
44
44
|
* Service has been created but not initialized
|
|
45
45
|
*/
|
|
46
|
-
export const
|
|
46
|
+
export const STATE_CREATED: "created";
|
|
47
47
|
/**
|
|
48
|
-
* Service is currently
|
|
48
|
+
* Service is currently being configured
|
|
49
49
|
*/
|
|
50
|
-
export const
|
|
50
|
+
export const STATE_CONFIGURING: "configuring";
|
|
51
51
|
/**
|
|
52
|
-
* Service has been
|
|
52
|
+
* Service has been configured and is ready to start
|
|
53
53
|
*/
|
|
54
|
-
export const
|
|
54
|
+
export const STATE_CONFIGURED: "configured";
|
|
55
55
|
/**
|
|
56
56
|
* Service is currently starting up
|
|
57
57
|
*/
|
|
58
|
-
export const
|
|
58
|
+
export const STATE_STARTING: "starting";
|
|
59
59
|
/**
|
|
60
60
|
* Service is running and operational
|
|
61
61
|
*/
|
|
62
|
-
export const
|
|
62
|
+
export const STATE_RUNNING: "running";
|
|
63
63
|
/**
|
|
64
64
|
* Service is currently shutting down
|
|
65
65
|
*/
|
|
66
|
-
export const
|
|
66
|
+
export const STATE_STOPPING: "stopping";
|
|
67
67
|
/**
|
|
68
68
|
* Service has been stopped
|
|
69
69
|
*/
|
|
70
|
-
export const
|
|
70
|
+
export const STATE_STOPPED: "stopped";
|
|
71
71
|
/**
|
|
72
72
|
* Service is being destroyed and cleaned up
|
|
73
73
|
*/
|
|
74
|
-
export const
|
|
74
|
+
export const STATE_DESTROYING: "destroying";
|
|
75
75
|
/**
|
|
76
76
|
* Service has been destroyed and cannot be used
|
|
77
77
|
*/
|
|
78
|
-
export const
|
|
78
|
+
export const STATE_DESTROYED: "destroyed";
|
|
79
79
|
/**
|
|
80
80
|
* Service encountered an error and is not operational
|
|
81
81
|
*/
|
|
82
|
-
export const
|
|
82
|
+
export const STATE_ERROR: "error";
|
|
83
83
|
/**
|
|
84
84
|
* Service is attempting to recover from an error
|
|
85
85
|
*/
|
|
86
|
-
export const
|
|
86
|
+
export const STATE_RECOVERING: "recovering";
|
|
87
|
+
/**
|
|
88
|
+
* Event emitted when service state changes
|
|
89
|
+
*/
|
|
90
|
+
export const EVENT_STATE_CHANGED: "stateChanged";
|
|
91
|
+
/**
|
|
92
|
+
* Event emitted when service target state changes
|
|
93
|
+
*/
|
|
94
|
+
export const EVENT_TARGET_STATE_CHANGED: "targetStateChanged";
|
|
95
|
+
/**
|
|
96
|
+
* Event emitted when service health status changes
|
|
97
|
+
*/
|
|
98
|
+
export const EVENT_HEALTH_CHANGED: "healthChanged";
|
|
99
|
+
/**
|
|
100
|
+
* Event emitted when service encounters an error
|
|
101
|
+
*/
|
|
102
|
+
export const EVENT_ERROR: "error";
|
|
@@ -37,62 +37,90 @@
|
|
|
37
37
|
* }
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// STATE CONSTANTS
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
40
44
|
/**
|
|
41
45
|
* Service has not been created yet
|
|
42
46
|
*/
|
|
43
|
-
export const
|
|
47
|
+
export const STATE_NOT_CREATED = 'not-created';
|
|
44
48
|
|
|
45
49
|
/**
|
|
46
50
|
* Service has been created but not initialized
|
|
47
51
|
*/
|
|
48
|
-
export const
|
|
52
|
+
export const STATE_CREATED = 'created';
|
|
49
53
|
|
|
50
54
|
/**
|
|
51
|
-
* Service is currently
|
|
55
|
+
* Service is currently being configured
|
|
52
56
|
*/
|
|
53
|
-
export const
|
|
57
|
+
export const STATE_CONFIGURING = 'configuring';
|
|
54
58
|
|
|
55
59
|
/**
|
|
56
|
-
* Service has been
|
|
60
|
+
* Service has been configured and is ready to start
|
|
57
61
|
*/
|
|
58
|
-
export const
|
|
62
|
+
export const STATE_CONFIGURED = 'configured';
|
|
59
63
|
|
|
60
64
|
/**
|
|
61
65
|
* Service is currently starting up
|
|
62
66
|
*/
|
|
63
|
-
export const
|
|
67
|
+
export const STATE_STARTING = 'starting';
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
70
|
* Service is running and operational
|
|
67
71
|
*/
|
|
68
|
-
export const
|
|
72
|
+
export const STATE_RUNNING = 'running';
|
|
69
73
|
|
|
70
74
|
/**
|
|
71
75
|
* Service is currently shutting down
|
|
72
76
|
*/
|
|
73
|
-
export const
|
|
77
|
+
export const STATE_STOPPING = 'stopping';
|
|
74
78
|
|
|
75
79
|
/**
|
|
76
80
|
* Service has been stopped
|
|
77
81
|
*/
|
|
78
|
-
export const
|
|
82
|
+
export const STATE_STOPPED = 'stopped';
|
|
79
83
|
|
|
80
84
|
/**
|
|
81
85
|
* Service is being destroyed and cleaned up
|
|
82
86
|
*/
|
|
83
|
-
export const
|
|
87
|
+
export const STATE_DESTROYING = 'destroying';
|
|
84
88
|
|
|
85
89
|
/**
|
|
86
90
|
* Service has been destroyed and cannot be used
|
|
87
91
|
*/
|
|
88
|
-
export const
|
|
92
|
+
export const STATE_DESTROYED = 'destroyed';
|
|
89
93
|
|
|
90
94
|
/**
|
|
91
95
|
* Service encountered an error and is not operational
|
|
92
96
|
*/
|
|
93
|
-
export const
|
|
97
|
+
export const STATE_ERROR = 'error';
|
|
94
98
|
|
|
95
99
|
/**
|
|
96
100
|
* Service is attempting to recover from an error
|
|
97
101
|
*/
|
|
98
|
-
export const
|
|
102
|
+
export const STATE_RECOVERING = 'recovering';
|
|
103
|
+
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// EVENT CONSTANTS
|
|
106
|
+
// ============================================================================
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Event emitted when service state changes
|
|
110
|
+
*/
|
|
111
|
+
export const EVENT_STATE_CHANGED = 'stateChanged';
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Event emitted when service target state changes
|
|
115
|
+
*/
|
|
116
|
+
export const EVENT_TARGET_STATE_CHANGED = 'targetStateChanged';
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Event emitted when service health status changes
|
|
120
|
+
*/
|
|
121
|
+
export const EVENT_HEALTH_CHANGED = 'healthChanged';
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Event emitted when service encounters an error
|
|
125
|
+
*/
|
|
126
|
+
export const EVENT_ERROR = 'error';
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All possible service states during lifecycle management
|
|
3
|
+
*/
|
|
4
|
+
export type ServiceState = "not-created" | "created" | "configuring" | "configured" | "starting" | "running" | "stopping" | "stopped" | "destroying" | "destroyed" | "error" | "recovering";
|
|
1
5
|
/**
|
|
2
6
|
* Options for creating a service instance
|
|
3
7
|
*/
|
|
@@ -66,17 +70,23 @@ export type StateChangeEvent = {
|
|
|
66
70
|
/**
|
|
67
71
|
* - Previous state
|
|
68
72
|
*/
|
|
69
|
-
oldState:
|
|
73
|
+
oldState: ServiceState;
|
|
70
74
|
/**
|
|
71
75
|
* - New state
|
|
72
76
|
*/
|
|
73
|
-
newState:
|
|
77
|
+
newState: ServiceState;
|
|
74
78
|
};
|
|
75
|
-
export type
|
|
79
|
+
export type TargetStateChangeEvent = {
|
|
76
80
|
/**
|
|
77
|
-
* -
|
|
81
|
+
* - Previous target state
|
|
78
82
|
*/
|
|
79
|
-
|
|
83
|
+
oldTargetState: ServiceState;
|
|
84
|
+
/**
|
|
85
|
+
* - New target state
|
|
86
|
+
*/
|
|
87
|
+
newTargetState: ServiceState;
|
|
88
|
+
};
|
|
89
|
+
export type HealthChangeEvent = {
|
|
80
90
|
/**
|
|
81
91
|
* - Current health status
|
|
82
92
|
*/
|
|
@@ -90,10 +100,6 @@ export type HealthChangeEvent = {
|
|
|
90
100
|
* Event emitted when service encounters an error
|
|
91
101
|
*/
|
|
92
102
|
export type ServiceErrorEvent = {
|
|
93
|
-
/**
|
|
94
|
-
* - Service name
|
|
95
|
-
*/
|
|
96
|
-
service: string;
|
|
97
103
|
/**
|
|
98
104
|
* - Operation that failed
|
|
99
105
|
*/
|