readiness-manager 1.1.4 → 1.2.0-rc.x6cd566eea
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/CHANGELOG.md +6 -0
- package/README.md +14 -79
- package/dist/src/error.d.ts +16 -0
- package/dist/src/error.d.ts.map +1 -0
- package/dist/src/error.js +23 -0
- package/dist/src/error.js.map +1 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +126 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/types.d.ts +17 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/dist/tests/mock.d.ts +8 -0
- package/dist/tests/mock.d.ts.map +1 -0
- package/dist/tests/mock.js +39 -0
- package/dist/tests/mock.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/jest.config.ts +8 -0
- package/package.json +16 -27
- package/project.json +16 -0
- package/src/error.ts +46 -0
- package/src/index.ts +230 -0
- package/src/spec.ts +250 -0
- package/src/types.ts +38 -0
- package/tests/mock.ts +57 -0
- package/tsconfig.json +10 -0
- package/LICENSE +0 -8
- package/index.js +0 -1
- package/src/constants.js +0 -14
- package/src/error.js +0 -42
- package/src/index.js +0 -208
- package/src/types.d.ts +0 -40
- package/tests/mock.d.ts +0 -9
- package/tests/mock.js +0 -36
package/tsconfig.json
ADDED
package/LICENSE
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
Copyright (c) Fiverr
|
|
3
|
-
|
|
4
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
|
-
|
|
6
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
7
|
-
|
|
8
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./src');
|
package/src/constants.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The possible beacon status.
|
|
3
|
-
* @type {{ NOT_STARTED: string, RESOLVED: string, PENDING: string, REJECTED: string }}
|
|
4
|
-
*/
|
|
5
|
-
const BeaconStatus = {
|
|
6
|
-
NOT_STARTED: 'not_started',
|
|
7
|
-
PENDING: 'pending',
|
|
8
|
-
RESOLVED: 'resolved',
|
|
9
|
-
REJECTED: 'rejected'
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
module.exports = {
|
|
13
|
-
BeaconStatus
|
|
14
|
-
};
|
package/src/error.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The possible errors that could be thrown.
|
|
3
|
-
* @type {Object<string>}
|
|
4
|
-
*/
|
|
5
|
-
const ERRORS = {
|
|
6
|
-
BEACON_ALREADY_EXISTS: 'Beacon is already exists, please ensure to use a unique name per beacon',
|
|
7
|
-
BEACON_DOES_NOT_EXISTS: 'Beacon does not exists, make sure to call `register` before trying to set beacon ready hook.',
|
|
8
|
-
BEACON_EXECUTION_FAILED: 'Beacon execution failed'
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* The custom error the be thrown when beacon execution fails.
|
|
13
|
-
* @type {ActionExecutionError}
|
|
14
|
-
*/
|
|
15
|
-
class ActionExecutionError extends Error {
|
|
16
|
-
constructor(name, attempt, error) {
|
|
17
|
-
super();
|
|
18
|
-
|
|
19
|
-
Object.assign(this, {
|
|
20
|
-
message: ERRORS.BEACON_EXECUTION_FAILED,
|
|
21
|
-
name,
|
|
22
|
-
attempt,
|
|
23
|
-
stack: error.stack,
|
|
24
|
-
failReason: error.message
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Default error handler to be triggered upon beacon errors.
|
|
31
|
-
* @param beaconError - The beacon error that occur.
|
|
32
|
-
* @type {ActionErrorHandler}
|
|
33
|
-
*/
|
|
34
|
-
const defaultErrorHandler = (
|
|
35
|
-
beaconError
|
|
36
|
-
) => console.log(beaconError); // eslint-disable-line no-console
|
|
37
|
-
|
|
38
|
-
module.exports = {
|
|
39
|
-
ERRORS,
|
|
40
|
-
ActionExecutionError,
|
|
41
|
-
defaultErrorHandler
|
|
42
|
-
};
|
package/src/index.js
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
ERRORS,
|
|
3
|
-
ActionExecutionError,
|
|
4
|
-
defaultErrorHandler
|
|
5
|
-
} = require('./error');
|
|
6
|
-
const { BeaconStatus } = require('./constants');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Sets of private attributes which should not be exposed / accessed by consumer.
|
|
10
|
-
* @type {Object<Symbol>}
|
|
11
|
-
*/
|
|
12
|
-
const Symbols = [
|
|
13
|
-
'beacons',
|
|
14
|
-
'callbacks',
|
|
15
|
-
'execute',
|
|
16
|
-
'trackBeaconUpdate',
|
|
17
|
-
'updateBeacon',
|
|
18
|
-
'errorHandler'
|
|
19
|
-
].reduce((acc, key) => ({ ...acc, [key]: Symbol() }), {});
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* The internal "ready" state to determine process readiness.
|
|
23
|
-
* @type {boolean}
|
|
24
|
-
*/
|
|
25
|
-
let readyState = false;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @type {ReadinessManager}
|
|
29
|
-
*/
|
|
30
|
-
class ReadinessManager {
|
|
31
|
-
constructor() {
|
|
32
|
-
this[Symbols.beacons] = {};
|
|
33
|
-
this[Symbols.callbacks] = [];
|
|
34
|
-
this[Symbols.errorHandler] = defaultErrorHandler;
|
|
35
|
-
|
|
36
|
-
this[Symbols.execute] = this[Symbols.execute].bind(this);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Returns true if current process state is considered as "ready".
|
|
41
|
-
* @return {boolean}
|
|
42
|
-
*/
|
|
43
|
-
get ready() {
|
|
44
|
-
return readyState;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Returns current registered actions status
|
|
49
|
-
* @return {ActionsStatus}
|
|
50
|
-
*/
|
|
51
|
-
status() {
|
|
52
|
-
return Object.values(this[Symbols.beacons])
|
|
53
|
-
.reduce((acc, { name, status }) => {
|
|
54
|
-
const current = acc[status] || [];
|
|
55
|
-
return Object.assign(acc, { [status]: [...current, name] });
|
|
56
|
-
}, {});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Registers a given name and action as beacon under manager.
|
|
61
|
-
* @param {string} name - The operation name to register with.
|
|
62
|
-
* @param {ReadyAction} action - The ready emitter to condition the process readiness with.
|
|
63
|
-
*/
|
|
64
|
-
register(name, action) {
|
|
65
|
-
if (this.ready) { return; }
|
|
66
|
-
|
|
67
|
-
if (this[Symbols.beacons][name]) { throw new Error(ERRORS.BEACON_ALREADY_EXISTS); }
|
|
68
|
-
|
|
69
|
-
const beacon = {
|
|
70
|
-
name,
|
|
71
|
-
action,
|
|
72
|
-
callbacks: [],
|
|
73
|
-
status: BeaconStatus.NOT_STARTED
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
Object.assign(this[Symbols.beacons], { [name]: beacon });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Runs current registered beacons execution to determine process "ready" state.
|
|
81
|
-
* @return {ReadinessManager}
|
|
82
|
-
*/
|
|
83
|
-
run() {
|
|
84
|
-
readyState = false;
|
|
85
|
-
|
|
86
|
-
Object.values(this[Symbols.beacons])
|
|
87
|
-
.forEach((beacon) => this[Symbols.execute](beacon));
|
|
88
|
-
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Registers a given callback to be triggered once process is marked as "ready".
|
|
94
|
-
* @param {ReadyCallback} callback
|
|
95
|
-
* @return {ReadinessManager}
|
|
96
|
-
*/
|
|
97
|
-
onReady(callback) {
|
|
98
|
-
if (readyState) {
|
|
99
|
-
// Invokes immediately given callback if process is already ready.
|
|
100
|
-
callback();
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this[Symbols.callbacks].push(callback);
|
|
105
|
-
return this;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Registers a given callback on a specific action resolved..
|
|
110
|
-
* @param {string} name - The name of the action the callback should be attached to.
|
|
111
|
-
* @param {ReadyCallback} callback - The callback to run upon beacon resolved.
|
|
112
|
-
* @return {ReadinessManager}
|
|
113
|
-
*/
|
|
114
|
-
onActionReady(name, callback) {
|
|
115
|
-
const beacon = this[Symbols.beacons][name];
|
|
116
|
-
if (!beacon) { throw new Error(ERRORS.BEACON_DOES_NOT_EXISTS); }
|
|
117
|
-
|
|
118
|
-
if (beacon.status === BeaconStatus.RESOLVED) {
|
|
119
|
-
// Invokes immediately given callback if beacon status is already resolved.
|
|
120
|
-
return callback();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
this[Symbols.beacons][name].callbacks.push(callback);
|
|
124
|
-
return this;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Registers a given error handler under manager errors.
|
|
129
|
-
* @param {ActionErrorHandler} errorHandler - The handler to trigger upon action errors.
|
|
130
|
-
* @return {ReadinessManager}
|
|
131
|
-
*/
|
|
132
|
-
onError(errorHandler) {
|
|
133
|
-
Object.assign(this, { [Symbols.errorHandler]: errorHandler });
|
|
134
|
-
return this;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Tracks a given beacon action.
|
|
139
|
-
* @param {Beacon} beacon - The beacon to execute.
|
|
140
|
-
* @param {Number} attempt - The attempt number of current beacon execution.
|
|
141
|
-
* @throws {ActionExecutionError}
|
|
142
|
-
* @private
|
|
143
|
-
*/
|
|
144
|
-
async [Symbols.execute](beacon, attempt = 1) {
|
|
145
|
-
const { name, action } = beacon;
|
|
146
|
-
|
|
147
|
-
const update = (status) => this[Symbols.updateBeacon](name, status);
|
|
148
|
-
|
|
149
|
-
update(BeaconStatus.PENDING);
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
// The actual beacon execution we want to keep track on.
|
|
153
|
-
const result = action();
|
|
154
|
-
|
|
155
|
-
if (result instanceof Promise) {
|
|
156
|
-
await result;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
update(BeaconStatus.RESOLVED);
|
|
160
|
-
} catch (error) {
|
|
161
|
-
update(BeaconStatus.REJECTED);
|
|
162
|
-
|
|
163
|
-
// Invokes consumer error hook with a retry method and the beacon error.
|
|
164
|
-
this[Symbols.errorHandler](
|
|
165
|
-
new ActionExecutionError(name, attempt, error),
|
|
166
|
-
() => this[Symbols.execute](beacon, attempt + 1)
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Updates a given beacon name with a given status.
|
|
173
|
-
* @param name - The beacon name to update.
|
|
174
|
-
* @param status - The beacon status to set.
|
|
175
|
-
* @private
|
|
176
|
-
*/
|
|
177
|
-
[Symbols.updateBeacon](name, status) {
|
|
178
|
-
Object.assign(
|
|
179
|
-
this[Symbols.beacons][name],
|
|
180
|
-
{ status }
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
// Resolves specific beacon ready listeners.
|
|
184
|
-
if (status === BeaconStatus.RESOLVED) {
|
|
185
|
-
this[Symbols.beacons][name].callbacks.map(
|
|
186
|
-
(callback) => callback()
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
this[Symbols.trackBeaconUpdate]();
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Tracks an beacon update event, checks whether process is "ready".
|
|
195
|
-
* If so, will trigger registered `onReady` callbacks.
|
|
196
|
-
* @private
|
|
197
|
-
*/
|
|
198
|
-
[Symbols.trackBeaconUpdate]() {
|
|
199
|
-
if (readyState) { return; }
|
|
200
|
-
|
|
201
|
-
readyState = Object.values(this[Symbols.beacons])
|
|
202
|
-
.every((beacon) => beacon.status === BeaconStatus.RESOLVED);
|
|
203
|
-
|
|
204
|
-
readyState && this[Symbols.callbacks].map((callback) => callback());
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
module.exports = new ReadinessManager();
|
package/src/types.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
type ReadyCallback = () => void;
|
|
2
|
-
type ReadyAction = () => unknown | Promise<unknown>;
|
|
3
|
-
type ActionRetry = () => Promise<unknown>;
|
|
4
|
-
type ActionStatus = 'not_started' | 'pending' | 'resolved' | 'rejected';
|
|
5
|
-
|
|
6
|
-
interface Beacon {
|
|
7
|
-
name: string;
|
|
8
|
-
action: ReadyAction;
|
|
9
|
-
status: ActionStatus;
|
|
10
|
-
callbacks: ReadyCallback[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
type BeaconsMap = { [name: string] : Beacon };
|
|
14
|
-
|
|
15
|
-
export interface ActionExecutionError extends Error {
|
|
16
|
-
name: string;
|
|
17
|
-
stack: string;
|
|
18
|
-
attempt: number;
|
|
19
|
-
failReason: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type ActionErrorHandler = (error: ActionExecutionError, retry: ActionRetry) => void;
|
|
23
|
-
|
|
24
|
-
export type ActionsStatus = {
|
|
25
|
-
[status in ActionStatus]: string[];
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export interface ReadinessManager {
|
|
29
|
-
register: (name: string, action: ReadyAction) => void;
|
|
30
|
-
run: () => ReadinessManager;
|
|
31
|
-
onReady:(callback: ReadyCallback) => ReadinessManager;
|
|
32
|
-
onActionReady:(name: string, callback: ReadyCallback) => ReadinessManager;
|
|
33
|
-
onError:(errorHandler: ActionErrorHandler) => ReadinessManager;
|
|
34
|
-
status:() => ActionsStatus;
|
|
35
|
-
ready: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
declare const manager: ReadinessManager;
|
|
39
|
-
|
|
40
|
-
export default manager;
|
package/tests/mock.d.ts
DELETED
package/tests/mock.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test mock helper class.
|
|
3
|
-
*/
|
|
4
|
-
class ReadinessManagerMock {
|
|
5
|
-
constructor() {
|
|
6
|
-
this._ready = false;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
get ready() {
|
|
10
|
-
return this._ready;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
status() {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
setReady(isReady) {
|
|
18
|
-
this._ready = isReady;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
register() { return undefined; }
|
|
22
|
-
|
|
23
|
-
orchestrate() {
|
|
24
|
-
this._ready = true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
onReady(callback) {
|
|
28
|
-
callback();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
onActionReady(callback) {
|
|
32
|
-
callback();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
module.exports = new ReadinessManagerMock();
|