@guanghechen/task 1.0.0-alpha.9 → 1.0.0-beta.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/lib/esm/index.mjs CHANGED
@@ -1,138 +1,136 @@
1
- import { TaskStatusEnum, ErrorLevelEnum, TaskStrategyEnum } from '@guanghechen/constant';
2
- export { TaskStatusEnum, TaskStrategyEnum } from '@guanghechen/constant';
3
- import { SoraErrorCollector } from '@guanghechen/error';
4
- import { Monitor } from '@guanghechen/monitor';
1
+ import { Observable } from '@guanghechen/observable';
2
+ import { ErrorLevelEnum } from '@guanghechen/error.types';
5
3
 
6
- function noop(..._args) { }
4
+ var TaskStrategyEnum;
5
+ (function (TaskStrategyEnum) {
6
+ TaskStrategyEnum[TaskStrategyEnum["ABORT_ON_ERROR"] = 1] = "ABORT_ON_ERROR";
7
+ TaskStrategyEnum[TaskStrategyEnum["CONTINUE_ON_ERROR"] = 2] = "CONTINUE_ON_ERROR";
8
+ })(TaskStrategyEnum || (TaskStrategyEnum = {}));
9
+ var TaskStatusEnum;
10
+ (function (TaskStatusEnum) {
11
+ TaskStatusEnum[TaskStatusEnum["PENDING"] = 1] = "PENDING";
12
+ TaskStatusEnum[TaskStatusEnum["RUNNING"] = 2] = "RUNNING";
13
+ TaskStatusEnum[TaskStatusEnum["SUSPENDED"] = 4] = "SUSPENDED";
14
+ TaskStatusEnum[TaskStatusEnum["CANCELLED"] = 8] = "CANCELLED";
15
+ TaskStatusEnum[TaskStatusEnum["FAILED"] = 16] = "FAILED";
16
+ TaskStatusEnum[TaskStatusEnum["COMPLETED"] = 32] = "COMPLETED";
17
+ TaskStatusEnum[TaskStatusEnum["ATTEMPT_SUSPENDING"] = 64] = "ATTEMPT_SUSPENDING";
18
+ TaskStatusEnum[TaskStatusEnum["ATTEMPT_RESUMING"] = 128] = "ATTEMPT_RESUMING";
19
+ TaskStatusEnum[TaskStatusEnum["ATTEMPT_CANCELING"] = 256] = "ATTEMPT_CANCELING";
20
+ TaskStatusEnum[TaskStatusEnum["ATTEMPT_COMPLETING"] = 512] = "ATTEMPT_COMPLETING";
21
+ })(TaskStatusEnum || (TaskStatusEnum = {}));
7
22
 
