investira.sdk 2.3.18 → 2.3.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/CHANGELOG.md +8 -0
- package/lib/hofs/tasks.js +101 -88
- package/lib/utils/arrays.js +26 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
package/lib/hofs/tasks.js
CHANGED
|
@@ -17,8 +17,9 @@ const STATUS = Object.freeze({
|
|
|
17
17
|
* @param {object} [pSource={}]
|
|
18
18
|
*/
|
|
19
19
|
function task(pOptions, pSource = {}) {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const xSelf = this;
|
|
21
|
+
xSelf.STATUS = STATUS;
|
|
22
|
+
xSelf.options = {
|
|
22
23
|
retries: 0, //Numero de tentativas quando houver erro
|
|
23
24
|
delay: 0, //Tempo em segundos para efetuar nova tentativa
|
|
24
25
|
enabled: true,
|
|
@@ -34,24 +35,24 @@ function task(pOptions, pSource = {}) {
|
|
|
34
35
|
], //Array com os agendamentos
|
|
35
36
|
...deepCopy(pOptions)
|
|
36
37
|
};
|
|
37
|
-
// console.log(`*-* INICIO ${
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// console.log(`*-* INICIO ${xSelf.options.id}`);
|
|
39
|
+
xSelf.event = new events.EventEmitter();
|
|
40
|
+
xSelf.beforeRun =
|
|
40
41
|
pSource.beforeRun ||
|
|
41
42
|
function () {
|
|
42
43
|
return Promise.resolve();
|
|
43
44
|
};
|
|
44
|
-
|
|
45
|
+
xSelf.execute =
|
|
45
46
|
pSource.execute ||
|
|
46
47
|
function () {
|
|
47
48
|
return Promise.resolve();
|
|
48
49
|
};
|
|
49
|
-
|
|
50
|
+
xSelf.afterStop =
|
|
50
51
|
pSource.afterStop ||
|
|
51
52
|
function () {
|
|
52
53
|
return Promise.resolve();
|
|
53
54
|
};
|
|
54
|
-
|
|
55
|
+
xSelf.state = {
|
|
55
56
|
status: STATUS.STOPPED, //Status da execução
|
|
56
57
|
nextAt: null, //Momento da próxima execução
|
|
57
58
|
startedAt: null, //Momento de inicio da execução
|
|
@@ -59,43 +60,43 @@ function task(pOptions, pSource = {}) {
|
|
|
59
60
|
retries: 0, //Quantidade de vezes que foi reiniciada
|
|
60
61
|
error: null //Mensagem de erro,
|
|
61
62
|
};
|
|
62
|
-
|
|
63
|
+
xSelf.timeout = null;
|
|
63
64
|
|
|
64
65
|
/**
|
|
65
66
|
* desabilitar esta tarefa
|
|
66
67
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
clearTimeout(
|
|
68
|
+
xSelf.disable = () => {
|
|
69
|
+
xSelf.options.enabled = false;
|
|
70
|
+
clearTimeout(xSelf.timeout);
|
|
70
71
|
//Dispara evento disabled
|
|
71
|
-
|
|
72
|
+
xSelf.event.emit('disabled');
|
|
72
73
|
};
|
|
73
74
|
/**
|
|
74
75
|
* Habilitar esta tarefa e reinicia o agendamento se houver
|
|
75
76
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
xSelf.enable = () => {
|
|
78
|
+
xSelf.options.enabled = true;
|
|
78
79
|
//Dispara evento scheduled
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
xSelf.event.emit('enabled');
|
|
81
|
+
xSelf.schedule();
|
|
81
82
|
};
|
|
82
83
|
/**
|
|
83
84
|
* Agenda próxima execução
|
|
84
85
|
*
|
|
85
86
|
*/
|
|
86
|
-
|
|
87
|
-
// console.log(`${
|
|
88
|
-
if (!
|
|
87
|
+
xSelf.schedule = () => {
|
|
88
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* SCHEDULE(#1)`);
|
|
89
|
+
if (!xSelf.options.enabled) {
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
92
|
//Configura schedule inicial
|
|
92
93
|
if (pvSetNextDate()) {
|
|
93
|
-
clearTimeout(
|
|
94
|
-
// console.log(`${
|
|
94
|
+
clearTimeout(xSelf.timeout);
|
|
95
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* SCHEDULE(#2) ${xSelf.state.nextAt}`);
|
|
95
96
|
//Efetua agendamento
|
|
96
|
-
|
|
97
|
+
xSelf.timeout = schedule(xSelf.state.nextAt, xSelf.run);
|
|
97
98
|
//Dispara evento scheduled
|
|
98
|
-
|
|
99
|
+
xSelf.event.emit('scheduled', xSelf.state.nextAt);
|
|
99
100
|
}
|
|
100
101
|
};
|
|
101
102
|
|
|
@@ -105,45 +106,48 @@ function task(pOptions, pSource = {}) {
|
|
|
105
106
|
* @param {object} [pPreviousTaskState=null] Atributo 'state' de uma tarefa anterior para a data/hora ser utilizada como o verdadeiro inicio
|
|
106
107
|
* @returns {Promise}
|
|
107
108
|
*/
|
|
108
|
-
|
|
109
|
-
// console.log(`${
|
|
110
|
-
if (!
|
|
111
|
-
if (
|
|
112
|
-
// console.log(`${
|
|
113
|
-
|
|
109
|
+
xSelf.run = (pPreviousTaskState = null) => {
|
|
110
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN`);
|
|
111
|
+
if (!xSelf.options.enabled || xSelf.isRunning()) {
|
|
112
|
+
if (xSelf.isRunning()) {
|
|
113
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN JÁ EM EXECUÇÃO`);
|
|
114
|
+
xSelf.event.emit('running', true);
|
|
114
115
|
} else {
|
|
115
|
-
// console.log(`${
|
|
116
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN DESABILITADA`);
|
|
116
117
|
}
|
|
117
118
|
return Promise.resolve();
|
|
118
119
|
}
|
|
119
120
|
return new Promise((pResolve, pReject) => {
|
|
120
121
|
//Códigos referentes a execução devem ser inseridos dentro da função executada no setTimeout
|
|
121
122
|
//Se for retry, aguarda o tempo definido no delay
|
|
122
|
-
// console.log(`${
|
|
123
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN SETTIMEOUT`);
|
|
123
124
|
|
|
124
125
|
setTimeout(
|
|
125
126
|
() => {
|
|
126
|
-
// console.log(`${
|
|
127
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN SETTIMEOUT RUN`);
|
|
127
128
|
//Inicia execução
|
|
128
129
|
//Reseta erro
|
|
129
|
-
|
|
130
|
+
xSelf.state.error = null;
|
|
130
131
|
//Dispara evento run
|
|
131
|
-
|
|
132
|
+
xSelf.event.emit('run');
|
|
132
133
|
//Verica se é para prosseguir
|
|
133
|
-
|
|
134
|
+
xSelf
|
|
135
|
+
.beforeRun()
|
|
134
136
|
.then((pIsOk = true) => {
|
|
135
|
-
// console.log(`${
|
|
137
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN BEFORE`);
|
|
136
138
|
if (pIsOk) {
|
|
137
|
-
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
xSelf.state.status = STATUS.RUNNING;
|
|
138
141
|
//Considera o inicio informado
|
|
139
|
-
|
|
142
|
+
xSelf.state.startedAt =
|
|
143
|
+
(pPreviousTaskState && pPreviousTaskState.startedAt) || toDate();
|
|
140
144
|
//Dispara evento disabled
|
|
141
|
-
|
|
145
|
+
xSelf.event.emit('running');
|
|
142
146
|
//--------------------
|
|
143
147
|
// EXECUTA
|
|
144
148
|
//--------------------
|
|
145
|
-
// console.log(`${
|
|
146
|
-
return
|
|
149
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN EXECUTE`);
|
|
150
|
+
return xSelf.execute();
|
|
147
151
|
} else {
|
|
148
152
|
return null;
|
|
149
153
|
}
|
|
@@ -151,8 +155,8 @@ function task(pOptions, pSource = {}) {
|
|
|
151
155
|
//Sucesso
|
|
152
156
|
.then(rResult => {
|
|
153
157
|
//Reseta retries quando execução finalizar com sucesso
|
|
154
|
-
|
|
155
|
-
// console.log(`${
|
|
158
|
+
xSelf.state.retries = 0;
|
|
159
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN SUCESSO`);
|
|
156
160
|
//Finaliza execução
|
|
157
161
|
return pvStop()
|
|
158
162
|
.then(() => {
|
|
@@ -164,37 +168,41 @@ function task(pOptions, pSource = {}) {
|
|
|
164
168
|
})
|
|
165
169
|
//Error
|
|
166
170
|
.catch(rErr => {
|
|
167
|
-
// console.log(`${
|
|
168
|
-
|
|
171
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN ERRO`);
|
|
172
|
+
xSelf.state.error = rErr;
|
|
169
173
|
//Finaliza execução
|
|
170
174
|
return pvStop().finally(() => {
|
|
171
|
-
// console.log(`${
|
|
175
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN FINALLY`);
|
|
172
176
|
//Verifica se fará novas tentativas 'Manual Stop'
|
|
173
|
-
if (
|
|
174
|
-
|
|
177
|
+
if (xSelf.state.retries < xSelf.options.retries) {
|
|
178
|
+
xSelf.state.retries++;
|
|
175
179
|
//Dispara evento retry
|
|
176
|
-
|
|
180
|
+
xSelf.event.emit('retry', xSelf.state.retries);
|
|
177
181
|
//Faz novas tentativas
|
|
178
|
-
// console.log(`${
|
|
179
|
-
return
|
|
182
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* RUN RETRY`);
|
|
183
|
+
return xSelf.run().catch(rErr => {
|
|
180
184
|
//Dispara evento error
|
|
181
|
-
|
|
185
|
+
xSelf.event.emit('error', {
|
|
182
186
|
err: rErr,
|
|
183
|
-
state:
|
|
184
|
-
options:
|
|
187
|
+
state: xSelf.state,
|
|
188
|
+
options: xSelf.options
|
|
185
189
|
});
|
|
186
190
|
return pReject(rErr);
|
|
187
191
|
});
|
|
188
192
|
} else {
|
|
189
193
|
//Dispara evento error
|
|
190
|
-
|
|
194
|
+
xSelf.event.emit('error', {
|
|
195
|
+
err: rErr,
|
|
196
|
+
state: xSelf.state,
|
|
197
|
+
options: xSelf.options
|
|
198
|
+
});
|
|
191
199
|
return pReject(rErr);
|
|
192
200
|
}
|
|
193
201
|
});
|
|
194
202
|
});
|
|
195
203
|
},
|
|
196
204
|
//Delay para efetuar novo restart
|
|
197
|
-
|
|
205
|
+
xSelf.state.retries > 0 ? xSelf.options.delay * 1000 : 0
|
|
198
206
|
);
|
|
199
207
|
});
|
|
200
208
|
};
|
|
@@ -203,27 +211,31 @@ function task(pOptions, pSource = {}) {
|
|
|
203
211
|
* Interrompe a execução da tarefa caso tenha sido agendada
|
|
204
212
|
*
|
|
205
213
|
*/
|
|
206
|
-
|
|
207
|
-
|
|
214
|
+
xSelf.stop = () => {
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
if (xSelf.state.status !== STATUS.RUNNING) {
|
|
208
217
|
return;
|
|
209
218
|
}
|
|
210
|
-
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
xSelf.state.status = STATUS.STOPPING;
|
|
211
221
|
};
|
|
212
222
|
/**
|
|
213
223
|
* Interrompe a execução da tarefa caso tenha sido agendada
|
|
214
224
|
*
|
|
215
225
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
xSelf.isStopping = () => {
|
|
227
|
+
// @ts-ignore
|
|
228
|
+
if (xSelf.state.status !== STATUS.STOPPING) {
|
|
218
229
|
return false;
|
|
219
230
|
}
|
|
220
231
|
//Indica que execução foi parada manualmente
|
|
221
|
-
|
|
232
|
+
xSelf.state.error = 'Manual Stop';
|
|
222
233
|
pvStop();
|
|
223
234
|
return true;
|
|
224
235
|
};
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
xSelf.isRunning = () => {
|
|
237
|
+
// @ts-ignore
|
|
238
|
+
return xSelf.state.status === STATUS.RUNNING;
|
|
227
239
|
};
|
|
228
240
|
/**
|
|
229
241
|
* Retorna próxima data considerando a configuração do schedule.
|
|
@@ -232,25 +244,25 @@ function task(pOptions, pSource = {}) {
|
|
|
232
244
|
* Se não informada, será utilizada a data atual
|
|
233
245
|
* @returns {Date}
|
|
234
246
|
*/
|
|
235
|
-
|
|
236
|
-
// console.log(`${
|
|
237
|
-
if (!
|
|
247
|
+
xSelf.getNextDate = (pBaseDate = null) => {
|
|
248
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* getNextDate(#1)`);
|
|
249
|
+
if (!xSelf.options.schedules || !isArray(xSelf.options.schedules) || xSelf.options.schedules.length === 0) {
|
|
238
250
|
return null;
|
|
239
251
|
}
|
|
240
|
-
// console.log(`${
|
|
252
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* getNextDate(#2)`);
|
|
241
253
|
let xNextDate = null;
|
|
242
254
|
//Pesquisa qual a data mais próximas considerando todos os agendamentos
|
|
243
|
-
for (const xSchedule of
|
|
255
|
+
for (const xSchedule of xSelf.options.schedules) {
|
|
244
256
|
if (xSchedule.type && isObject(xSchedule)) {
|
|
245
257
|
//Calcula próxima data
|
|
246
258
|
const xDate = scheduleToDate(xSchedule, pBaseDate);
|
|
247
|
-
// console.log(`${
|
|
259
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* getNextDate(#3) ${xDate}`);
|
|
248
260
|
if (!xNextDate || xDate < xNextDate) {
|
|
249
261
|
xNextDate = xDate;
|
|
250
262
|
}
|
|
251
263
|
}
|
|
252
264
|
}
|
|
253
|
-
// console.log(`${
|
|
265
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* getNextDate(#4) ${xNextDate}`);
|
|
254
266
|
return xNextDate;
|
|
255
267
|
};
|
|
256
268
|
/**
|
|
@@ -258,37 +270,38 @@ function task(pOptions, pSource = {}) {
|
|
|
258
270
|
*
|
|
259
271
|
*/
|
|
260
272
|
const pvStop = () => {
|
|
261
|
-
// console.log(`${
|
|
262
|
-
|
|
273
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* STOP`);
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
if (xSelf.state.status !== STATUS.RUNNING && xSelf.state.status !== STATUS.STOPPING) {
|
|
263
276
|
return Promise.resolve();
|
|
264
277
|
}
|
|
265
|
-
// console.log(`${
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
278
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* STOPPED`);
|
|
279
|
+
xSelf.state.status = STATUS.STOPPED;
|
|
280
|
+
xSelf.state.endedAt = toDate();
|
|
281
|
+
xSelf.state.duration = xSelf.state.endedAt.getTime() - xSelf.state.startedAt.getTime();
|
|
269
282
|
//Dispara evento stopped
|
|
270
|
-
|
|
283
|
+
xSelf.event.emit('stopped', xSelf.state.error);
|
|
271
284
|
//Inicia novo schedule, se houver
|
|
272
|
-
|
|
285
|
+
xSelf.schedule();
|
|
273
286
|
//Chama afterStop
|
|
274
|
-
return
|
|
287
|
+
return xSelf.afterStop();
|
|
275
288
|
};
|
|
276
289
|
|
|
277
290
|
const pvSetNextDate = () => {
|
|
278
|
-
// console.log(`${
|
|
279
|
-
const xNextDate =
|
|
280
|
-
// console.log(`${
|
|
281
|
-
if (!xNextDate || (
|
|
291
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* setNextDate(#1)`);
|
|
292
|
+
const xNextDate = xSelf.getNextDate();
|
|
293
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* setNextDate(#2) ${xNextDate} ${xSelf.state.nextAt}`);
|
|
294
|
+
if (!xNextDate || (xSelf.state.nextAt && xNextDate.getTime() === xSelf.state.nextAt.getTime())) {
|
|
282
295
|
return false;
|
|
283
296
|
}
|
|
284
|
-
// console.log(`${
|
|
285
|
-
|
|
297
|
+
// console.log(`${xSelf.options.id} ${xSelf.options.name} *-* setNextDate(#3)`);
|
|
298
|
+
xSelf.state.nextAt = xNextDate;
|
|
286
299
|
return true;
|
|
287
300
|
};
|
|
288
301
|
|
|
289
302
|
//Inicia schedule de houver
|
|
290
303
|
setTimeout(() => {
|
|
291
|
-
|
|
304
|
+
xSelf.schedule();
|
|
292
305
|
}, 0);
|
|
293
306
|
}
|
|
294
307
|
|
package/lib/utils/arrays.js
CHANGED
|
@@ -167,6 +167,32 @@ const arrays = {
|
|
|
167
167
|
return pArray.filter((pItem, pIndex) => {
|
|
168
168
|
return pArray.indexOf(pItem) === pIndex;
|
|
169
169
|
});
|
|
170
|
+
},
|
|
171
|
+
/**
|
|
172
|
+
* Retorna se array é iqual
|
|
173
|
+
*
|
|
174
|
+
* @param {*} pArray1
|
|
175
|
+
* @param {*} pArray2
|
|
176
|
+
* @return {*}
|
|
177
|
+
*/
|
|
178
|
+
isEqual: (pArray1, pArray2) => {
|
|
179
|
+
// Check if the arrays have the same length
|
|
180
|
+
if (pArray1.length !== pArray2.length) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Sort the arrays before comparison
|
|
185
|
+
const xSortedArr1 = pArray1.slice().sort();
|
|
186
|
+
const xSortedArr2 = pArray2.slice().sort();
|
|
187
|
+
|
|
188
|
+
// Check each element individually
|
|
189
|
+
for (let i = 0; i < xSortedArr1.length; i++) {
|
|
190
|
+
if (xSortedArr1[i] !== xSortedArr2[i]) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// If all elements are equal, the arrays are equal
|
|
195
|
+
return true;
|
|
170
196
|
}
|
|
171
197
|
};
|
|
172
198
|
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "investira.sdk",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.20",
|
|
4
4
|
"author": "Investira",
|
|
5
5
|
"description": "Investira SDK",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"type": "commonjs",
|
|
8
8
|
"registry": true,
|
|
9
|
-
"raw": "investira.sdk@2.3.
|
|
9
|
+
"raw": "investira.sdk@2.3.20",
|
|
10
10
|
"escapedName": "investira.sdk",
|
|
11
|
-
"rawSpec": "2.3.
|
|
11
|
+
"rawSpec": "2.3.20",
|
|
12
12
|
"saveSpec": null,
|
|
13
|
-
"fetchSpec": "2.3.
|
|
13
|
+
"fetchSpec": "2.3.20",
|
|
14
14
|
"homepage": "https://investira.com.br/",
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": ">=11.11.0 <=18.12",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"axios": "1.5.1",
|
|
39
39
|
"deep-diff": "1.0.2",
|
|
40
40
|
"flatted": "3.2.9",
|
|
41
|
-
"investira.data": "^1.3.
|
|
41
|
+
"investira.data": "^1.3.8",
|
|
42
42
|
"moment": "^2.30.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|