@syncbridge/common 0.6.1 → 0.6.3
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/classes/base-element.d.ts +1 -1
- package/classes/base-element.js +5 -8
- package/classes/runnable.d.ts +2 -1
- package/classes/runnable.js +8 -4
- package/classes/sb-error.d.ts +1 -0
- package/classes/sb-error.js +9 -0
- package/classes/stack-executor.js +12 -5
- package/constants.js +1 -1
- package/package.json +1 -1
- package/processor-factory.js +4 -2
- package/utils/decode-profile.js +4 -0
- package/utils/materialize-metadata.js +4 -0
|
@@ -14,7 +14,7 @@ export declare abstract class BaseElement<TEvents extends BaseElement.Events = B
|
|
|
14
14
|
get status(): ServiceStatus;
|
|
15
15
|
get statusMessage(): string;
|
|
16
16
|
protected _init(): Promise<void>;
|
|
17
|
-
protected _start(abortSignal
|
|
17
|
+
protected _start(abortSignal?: AbortSignal): Promise<void>;
|
|
18
18
|
protected _stop(): Promise<void>;
|
|
19
19
|
protected onStatusChange(): void;
|
|
20
20
|
}
|
package/classes/base-element.js
CHANGED
|
@@ -26,6 +26,7 @@ export class BaseElement extends Runnable {
|
|
|
26
26
|
async _init() {
|
|
27
27
|
for (const component of Object.values(this.components)) {
|
|
28
28
|
component.on('status-change', (status, statusMessage) => {
|
|
29
|
+
component.on('component-status-change', (...args) => this.emitAsyncSafe('component-status-change', ...args));
|
|
29
30
|
/** Reset counters */
|
|
30
31
|
this._context.statusIndicators = this._context.statusIndicators || {};
|
|
31
32
|
Object.keys(ServiceStatus).forEach(key => {
|
|
@@ -42,7 +43,8 @@ export class BaseElement extends Runnable {
|
|
|
42
43
|
counter.componentNames.push(comp.name);
|
|
43
44
|
});
|
|
44
45
|
this.emitSafe('component-status-change', component, status, statusMessage);
|
|
45
|
-
if (this._context.status !== this._context.calculatedStatus
|
|
46
|
+
if (this._context.status !== this._context.calculatedStatus ||
|
|
47
|
+
this._context.statusMessage !== this._context.statusMessage)
|
|
46
48
|
this.onStatusChange();
|
|
47
49
|
});
|
|
48
50
|
}
|
|
@@ -60,8 +62,6 @@ export class BaseElement extends Runnable {
|
|
|
60
62
|
.map(component => component.stop()));
|
|
61
63
|
}
|
|
62
64
|
onStatusChange() {
|
|
63
|
-
const oldStatus = this.status;
|
|
64
|
-
const oldStatusMessage = this.statusMessage;
|
|
65
65
|
this._context.calculatedStatus = this._context.status;
|
|
66
66
|
this._context.calculatedStatusMessage = this._context.statusMessage;
|
|
67
67
|
if (!(this.status === ServiceStatus.stopped ||
|
|
@@ -72,13 +72,10 @@ export class BaseElement extends Runnable {
|
|
|
72
72
|
if (indicator?.count) {
|
|
73
73
|
this._context.calculatedStatus = _status;
|
|
74
74
|
this._context.calculatedStatusMessage = `${_status} components: ${indicator.componentNames}`;
|
|
75
|
-
|
|
75
|
+
break;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
this.logger?.debug(this.status);
|
|
81
|
-
super.onStatusChange();
|
|
82
|
-
}
|
|
79
|
+
super.onStatusChange();
|
|
83
80
|
}
|
|
84
81
|
}
|
package/classes/runnable.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ServiceStatus } from '../models/index.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare abstract class Runnable<T extends Runnable.Events = Runnable.Events> extends AsyncEventEmitter<EventMap<T>> {
|
|
7
7
|
protected _context: Runnable.Context;
|
|
8
|
+
private _startAbortController?;
|
|
8
9
|
constructor(init?: Runnable.InitArgs);
|
|
9
10
|
get status(): ServiceStatus;
|
|
10
11
|
get statusMessage(): string;
|
|
@@ -34,7 +35,7 @@ export declare abstract class Runnable<T extends Runnable.Events = Runnable.Even
|
|
|
34
35
|
/**
|
|
35
36
|
*
|
|
36
37
|
*/
|
|
37
|
-
protected abstract _start(abortSignal
|
|
38
|
+
protected abstract _start(abortSignal?: AbortSignal): Promise<void>;
|
|
38
39
|
/**
|
|
39
40
|
*
|
|
40
41
|
*/
|
package/classes/runnable.js
CHANGED
|
@@ -8,6 +8,7 @@ import { SbError } from './sb-error.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export class Runnable extends AsyncEventEmitter {
|
|
10
10
|
_context;
|
|
11
|
+
_startAbortController;
|
|
11
12
|
constructor(init) {
|
|
12
13
|
super();
|
|
13
14
|
this.setMaxListeners(1000);
|
|
@@ -67,6 +68,9 @@ export class Runnable extends AsyncEventEmitter {
|
|
|
67
68
|
if (this.status === ServiceStatus.started)
|
|
68
69
|
return;
|
|
69
70
|
this.setStatus(ServiceStatus.starting);
|
|
71
|
+
const abortController = (this._startAbortController =
|
|
72
|
+
new AbortController());
|
|
73
|
+
abortSignal?.addEventListener('abort', () => abortController.abort());
|
|
70
74
|
this._context.waitTimer = Promise.resolve()
|
|
71
75
|
.then(async () => {
|
|
72
76
|
await this.init();
|
|
@@ -74,8 +78,6 @@ export class Runnable extends AsyncEventEmitter {
|
|
|
74
78
|
let promiseSettled = false;
|
|
75
79
|
await new Promise((resolve, reject) => {
|
|
76
80
|
let startWaitTimer;
|
|
77
|
-
const abortController = new AbortController();
|
|
78
|
-
abortSignal?.addEventListener('abort', () => abortController.abort());
|
|
79
81
|
if (this._context.startMaxWaitMs) {
|
|
80
82
|
startWaitTimer = setTimeout(() => {
|
|
81
83
|
const err = new SbError('Start timeout', {
|
|
@@ -124,6 +126,7 @@ export class Runnable extends AsyncEventEmitter {
|
|
|
124
126
|
});
|
|
125
127
|
})
|
|
126
128
|
.finally(() => {
|
|
129
|
+
this._startAbortController = undefined;
|
|
127
130
|
this._context.waitTimer = undefined;
|
|
128
131
|
});
|
|
129
132
|
await this._context.waitTimer;
|
|
@@ -132,12 +135,13 @@ export class Runnable extends AsyncEventEmitter {
|
|
|
132
135
|
*
|
|
133
136
|
*/
|
|
134
137
|
async stop() {
|
|
135
|
-
if (this._context.waitTimer)
|
|
136
|
-
await this._context.waitTimer;
|
|
137
138
|
if (this.status === ServiceStatus.stopped)
|
|
138
139
|
return;
|
|
139
140
|
this.setStatus(ServiceStatus.stopping);
|
|
140
141
|
this.emit('stopping');
|
|
142
|
+
this._startAbortController?.abort();
|
|
143
|
+
if (this._context.waitTimer)
|
|
144
|
+
await this._context.waitTimer;
|
|
141
145
|
this._context.waitTimer = Promise.resolve()
|
|
142
146
|
.then(async () => {
|
|
143
147
|
try {
|
package/classes/sb-error.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class SbError extends Error implements ErrorIssue {
|
|
|
5
5
|
code?: string;
|
|
6
6
|
[index: string]: any;
|
|
7
7
|
constructor(message?: string | Error, options?: SbErrorOptions);
|
|
8
|
+
toJSON(): any;
|
|
8
9
|
}
|
|
9
10
|
export interface SbErrorOptions extends Partial<ErrorIssue> {
|
|
10
11
|
cause?: Error;
|
package/classes/sb-error.js
CHANGED
|
@@ -32,15 +32,22 @@ export class StackExecutor {
|
|
|
32
32
|
if (e instanceof ValidationError) {
|
|
33
33
|
e.issues.forEach(x => {
|
|
34
34
|
const issue = new SbValidationError(x.message, x);
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
issue.severity = x.severity ?? 'error';
|
|
36
|
+
issue.location = location + (x.location ? '/' + x.location : '');
|
|
37
|
+
issue.stack = x.stack;
|
|
37
38
|
this.issues.push(issue);
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const issue = {
|
|
43
|
+
message: e.message,
|
|
44
|
+
severity: e.severity || 'error',
|
|
45
|
+
location,
|
|
46
|
+
stack: e.stack,
|
|
47
|
+
...e,
|
|
48
|
+
};
|
|
49
|
+
Object.setPrototypeOf(issue, Object.getPrototypeOf(e));
|
|
50
|
+
this.issues.push(issue);
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
}
|
package/constants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const version = '0.6.
|
|
1
|
+
export const version = '0.6.3';
|
|
2
2
|
export const OWN_ELEMENT_METADATA = Symbol.for('OWN_ELEMENT_METADATA');
|
|
3
3
|
export const COMPONENT_OPTIONS = Symbol.for('COMPONENT_OPTIONS');
|
|
4
4
|
export const PROCESSOR_OPTIONS = Symbol.for('PROCESSOR_OPTIONS');
|
package/package.json
CHANGED
package/processor-factory.js
CHANGED
|
@@ -97,7 +97,7 @@ export var ProcessorFactory;
|
|
|
97
97
|
oldMetadata?.className !== newMetadata.className)
|
|
98
98
|
throw new SbError('Cannot change component class while processor running. You should stop it first.');
|
|
99
99
|
/** Validate sub components */
|
|
100
|
-
if (childMetadata.components) {
|
|
100
|
+
if (childMetadata.components && componentInstance) {
|
|
101
101
|
_validateComponents({
|
|
102
102
|
...ctx,
|
|
103
103
|
owner: componentInstance,
|
|
@@ -128,9 +128,11 @@ export var ProcessorFactory;
|
|
|
128
128
|
}
|
|
129
129
|
async function _configureComponent(ctx, key, childMetadata) {
|
|
130
130
|
const { newProfile, oldMetadata, oldProfile, curPath, owner, processor } = ctx;
|
|
131
|
+
const childProfile = newProfile.components[key];
|
|
132
|
+
if (!childProfile?.className)
|
|
133
|
+
return;
|
|
131
134
|
const oldChildMetadata = oldMetadata?.components?.[key];
|
|
132
135
|
const oldChildProfile = oldProfile?.components?.[key];
|
|
133
|
-
const childProfile = newProfile.components[key];
|
|
134
136
|
const componentPath = curPath ? curPath + '/' + key : key;
|
|
135
137
|
let componentInstance = owner.components?.[key];
|
|
136
138
|
/** Create the component only if the owner stopped */ // todo implement hotplug components
|
package/utils/decode-profile.js
CHANGED
|
@@ -14,6 +14,10 @@ export function decodeProfile(materializedMetadata, rawProfile, options) {
|
|
|
14
14
|
issues
|
|
15
15
|
.map(issue => `- ${issue.message}. Location: /${issue.location}`)
|
|
16
16
|
.join('\n ');
|
|
17
|
+
issues.forEach(issue => {
|
|
18
|
+
if (issue instanceof SbValidationError)
|
|
19
|
+
delete issue.stack;
|
|
20
|
+
});
|
|
17
21
|
throw new SbValidationError(msg, {
|
|
18
22
|
workerId: rawProfile.id,
|
|
19
23
|
issues,
|
|
@@ -13,6 +13,10 @@ export function materializeMetadata(profile) {
|
|
|
13
13
|
issues
|
|
14
14
|
.map(issue => `- ${issue.message}. Location: /${issue.location}`)
|
|
15
15
|
.join('\n ');
|
|
16
|
+
issues.forEach(issue => {
|
|
17
|
+
if (issue instanceof SbValidationError)
|
|
18
|
+
delete issue.stack;
|
|
19
|
+
});
|
|
16
20
|
throw new SbValidationError(msg, {
|
|
17
21
|
workerId: profile.id,
|
|
18
22
|
issues,
|