8
- const active = TaskStatusEnum.RUNNING |
9
- TaskStatusEnum.ATTEMPT_SUSPENDING |
10
- TaskStatusEnum.ATTEMPT_RESUMING;
11
- const alive = TaskStatusEnum.PENDING |
12
- TaskStatusEnum.RUNNING |
13
- TaskStatusEnum.SUSPENDED |
14
- TaskStatusEnum.ATTEMPT_SUSPENDING |
15
- TaskStatusEnum.ATTEMPT_RESUMING;
16
- const terminated = TaskStatusEnum.CANCELLED |
17
- TaskStatusEnum.FAILED |
18
- TaskStatusEnum.FINISHED;
19
- class TaskState {
20
- name;
21
- _errorCollector;
22
- _monitorAddError;
23
- _monitorStatusChange;
24
- _status;
25
- constructor(name) {
26
- this.name = name;
27
- this._errorCollector = new SoraErrorCollector(name);
28
- this._monitorAddError = new Monitor('onAddError');
29
- this._monitorStatusChange = new Monitor('onStatusChange');
30
- this._status = TaskStatusEnum.PENDING;
31
- }
32
- get status() {
33
- return this._status;
34
- }
35
- get active() {
36
- return (this._status & active) > 0;
23
+ const _terminated = TaskStatusEnum.CANCELLED | TaskStatusEnum.FAILED | TaskStatusEnum.COMPLETED;
24
+ const _transitionMap = {
25
+ [TaskStatusEnum.PENDING]: TaskStatusEnum.PENDING |
26
+ TaskStatusEnum.RUNNING |
27
+ TaskStatusEnum.CANCELLED |
28
+ TaskStatusEnum.ATTEMPT_CANCELING,
29
+ [TaskStatusEnum.RUNNING]: TaskStatusEnum.RUNNING |
30
+ TaskStatusEnum.SUSPENDED |
31
+ _terminated |
32
+ TaskStatusEnum.ATTEMPT_SUSPENDING |
33
+ TaskStatusEnum.ATTEMPT_CANCELING |
34
+ TaskStatusEnum.ATTEMPT_COMPLETING,
35
+ [TaskStatusEnum.SUSPENDED]: TaskStatusEnum.RUNNING |
36
+ TaskStatusEnum.SUSPENDED |
37
+ _terminated |
38
+ TaskStatusEnum.ATTEMPT_RESUMING |
39
+ TaskStatusEnum.ATTEMPT_CANCELING |
40
+ TaskStatusEnum.ATTEMPT_COMPLETING,
41
+ [TaskStatusEnum.CANCELLED]: TaskStatusEnum.CANCELLED,
42
+ [TaskStatusEnum.FAILED]: TaskStatusEnum.FAILED,
43
+ [TaskStatusEnum.COMPLETED]: TaskStatusEnum.COMPLETED,
44
+ [TaskStatusEnum.ATTEMPT_SUSPENDING]: TaskStatusEnum.SUSPENDED |
45
+ _terminated |
46
+ TaskStatusEnum.ATTEMPT_SUSPENDING |
47
+ TaskStatusEnum.ATTEMPT_CANCELING |
48
+ TaskStatusEnum.ATTEMPT_COMPLETING,
49
+ [TaskStatusEnum.ATTEMPT_RESUMING]: TaskStatusEnum.RUNNING |
50
+ _terminated |
51
+ TaskStatusEnum.ATTEMPT_RESUMING |
52
+ TaskStatusEnum.ATTEMPT_CANCELING |
53
+ TaskStatusEnum.ATTEMPT_COMPLETING,
54
+ [TaskStatusEnum.ATTEMPT_CANCELING]: _terminated | TaskStatusEnum.ATTEMPT_CANCELING,
55
+ [TaskStatusEnum.ATTEMPT_COMPLETING]: _terminated | TaskStatusEnum.ATTEMPT_COMPLETING,
56
+ };
57
+ class TaskStatus extends Observable {
58
+ constructor() {
59
+ super(TaskStatusEnum.PENDING);
37
60
  }
38
61
  get alive() {
39
- return (this._status & alive) > 0;
62
+ const value = this.getSnapshot();
63
+ return (value & _terminated) === 0;
40
64
  }
41
65
  get terminated() {
42
- return (this._status & terminated) > 0;
66
+ const value = this.getSnapshot();
67
+ return (value & _terminated) > 0;
43
68
  }
44
- get hasError() {
45
- return this._errorCollector.size > 0;
46
- }
47
- get error() {
48
- if (this._errorCollector.size === 0)
49
- return undefined;
50
- return { from: this.name, details: this._errorCollector.errors };
51
- }
52
- set status(status) {
53
- const curStatus = this._status;
54
- if (status !== curStatus) {
55
- const accepted = this.check(status);
56
- if (accepted) {
57
- this._status = status;
58
- this._monitorStatusChange.notify(status, curStatus);
59
- }
60
- else {
61
- throw new TypeError(`[transit] unexpected status: task(${this.name}) cur(${curStatus}) next(${status})`);
62
- }
69
+ dispose() {
70
+ if (this.terminated) {
71
+ if (!this.disposed)
72
+ super.dispose();
73
+ return;
63
74
  }
75
+ this.next(TaskStatusEnum.CANCELLED, { strict: false });
76
+ super.dispose();
64
77
  }
65
- monitor(monitor) {
66
- if (this.terminated)
67
- return noop;
68
- const { onAddError, onStatusChange } = monitor;
69
- const unsubscribeOnAddError = this._monitorAddError.subscribe(onAddError);
70
- const unsubscribeOnStatusChange = this._monitorStatusChange.subscribe(onStatusChange);
71
- return () => {
72
- unsubscribeOnAddError();
73
- unsubscribeOnStatusChange();
74
- };
75
- }
76
- check(nextStatus) {
77
- const status = this._status;
78
- switch (nextStatus) {
79
- case TaskStatusEnum.PENDING:
80
- return false;
81
- case TaskStatusEnum.RUNNING:
82
- return status === TaskStatusEnum.PENDING || status === TaskStatusEnum.ATTEMPT_RESUMING;
83
- case TaskStatusEnum.SUSPENDED:
84
- return status === TaskStatusEnum.ATTEMPT_SUSPENDING;
85
- case TaskStatusEnum.CANCELLED:
86
- return status === TaskStatusEnum.ATTEMPT_CANCELING;
87
- case TaskStatusEnum.FAILED:
88
- return (status !== TaskStatusEnum.PENDING &&
89
- status !== TaskStatusEnum.SUSPENDED &&
90
- (status & terminated) === 0);
91
- case TaskStatusEnum.FINISHED:
92
- return (status !== TaskStatusEnum.PENDING &&
93
- status !== TaskStatusEnum.SUSPENDED &&
94
- (status & terminated) === 0);
95
- case TaskStatusEnum.ATTEMPT_SUSPENDING:
96
- return status === TaskStatusEnum.RUNNING;
97
- case TaskStatusEnum.ATTEMPT_RESUMING:
98
- return status === TaskStatusEnum.SUSPENDED;
99
- case TaskStatusEnum.ATTEMPT_CANCELING:
100
- return (status & alive) > 0;
101
- case TaskStatusEnum.ATTEMPT_FINISHING:
102
- return status !== TaskStatusEnum.PENDING && (status & alive) > 0;
103
- default:
104
- return false;
78
+ next(nextStatus, options) {
79
+ const curStatus = this.getSnapshot();
80
+ if (curStatus === nextStatus)
81
+ return;
82
+ if (this._verifyTransition(curStatus, nextStatus)) {
83
+ super.next(nextStatus, options);
84
+ if ((nextStatus & _terminated) > 0)
85
+ this.dispose();
86
+ return;
87
+ }
88
+ const strict = options?.strict ?? true;
89
+ if (strict) {
90
+ const curStatusName = TaskStatusEnum[curStatus];
91
+ const nextStatusName = TaskStatusEnum[nextStatus];
92
+ throw new RangeError(`Invalid status transition: ${curStatusName} -> ${nextStatusName}.`);
105
93
  }
106
94
  }
107
- cleanup() {
108
- if (!this.terminated)
109
- throw new Error(`[cleanup] task(${this.name}) is not terminated`);
110
- this._errorCollector.cleanup();
111
- this._monitorStatusChange.destroy();
112
- this._monitorAddError.destroy();
113
- }
114
- _addError(type, error, level = ErrorLevelEnum.ERROR) {
115
- this._errorCollector.add(type, error, level);
116
- this._monitorAddError.notify(type, error, level);
95
+ _verifyTransition(curStatus, nextStatus) {
96
+ const validTransitions = _transitionMap[curStatus];
97
+ if (validTransitions === undefined)
98
+ return false;
99
+ return (nextStatus & validTransitions) > 0;
117
100
  }
118
101
  }
119
102
 
120
- class AtomicTask extends TaskState {
103
+ class AtomicTask {
104
+ name;
105
+ status;
106
+ strategy;
107
+ _errors;
121
108
  _promise;
122
- constructor(name) {
123
- super(name);
109
+ constructor(name, strategy) {
110
+ this.name = name;
111
+ this.strategy = strategy;
112
+ this.status = new TaskStatus();
113
+ this._errors = [];
124
114
  this._promise = undefined;
125
115
  }
116
+ get errors() {
117
+ return this._errors;
118
+ }
126
119
  async start() {
127
- if (this.status === TaskStatusEnum.PENDING) {
128
- this.status = TaskStatusEnum.RUNNING;
120
+ if (this.status.getSnapshot() === TaskStatusEnum.PENDING) {
121
+ this.status.next(TaskStatusEnum.RUNNING);
129
122
  this._promise = this.run()
130
123
  .then(() => {
131
- this.status = TaskStatusEnum.FINISHED;
124
+ this.status.next(TaskStatusEnum.COMPLETED, { strict: false });
132
125
  })
133
126
  .catch(error => {
134
- this._addError('AtomicTaskError', error);
135
- this.status = TaskStatusEnum.FAILED;
127
+ const soraError = {
128
+ from: this.name,
129
+ level: ErrorLevelEnum.ERROR,
130
+ details: error,
131
+ };
132
+ this._errors.push(soraError);
133
+ this.status.next(TaskStatusEnum.FAILED, { strict: false });
136
134
  });
137
135
  }
138
136
  return this._promise;
@@ -144,131 +142,164 @@ class AtomicTask extends TaskState {
144
142
  await this._promise;
145
143
  }
146
144
  async cancel() {
147
- if (this.status === TaskStatusEnum.PENDING) {
148
- this.status = TaskStatusEnum.ATTEMPT_CANCELING;
149
- this.status = TaskStatusEnum.CANCELLED;
145
+ if (this.status.terminated)
150
146
  return;
151
- }
152
- if (this.alive)
153
- this.status = TaskStatusEnum.ATTEMPT_CANCELING;
147
+ this.status.next(TaskStatusEnum.ATTEMPT_CANCELING);
154
148
  await this._promise;
149
+ this.status.next(TaskStatusEnum.CANCELLED, { strict: false });
155
150
  }
156
- async finish() {
157
- if (this.status === TaskStatusEnum.PENDING)
151
+ async complete() {
152
+ const status = this.status;
153
+ if (status.getSnapshot() === TaskStatusEnum.PENDING)
158
154
  await this.start();
159
- if (this.alive)
160
- this.status = TaskStatusEnum.ATTEMPT_FINISHING;
155
+ if (status.terminated)
156
+ return;
157
+ status.next(TaskStatusEnum.ATTEMPT_COMPLETING);
161
158
  await this._promise;
159
+ status.next(TaskStatusEnum.COMPLETED, { strict: false });
162
160
  }
163
161
  }
164
162
 
165
- class ResumableTask extends TaskState {
163
+ class ResumableTask {
164
+ name;
165
+ status;
166
166
  strategy;
167
+ _errors;
167
168
  _pollInterval;
168
169
  _execution;
169
170
  _step;
170
- constructor(props) {
171
- super(props.name);
172
- this.strategy = props.strategy;
173
- this._pollInterval = Math.max(0, props.pollInterval);
171
+ constructor(name, strategy, pollInterval) {
172
+ this.name = name;
173
+ this.strategy = strategy;
174
+ this.status = new TaskStatus();
175
+ this._errors = [];
176
+ this._pollInterval = Math.max(0, pollInterval);
174
177
  this._execution = undefined;
175
178
  this._step = undefined;
176
179
  }
180
+ get errors() {
181
+ return this._errors;
182
+ }
177
183
  async start() {
178
- if (this.status === TaskStatusEnum.PENDING) {
179
- this.status = TaskStatusEnum.RUNNING;
184
+ if (this.status.getSnapshot() === TaskStatusEnum.PENDING) {
185
+ this.status.next(TaskStatusEnum.RUNNING);
180
186
  this._execution = this.run();
181
- this.launchStep();
182
- await this._step;
187
+ void this._launchStep();
183
188
  }
184
189
  }
185
190
  async pause() {
186
- if (this.status === TaskStatusEnum.RUNNING) {
187
- this.status = TaskStatusEnum.ATTEMPT_SUSPENDING;
191
+ if (this.status.getSnapshot() === TaskStatusEnum.RUNNING) {
192
+ this.status.next(TaskStatusEnum.ATTEMPT_SUSPENDING);
188
193
  await this._step;
189
- if (this.status === TaskStatusEnum.ATTEMPT_SUSPENDING) {
190
- this.status = TaskStatusEnum.SUSPENDED;
191
- }
194
+ this.status.next(TaskStatusEnum.SUSPENDED, { strict: false });
192
195
  }
193
196
  }
194
197
  async resume() {
195
- if (this.status === TaskStatusEnum.SUSPENDED) {
196
- this.status = TaskStatusEnum.ATTEMPT_RESUMING;
198
+ if (this.status.getSnapshot() === TaskStatusEnum.SUSPENDED) {
199
+ this.status.next(TaskStatusEnum.ATTEMPT_RESUMING);
197
200
  await this._step;
198
- if (this.status === TaskStatusEnum.ATTEMPT_RESUMING) {
199
- this.status = TaskStatusEnum.RUNNING;
200
- this.queueStep();
201
+ if (this.status.getSnapshot() === TaskStatusEnum.ATTEMPT_RESUMING) {
202
+ this.status.next(TaskStatusEnum.RUNNING);
203
+ void this._queueStep();
201
204
  }
202
205
  }
203
206
  }
204
207
  async cancel() {
205
- if (this.alive) {
206
- this.status = TaskStatusEnum.ATTEMPT_CANCELING;
207
- await this._step;
208
- if (this.status === TaskStatusEnum.ATTEMPT_CANCELING) {
209
- this.status = TaskStatusEnum.CANCELLED;
210
- }
211
- }
208
+ if (this.status.terminated)
209
+ return;
210
+ this.status.next(TaskStatusEnum.ATTEMPT_CANCELING);
211
+ await this._step;
212
+ this.status.next(TaskStatusEnum.CANCELLED, { strict: false });
212
213
  }
213
- async finish() {
214
- if (this.status === TaskStatusEnum.PENDING)
214
+ async complete() {
215
+ const status = this.status;
216
+ if (status.getSnapshot() === TaskStatusEnum.PENDING)
215
217
  await this.start();
216
- if (this.alive) {
217
- this.status = TaskStatusEnum.ATTEMPT_FINISHING;
218
- await this._step;
219
- const execution = this._execution;
220
- if (execution) {
221
- while (this.status === TaskStatusEnum.ATTEMPT_FINISHING) {
222
- const step = execution.next();
223
- if (step.done) {
224
- this.status = this.hasError ? TaskStatusEnum.FAILED : TaskStatusEnum.FINISHED;
225
- break;
226
- }
227
- await step.value.catch(error => {
228
- this._addError('ResumableTaskError', error);
229
- switch (this.strategy) {
230
- case TaskStrategyEnum.ABORT_ON_ERROR:
231
- if (!this.terminated)
232
- this.status = TaskStatusEnum.FAILED;
233
- break;
234
- case TaskStrategyEnum.CONTINUE_ON_ERROR:
235
- break;
236
- }
237
- });
238
- }
239
- }
240
- }
241
- }
242
- launchStep() {
243
- if (this.status === TaskStatusEnum.RUNNING && this._step === undefined && this._execution) {
244
- const step = this._execution.next();
218
+ if (status.terminated)
219
+ return;
220
+ status.next(TaskStatusEnum.ATTEMPT_COMPLETING);
221
+ await this._step;
222
+ const execution = this._execution;
223
+ for (let alive = true; alive;) {
224
+ const step = execution.next();
245
225
  if (step.done) {
246
- this.status = this.hasError ? TaskStatusEnum.FAILED : TaskStatusEnum.FINISHED;
247
- return;
226
+ const nextStatus = this._errors.length > 0 ? TaskStatusEnum.FAILED : TaskStatusEnum.COMPLETED;
227
+ status.next(nextStatus, { strict: false });
228
+ break;
248
229
  }
249
- this._step = step.value
250
- .then(() => {
251
- this._step = undefined;
252
- this.queueStep();
253
- })
254
- .catch(error => {
255
- this._step = undefined;
256
- this._addError('ResumableTaskError', error);
230
+ try {
231
+ await step.value;
232
+ }
233
+ catch (error) {
234
+ const soraError = {
235
+ from: this.name,
236
+ level: ErrorLevelEnum.ERROR,
237
+ details: error,
238
+ };
239
+ this._errors.push(soraError);
257
240
  switch (this.strategy) {
258
241
  case TaskStrategyEnum.ABORT_ON_ERROR:
259
- if (!this.terminated)
260
- this.status = TaskStatusEnum.FAILED;
242
+ status.next(TaskStatusEnum.FAILED, { strict: false });
243
+ alive = false;
261
244
  break;
262
245
  case TaskStrategyEnum.CONTINUE_ON_ERROR:
263
- this.queueStep();
246
+ await this._queueStep();
264
247
  break;
265
248
  }
249
+ }
250
+ }
251
+ if (status.alive) {
252
+ const soraError = {
253
+ from: this.name,
254
+ level: ErrorLevelEnum.ERROR,
255
+ details: new RangeError('The task is not terminated.'),
256
+ };
257
+ this._errors.push(soraError);
258
+ }
259
+ }
260
+ async _launchStep() {
261
+ if (this._execution === undefined)
262
+ return;
263
+ if (this._step !== undefined)
264
+ return;
265
+ if (this.status.getSnapshot() !== TaskStatusEnum.RUNNING)
266
+ return;
267
+ const execution = this._execution;
268
+ const step = execution.next();
269
+ if (step.done) {
270
+ this.status.next(this._errors.length > 0 ? TaskStatusEnum.FAILED : TaskStatusEnum.COMPLETED, {
271
+ strict: false,
266
272
  });
273
+ return;
274
+ }
275
+ this._step = step.value;
276
+ try {
277
+ await step.value;
278
+ this._step = undefined;
279
+ void this._queueStep();
280
+ }
281
+ catch (error) {
282
+ this._step = undefined;
283
+ const soraError = {
284
+ from: this.name,
285
+ level: ErrorLevelEnum.ERROR,
286
+ details: error,
287
+ };
288
+ this._errors.push(soraError);
289
+ switch (this.strategy) {
290
+ case TaskStrategyEnum.ABORT_ON_ERROR:
291
+ this.status.next(TaskStatusEnum.FAILED, { strict: false });
292
+ break;
293
+ case TaskStrategyEnum.CONTINUE_ON_ERROR:
294
+ void this._queueStep();
295
+ break;
296
+ }
267
297
  }
268
298
  }
269
- queueStep() {
270
- setTimeout(() => this.launchStep(), this._pollInterval);
299
+ async _queueStep() {
300
+ await new Promise(resolve => setTimeout(resolve, this._pollInterval));
301
+ await this._launchStep();
271
302
  }
272
303
  }
273
304
 
274
- export { AtomicTask, ResumableTask, TaskState };
305
+ export { AtomicTask, ResumableTask, TaskStatus, TaskStatusEnum, TaskStrategyEnum };
@@ -1,58 +1,120 @@
1
- import { TaskStatusEnum, ErrorLevelEnum, TaskStrategyEnum } from '@guanghechen/constant';
2
- export { TaskStatusEnum, TaskStrategyEnum } from '@guanghechen/constant';
3
- import { ITaskState, ISoraErrorCollector, ITaskError, ITaskMonitor, IUnMonitorTask, ITask } from '@guanghechen/types';
4
- export { ITask, ITaskError, ITaskMonitor, ITaskState } from '@guanghechen/types';
1
+ import { IObservable, IObservableNextOptions, Observable } from '@guanghechen/observable';
5
2
 
6
- declare class TaskState implements ITaskState {
3
+ declare enum TaskStrategyEnum {
4
+ ABORT_ON_ERROR = 1,// Abort the task if any error occurred.
5
+ CONTINUE_ON_ERROR = 2
6
+ }
7
+ declare enum TaskStatusEnum {
8
+ PENDING = 1,// Task not start.
9
+ RUNNING = 2,// Task is running.
10
+ SUSPENDED = 4,// Task is paused.
11
+ CANCELLED = 8,// Task is cancelled.
12
+ FAILED = 16,// Task is failed.
13
+ COMPLETED = 32,// Task is completed.
14
+ ATTEMPT_SUSPENDING = 64,// Attempting to suspend the task.
15
+ ATTEMPT_RESUMING = 128,// Attempting to resume the task.
16
+ ATTEMPT_CANCELING = 256,// Attempting to cancel the task.
17
+ ATTEMPT_COMPLETING = 512
18
+ }
19
+
20
+ interface ITaskStatus extends IObservable<TaskStatusEnum> {
21
+ /**
22
+ * Whether the task was alive.
23
+ */
24
+ readonly alive: boolean;
25
+ /**
26
+ * Whether the task was terminated.
27
+ */
28
+ readonly terminated: boolean;
29
+ /**
30
+ *
31
+ * @param nextStatus
32
+ * @param options
33
+ */
34
+ next(nextStatus: TaskStatusEnum, options?: IObservableNextOptions): void;
35
+ }
36
+ interface ITask {
37
+ /**
38
+ * Task name.
39
+ */
7
40
  readonly name: string;
8
- protected readonly _errorCollector: ISoraErrorCollector;
9
- private readonly _monitorAddError;
10
- private readonly _monitorStatusChange;
11
- private _status;
12
- constructor(name: string);
13
- get status(): TaskStatusEnum;
14
- get active(): boolean;
41
+ /**
42
+ * Task status.
43
+ */
44
+ readonly status: ITaskStatus;
45
+ /**
46
+ * Task strategy.
47
+ */
48
+ readonly strategy: TaskStrategyEnum;
49
+ /**
50
+ * Errors while run the task.
51
+ */
52
+ readonly errors: ReadonlyArray<unknown>;
53
+ /**
54
+ * Start the task.
55
+ */
56
+ start(): Promise<void>;
57
+ /**
58
+ * Pause the task.
59
+ */
60
+ pause(): Promise<void>;
61
+ /**
62
+ * Resume the task.
63
+ */
64
+ resume(): Promise<void>;
65
+ /**
66
+ * Cancel the task.
67
+ */
68
+ cancel(): Promise<void>;
69
+ /**
70
+ * finish the task: run to completed no matter if the task started or not.
71
+ */
72
+ complete(): Promise<void>;
73
+ }
74
+
75
+ declare class TaskStatus extends Observable<TaskStatusEnum> implements ITaskStatus {
76
+ constructor();
15
77
  get alive(): boolean;
16
78
  get terminated(): boolean;
17
- get hasError(): boolean;
18
- get error(): ITaskError | undefined;
19
- set status(status: TaskStatusEnum);
20
- monitor(monitor: Partial<ITaskMonitor>): IUnMonitorTask;
21
- check(nextStatus: TaskStatusEnum): boolean;
22
- cleanup(): void;
23
- protected _addError(type: string, error: unknown, level?: ErrorLevelEnum): void;
79
+ dispose(): void;
80
+ next(nextStatus: TaskStatusEnum, options?: IObservableNextOptions): void;
81
+ protected _verifyTransition(curStatus: TaskStatusEnum, nextStatus: TaskStatusEnum): boolean;
24
82
  }
25
83
 
26
- declare abstract class AtomicTask extends TaskState implements ITask {
84
+ declare abstract class AtomicTask implements ITask {
85
+ readonly name: string;
86
+ readonly status: ITaskStatus;
87
+ readonly strategy: TaskStrategyEnum;
88
+ protected readonly _errors: unknown[];
27
89
  private _promise;
28
- constructor(name: string);
90
+ constructor(name: string, strategy: TaskStrategyEnum);
91
+ get errors(): ReadonlyArray<unknown>;
29
92
  start(): Promise<void>;
30
93
  pause(): Promise<void>;
31
94
  resume(): Promise<void>;
32
95
  cancel(): Promise<void>;
33
- finish(): Promise<void>;
96
+ complete(): Promise<void>;
34
97
  protected abstract run(): Promise<void>;
35
98
  }
36
99
 
37
- interface IResumableTaskProps {
38
- name: string;
39
- strategy: TaskStrategyEnum;
40
- pollInterval: number;
41
- }
42
- declare abstract class ResumableTask extends TaskState implements ITask {
100
+ declare abstract class ResumableTask implements ITask {
101
+ readonly name: string;
102
+ readonly status: ITaskStatus;
43
103
  readonly strategy: TaskStrategyEnum;
104
+ protected readonly _errors: unknown[];
44
105
  private readonly _pollInterval;
45
106
  private _execution;
46
107
  private _step;
47
- constructor(props: IResumableTaskProps);
108
+ constructor(name: string, strategy: TaskStrategyEnum, pollInterval: number);
109
+ get errors(): ReadonlyArray<unknown>;
48
110
  start(): Promise<void>;
49
111
  pause(): Promise<void>;
50
112
  resume(): Promise<void>;
51
113
  cancel(): Promise<void>;
52
- finish(): Promise<void>;
114
+ complete(): Promise<void>;
53
115
  protected abstract run(): IterableIterator<Promise<void>>;
54
- private launchStep;
55
- private queueStep;
116
+ private _launchStep;
117
+ private _queueStep;
56
118
  }
57
119
 
58
- export { AtomicTask, ResumableTask, TaskState };
120
+ export { AtomicTask, type ITask, type ITaskStatus, ResumableTask, TaskStatus, TaskStatusEnum, TaskStrategyEnum };