@guanghechen/task 1.0.0-alpha.9 → 1.0.0-beta.1

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,125 @@
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
+ next(nextStatus, options) {
70
+ const curStatus = this.getSnapshot();
71
+ if (this._verifyTransition(curStatus, nextStatus)) {
72
+ super.next(nextStatus, options);
73
+ if ((nextStatus & _terminated) > 0)
74
+ this.dispose();
75
+ return;
63
76
  }
64
- }
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;
77
+ const strict = options?.strict ?? true;
78
+ if (strict) {
79
+ const curStatusName = TaskStatusEnum[curStatus];
80
+ const nextStatusName = TaskStatusEnum[nextStatus];
81
+ throw new RangeError(`Invalid status transition: ${curStatusName} -> ${nextStatusName}.`);
105
82
  }
106
83
  }
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);
84
+ _verifyTransition(curStatus, nextStatus) {
85
+ const validTransitions = _transitionMap[curStatus];
86
+ if (validTransitions === undefined)
87
+ return false;
88
+ return (nextStatus & validTransitions) > 0;
117
89
  }
118
90
  }
119
91
 
120
- class AtomicTask extends TaskState {
92
+ class AtomicTask {
93
+ name;
94
+ status;
95
+ strategy;
96
+ _errors;
121
97
  _promise;
122
- constructor(name) {
123
- super(name);
98
+ constructor(name, strategy) {
99
+ this.name = name;
100
+ this.strategy = strategy;
101
+ this.status = new TaskStatus();
102
+ this._errors = [];
124
103
  this._promise = undefined;
125
104
  }
105
+ get errors() {
106
+ return this._errors;
107
+ }
126
108
  async start() {
127
- if (this.status === TaskStatusEnum.PENDING) {
128
- this.status = TaskStatusEnum.RUNNING;
109
+ if (this.status.getSnapshot() === TaskStatusEnum.PENDING) {
110
+ this.status.next(TaskStatusEnum.RUNNING);
129
111
  this._promise = this.run()
130
112
  .then(() => {
131
- this.status = TaskStatusEnum.FINISHED;
113
+ this.status.next(TaskStatusEnum.COMPLETED);
132
114
  })
133
115
  .catch(error => {
134
- this._addError('AtomicTaskError', error);
135
- this.status = TaskStatusEnum.FAILED;
116
+ const soraError = {
117
+ from: this.name,
118
+ level: ErrorLevelEnum.ERROR,
119
+ details: error,
120
+ };
121
+ this._errors.push(soraError);
122
+ this.status.next(TaskStatusEnum.FAILED);
136
123
  });
137
124
  }
138
125
  return this._promise;
@@ -144,131 +131,164 @@ class AtomicTask extends TaskState {
144
131
  await this._promise;
145
132
  }
146
133
  async cancel() {
147
- if (this.status === TaskStatusEnum.PENDING) {
148
- this.status = TaskStatusEnum.ATTEMPT_CANCELING;
149
- this.status = TaskStatusEnum.CANCELLED;
134
+ if (this.status.terminated)
150
135
  return;
151
- }
152
- if (this.alive)
153
- this.status = TaskStatusEnum.ATTEMPT_CANCELING;
136
+ this.status.next(TaskStatusEnum.ATTEMPT_CANCELING);
154
137
  await this._promise;
138
+ this.status.next(TaskStatusEnum.CANCELLED, { strict: false });
155
139
  }
156
- async finish() {
157
- if (this.status === TaskStatusEnum.PENDING)
140
+ async complete() {
141
+ const status = this.status;
142
+ if (status.getSnapshot() === TaskStatusEnum.PENDING)
158
143
  await this.start();
159
- if (this.alive)
160
- this.status = TaskStatusEnum.ATTEMPT_FINISHING;
144
+ if (status.terminated)
145
+ return;
146
+ status.next(TaskStatusEnum.ATTEMPT_COMPLETING);
161
147
  await this._promise;
148
+ status.next(TaskStatusEnum.COMPLETED, { strict: false });
162
149
  }
163
150
  }
164
151
 
165
- class ResumableTask extends TaskState {
152
+ class ResumableTask {
153
+ name;
154
+ status;
166
155
  strategy;
156
+ _errors;
167
157
  _pollInterval;
168
158
  _execution;
169
159
  _step;
170
- constructor(props) {
171
- super(props.name);
172
- this.strategy = props.strategy;
173
- this._pollInterval = Math.max(0, props.pollInterval);
160
+ constructor(name, strategy, pollInterval) {
161
+ this.name = name;
162
+ this.strategy = strategy;
163
+ this.status = new TaskStatus();
164
+ this._errors = [];
165
+ this._pollInterval = Math.max(0, pollInterval);
174
166
  this._execution = undefined;
175
167
  this._step = undefined;
176
168
  }
169
+ get errors() {
170
+ return this._errors;
171
+ }
177
172
  async start() {
178
- if (this.status === TaskStatusEnum.PENDING) {
179
- this.status = TaskStatusEnum.RUNNING;
173
+ if (this.status.getSnapshot() === TaskStatusEnum.PENDING) {
174
+ this.status.next(TaskStatusEnum.RUNNING);
180
175
  this._execution = this.run();
181
- this.launchStep();
182
- await this._step;
176
+ void this._launchStep();
183
177
  }
184
178
  }
185
179
  async pause() {
186
- if (this.status === TaskStatusEnum.RUNNING) {
187
- this.status = TaskStatusEnum.ATTEMPT_SUSPENDING;
180
+ if (this.status.getSnapshot() === TaskStatusEnum.RUNNING) {
181
+ this.status.next(TaskStatusEnum.ATTEMPT_SUSPENDING);
188
182
  await this._step;
189
- if (this.status === TaskStatusEnum.ATTEMPT_SUSPENDING) {
190
- this.status = TaskStatusEnum.SUSPENDED;
191
- }
183
+ this.status.next(TaskStatusEnum.SUSPENDED, { strict: false });
192
184
  }
193
185
  }
194
186
  async resume() {
195
- if (this.status === TaskStatusEnum.SUSPENDED) {
196
- this.status = TaskStatusEnum.ATTEMPT_RESUMING;
187
+ if (this.status.getSnapshot() === TaskStatusEnum.SUSPENDED) {
188
+ this.status.next(TaskStatusEnum.ATTEMPT_RESUMING);
197
189
  await this._step;
198
- if (this.status === TaskStatusEnum.ATTEMPT_RESUMING) {
199
- this.status = TaskStatusEnum.RUNNING;
200
- this.queueStep();
190
+ if (this.status.getSnapshot() === TaskStatusEnum.ATTEMPT_RESUMING) {
191
+ this.status.next(TaskStatusEnum.RUNNING);
192
+ void this._queueStep();
201
193
  }
202
194
  }
203
195
  }
204
196
  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
- }
197
+ if (this.status.terminated)
198
+ return;
199
+ this.status.next(TaskStatusEnum.ATTEMPT_CANCELING);
200
+ await this._step;
201
+ this.status.next(TaskStatusEnum.CANCELLED, { strict: false });
212
202
  }
213
- async finish() {
214
- if (this.status === TaskStatusEnum.PENDING)
203
+ async complete() {
204
+ const status = this.status;
205
+ if (status.getSnapshot() === TaskStatusEnum.PENDING)
215
206
  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();
207
+ if (status.terminated)
208
+ return;
209
+ status.next(TaskStatusEnum.ATTEMPT_COMPLETING);
210
+ await this._step;
211
+ const execution = this._execution;
212
+ for (let alive = true; alive;) {
213
+ const step = execution.next();
245
214
  if (step.done) {
246
- this.status = this.hasError ? TaskStatusEnum.FAILED : TaskStatusEnum.FINISHED;
247
- return;
215
+ const nextStatus = this._errors.length > 0 ? TaskStatusEnum.FAILED : TaskStatusEnum.COMPLETED;
216
+ status.next(nextStatus, { strict: false });
217
+ break;
248
218
  }
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);
219
+ try {
220
+ await step.value;
221
+ }
222
+ catch (error) {
223
+ const soraError = {
224
+ from: this.name,
225
+ level: ErrorLevelEnum.ERROR,
226
+ details: error,
227
+ };
228
+ this._errors.push(soraError);
257
229
  switch (this.strategy) {
258
230
  case TaskStrategyEnum.ABORT_ON_ERROR:
259
- if (!this.terminated)
260
- this.status = TaskStatusEnum.FAILED;
231
+ status.next(TaskStatusEnum.FAILED, { strict: false });
232
+ alive = false;
261
233
  break;
262
234
  case TaskStrategyEnum.CONTINUE_ON_ERROR:
263
- this.queueStep();
235
+ await this._queueStep();
264
236
  break;
265
237
  }
238
+ }
239
+ }
240
+ if (status.alive) {
241
+ const soraError = {
242
+ from: this.name,
243
+ level: ErrorLevelEnum.ERROR,
244
+ details: new RangeError('The task is not terminated.'),
245
+ };
246
+ this._errors.push(soraError);
247
+ }
248
+ }
249
+ async _launchStep() {
250
+ if (this._execution === undefined)
251
+ return;
252
+ if (this._step !== undefined)
253
+ return;
254
+ if (this.status.getSnapshot() !== TaskStatusEnum.RUNNING)
255
+ return;
256
+ const execution = this._execution;
257
+ const step = execution.next();
258
+ if (step.done) {
259
+ this.status.next(this._errors.length > 0 ? TaskStatusEnum.FAILED : TaskStatusEnum.COMPLETED, {
260
+ strict: false,
266
261
  });
262
+ return;
263
+ }
264
+ this._step = step.value;
265
+ try {
266
+ await step.value;
267
+ this._step = undefined;
268
+ void this._queueStep();
269
+ }
270
+ catch (error) {
271
+ this._step = undefined;
272
+ const soraError = {
273
+ from: this.name,
274
+ level: ErrorLevelEnum.ERROR,
275
+ details: error,
276
+ };
277
+ this._errors.push(soraError);
278
+ switch (this.strategy) {
279
+ case TaskStrategyEnum.ABORT_ON_ERROR:
280
+ this.status.next(TaskStatusEnum.FAILED, { strict: false });
281
+ break;
282
+ case TaskStrategyEnum.CONTINUE_ON_ERROR:
283
+ void this._queueStep();
284
+ break;
285
+ }
267
286
  }
268
287
  }
269
- queueStep() {
270
- setTimeout(() => this.launchStep(), this._pollInterval);
288
+ async _queueStep() {
289
+ await new Promise(resolve => setTimeout(resolve, this._pollInterval));
290
+ await this._launchStep();
271
291
  }
272
292
  }
273
293
 
274
- export { AtomicTask, ResumableTask, TaskState };
294
+ export { AtomicTask, ResumableTask, TaskStatus, TaskStatusEnum, TaskStrategyEnum };
@@ -1,58 +1,119 @@
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
+ next(nextStatus: TaskStatusEnum, options?: IObservableNextOptions): void;
80
+ protected _verifyTransition(curStatus: TaskStatusEnum, nextStatus: TaskStatusEnum): boolean;
24
81
  }
25
82
 
26
- declare abstract class AtomicTask extends TaskState implements ITask {
83
+ declare abstract class AtomicTask implements ITask {
84
+ readonly name: string;
85
+ readonly status: ITaskStatus;
86
+ readonly strategy: TaskStrategyEnum;
87
+ protected readonly _errors: unknown[];
27
88
  private _promise;
28
- constructor(name: string);
89
+ constructor(name: string, strategy: TaskStrategyEnum);
90
+ get errors(): ReadonlyArray<unknown>;
29
91
  start(): Promise<void>;
30
92
  pause(): Promise<void>;
31
93
  resume(): Promise<void>;
32
94
  cancel(): Promise<void>;
33
- finish(): Promise<void>;
95
+ complete(): Promise<void>;
34
96
  protected abstract run(): Promise<void>;
35
97
  }
36
98
 
37
- interface IResumableTaskProps {
38
- name: string;
39
- strategy: TaskStrategyEnum;
40
- pollInterval: number;
41
- }
42
- declare abstract class ResumableTask extends TaskState implements ITask {
99
+ declare abstract class ResumableTask implements ITask {
100
+ readonly name: string;
101
+ readonly status: ITaskStatus;
43
102
  readonly strategy: TaskStrategyEnum;
103
+ protected readonly _errors: unknown[];
44
104
  private readonly _pollInterval;
45
105
  private _execution;
46
106
  private _step;
47
- constructor(props: IResumableTaskProps);
107
+ constructor(name: string, strategy: TaskStrategyEnum, pollInterval: number);
108
+ get errors(): ReadonlyArray<unknown>;
48
109
  start(): Promise<void>;
49
110
  pause(): Promise<void>;
50
111
  resume(): Promise<void>;
51
112
  cancel(): Promise<void>;
52
- finish(): Promise<void>;
113
+ complete(): Promise<void>;
53
114
  protected abstract run(): IterableIterator<Promise<void>>;
54
- private launchStep;
55
- private queueStep;
115
+ private _launchStep;
116
+ private _queueStep;
56
117
  }
57
118
 
58
- export { AtomicTask, ResumableTask, TaskState };
119
+ export { AtomicTask, type ITask, type ITaskStatus, ResumableTask, TaskStatus, TaskStatusEnum, TaskStrategyEnum };