@tstdl/base 0.93.141 → 0.93.143
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/authentication/client/authentication.service.d.ts +1 -0
- package/authentication/client/authentication.service.js +3 -2
- package/circuit-breaker/circuit-breaker.d.ts +6 -4
- package/circuit-breaker/postgres/circuit-breaker.d.ts +1 -0
- package/circuit-breaker/postgres/circuit-breaker.js +8 -5
- package/circuit-breaker/tests/circuit-breaker.test.js +20 -0
- package/examples/document-management/main.js +2 -2
- package/notification/tests/notification-api.test.js +5 -1
- package/notification/tests/notification-flow.test.js +9 -6
- package/orm/decorators.d.ts +17 -4
- package/orm/decorators.js +9 -0
- package/orm/server/bootstrap.d.ts +11 -0
- package/orm/server/bootstrap.js +31 -0
- package/orm/server/drizzle/schema-converter.d.ts +3 -1
- package/orm/server/drizzle/schema-converter.js +71 -29
- package/orm/server/extension.d.ts +14 -0
- package/orm/server/extension.js +27 -0
- package/orm/server/index.d.ts +2 -0
- package/orm/server/index.js +2 -0
- package/orm/server/migration.d.ts +2 -3
- package/orm/server/migration.js +7 -21
- package/orm/server/repository.d.ts +1 -0
- package/orm/server/repository.js +19 -9
- package/orm/server/transaction.d.ts +1 -0
- package/orm/server/transaction.js +3 -0
- package/orm/tests/database-extension.test.js +63 -0
- package/orm/tests/database-migration.test.js +7 -6
- package/orm/tests/repository-compound-primary-key.test.d.ts +2 -0
- package/orm/tests/repository-compound-primary-key.test.js +234 -0
- package/orm/tests/schema-generation.test.d.ts +1 -0
- package/orm/tests/schema-generation.test.js +52 -5
- package/package.json +4 -4
- package/task-queue/README.md +0 -1
- package/task-queue/postgres/drizzle/0000_faithful_daimon_hellstrom.sql +84 -0
- package/task-queue/postgres/drizzle/meta/0000_snapshot.json +155 -72
- package/task-queue/postgres/drizzle/meta/_journal.json +2 -2
- package/task-queue/postgres/module.js +2 -1
- package/task-queue/postgres/schemas.d.ts +6 -0
- package/task-queue/postgres/task-queue.d.ts +18 -5
- package/task-queue/postgres/task-queue.js +577 -357
- package/task-queue/postgres/task.model.d.ts +10 -6
- package/task-queue/postgres/task.model.js +28 -28
- package/task-queue/task-context.d.ts +10 -5
- package/task-queue/task-context.js +5 -3
- package/task-queue/task-queue.d.ts +342 -38
- package/task-queue/task-queue.js +135 -31
- package/task-queue/tests/coverage-branch.test.js +46 -58
- package/task-queue/tests/coverage-enhancement.test.js +123 -117
- package/task-queue/tests/{extensive-dependencies.test.js → dag.test.js} +66 -37
- package/task-queue/tests/dependencies.test.js +143 -25
- package/task-queue/tests/enqueue-batch.test.js +125 -0
- package/task-queue/tests/fan-out-spawning.test.js +46 -5
- package/task-queue/tests/idempotent-replacement.test.js +54 -1
- package/task-queue/tests/missing-idempotent-tasks.test.js +9 -8
- package/task-queue/tests/queue.test.js +261 -25
- package/task-queue/tests/shutdown.test.js +41 -0
- package/task-queue/tests/transactions.test.d.ts +1 -0
- package/task-queue/tests/transactions.test.js +47 -0
- package/task-queue/tests/worker.test.js +46 -13
- package/task-queue/tests/zombie-parent.test.js +4 -4
- package/task-queue/tests/zombie-recovery.test.js +3 -3
- package/testing/integration-setup.js +5 -3
- package/utils/timing.d.ts +2 -2
- package/task-queue/postgres/drizzle/0000_wakeful_sunspot.sql +0 -82
- package/task-queue/tests/cascading-cancellations.test.js +0 -38
- package/task-queue/tests/complex.test.js +0 -122
- package/task-queue/tests/dag-dependencies.test.js +0 -41
- /package/{task-queue/tests/cascading-cancellations.test.d.ts → orm/tests/database-extension.test.d.ts} +0 -0
- /package/task-queue/tests/{complex.test.d.ts → dag.test.d.ts} +0 -0
- /package/task-queue/tests/{dag-dependencies.test.d.ts → enqueue-batch.test.d.ts} +0 -0
- /package/task-queue/tests/{extensive-dependencies.test.d.ts → shutdown.test.d.ts} +0 -0
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
/** biome-ignore-all lint/nursery/noExcessiveClassesPerFile: <explanation> */
|
|
2
2
|
import { BaseEntity, type Json, type Timestamp } from '../../orm/index.js';
|
|
3
|
-
import type { ObjectLiteral
|
|
3
|
+
import type { ObjectLiteral } from '../../types/types.js';
|
|
4
4
|
import { type Task, TaskDependencyType, TaskStatus } from '../task-queue.js';
|
|
5
|
-
export declare
|
|
5
|
+
export declare const terminalStatuses: TaskStatus[];
|
|
6
|
+
export declare const finalizedStatuses: TaskStatus[];
|
|
7
|
+
export declare const nonFinalizedStatuses: TaskStatus[];
|
|
8
|
+
export declare const queueableStatuses: TaskStatus[];
|
|
9
|
+
export declare const waitableStatuses: TaskStatus[];
|
|
10
|
+
export declare const queueableOrWaitableStatuses: TaskStatus[];
|
|
11
|
+
export declare abstract class PostgresTaskBase<Data extends ObjectLiteral = ObjectLiteral, State extends ObjectLiteral = ObjectLiteral, Result extends ObjectLiteral = ObjectLiteral> extends BaseEntity implements Task {
|
|
6
12
|
namespace: string;
|
|
7
13
|
type: string;
|
|
8
14
|
status: TaskStatus;
|
|
9
15
|
idempotencyKey: string | null;
|
|
10
16
|
traceId: string | null;
|
|
17
|
+
parentId: string | null;
|
|
11
18
|
tags: string[];
|
|
12
|
-
|
|
19
|
+
abortOnDependencyFailure: boolean;
|
|
13
20
|
priority: number;
|
|
14
21
|
unresolvedScheduleDependencies: number;
|
|
15
22
|
unresolvedCompleteDependencies: number;
|
|
@@ -30,15 +37,12 @@ export declare abstract class PostgresTaskBase<Data extends ObjectLiteral = Obje
|
|
|
30
37
|
}
|
|
31
38
|
export declare class PostgresTask<Data extends ObjectLiteral = ObjectLiteral, State extends ObjectLiteral = ObjectLiteral, Result extends ObjectLiteral = ObjectLiteral> extends PostgresTaskBase<Data, State, Result> implements Task {
|
|
32
39
|
static readonly entityName = "Task";
|
|
33
|
-
parentId: string | null;
|
|
34
40
|
}
|
|
35
41
|
export declare class PostgresTaskArchive<Data extends ObjectLiteral = ObjectLiteral, State extends ObjectLiteral = ObjectLiteral, Result extends ObjectLiteral = ObjectLiteral> extends PostgresTaskBase<Data, State, Result> implements PostgresTask<Data, State, Result> {
|
|
36
42
|
static readonly entityName = "TaskArchive";
|
|
37
|
-
parentId: string | null;
|
|
38
43
|
}
|
|
39
44
|
export declare class PostgresTaskDependency extends BaseEntity {
|
|
40
45
|
static readonly entityName = "TaskDependency";
|
|
41
|
-
namespace: string;
|
|
42
46
|
taskId: string;
|
|
43
47
|
dependencyTaskId: string;
|
|
44
48
|
type: TaskDependencyType;
|
|
@@ -10,15 +10,23 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
import { BaseEntity, ForeignKey, Index, JsonProperty, Table, TimestampProperty, Unique, UuidProperty } from '../../orm/index.js';
|
|
12
12
|
import { Array as ArrayProperty, BooleanProperty, Enumeration, Integer, NumberProperty, StringProperty } from '../../schema/index.js';
|
|
13
|
+
import { isNotNull } from 'drizzle-orm';
|
|
13
14
|
import { TaskDependencyType, TaskStatus } from '../task-queue.js';
|
|
15
|
+
export const terminalStatuses = [TaskStatus.Completed, TaskStatus.Cancelled, TaskStatus.Dead, TaskStatus.TimedOut, TaskStatus.Expired, TaskStatus.Skipped, TaskStatus.Orphaned];
|
|
16
|
+
export const finalizedStatuses = terminalStatuses;
|
|
17
|
+
export const nonFinalizedStatuses = [TaskStatus.Pending, TaskStatus.Retrying, TaskStatus.Waiting, TaskStatus.WaitingChildren, TaskStatus.Running];
|
|
18
|
+
export const queueableStatuses = [TaskStatus.Pending, TaskStatus.Retrying];
|
|
19
|
+
export const waitableStatuses = [TaskStatus.Waiting, TaskStatus.WaitingChildren];
|
|
20
|
+
export const queueableOrWaitableStatuses = [...queueableStatuses, ...waitableStatuses];
|
|
14
21
|
export class PostgresTaskBase extends BaseEntity {
|
|
15
22
|
namespace;
|
|
16
23
|
type;
|
|
17
24
|
status;
|
|
18
25
|
idempotencyKey;
|
|
19
26
|
traceId;
|
|
27
|
+
parentId;
|
|
20
28
|
tags;
|
|
21
|
-
|
|
29
|
+
abortOnDependencyFailure;
|
|
22
30
|
priority;
|
|
23
31
|
unresolvedScheduleDependencies;
|
|
24
32
|
unresolvedCompleteDependencies;
|
|
@@ -57,6 +65,10 @@ __decorate([
|
|
|
57
65
|
StringProperty({ nullable: true }),
|
|
58
66
|
__metadata("design:type", Object)
|
|
59
67
|
], PostgresTaskBase.prototype, "traceId", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
UuidProperty({ nullable: true }),
|
|
70
|
+
__metadata("design:type", Object)
|
|
71
|
+
], PostgresTaskBase.prototype, "parentId", void 0);
|
|
60
72
|
__decorate([
|
|
61
73
|
ArrayProperty(String),
|
|
62
74
|
__metadata("design:type", Array)
|
|
@@ -64,7 +76,7 @@ __decorate([
|
|
|
64
76
|
__decorate([
|
|
65
77
|
BooleanProperty(),
|
|
66
78
|
__metadata("design:type", Boolean)
|
|
67
|
-
], PostgresTaskBase.prototype, "
|
|
79
|
+
], PostgresTaskBase.prototype, "abortOnDependencyFailure", void 0);
|
|
68
80
|
__decorate([
|
|
69
81
|
Integer(),
|
|
70
82
|
__metadata("design:type", Number)
|
|
@@ -135,32 +147,25 @@ __decorate([
|
|
|
135
147
|
], PostgresTaskBase.prototype, "error", void 0);
|
|
136
148
|
let PostgresTask = class PostgresTask extends PostgresTaskBase {
|
|
137
149
|
static entityName = 'Task';
|
|
138
|
-
parentId;
|
|
139
150
|
};
|
|
140
|
-
__decorate([
|
|
141
|
-
UuidProperty({ nullable: true }),
|
|
142
|
-
__metadata("design:type", Object)
|
|
143
|
-
], PostgresTask.prototype, "parentId", void 0);
|
|
144
151
|
PostgresTask = __decorate([
|
|
145
152
|
Table('task', { schema: 'task_queue' }),
|
|
146
153
|
Unique(['namespace', 'idempotencyKey']),
|
|
147
|
-
|
|
148
|
-
Index(['namespace', '
|
|
149
|
-
Index(['
|
|
150
|
-
Index(['
|
|
151
|
-
Index(['
|
|
152
|
-
Index(['
|
|
153
|
-
|
|
154
|
+
Index(['namespace', 'tags'], { using: 'gin' }),
|
|
155
|
+
Index(['namespace', 'priority', 'scheduleTimestamp'], { where: () => ({ status: { $in: queueableStatuses } }) }),
|
|
156
|
+
Index(['namespace', 'type', 'priority', 'scheduleTimestamp'], { where: () => ({ status: { $in: queueableStatuses } }) }),
|
|
157
|
+
Index(['namespace', 'priorityAgeTimestamp'], { where: () => ({ status: { $in: queueableStatuses } }) }),
|
|
158
|
+
Index(['namespace', 'timeToLive'], { where: () => ({ status: { $in: queueableOrWaitableStatuses } }) }),
|
|
159
|
+
Index(['namespace', 'visibilityDeadline'], { where: () => ({ status: TaskStatus.Running }) }),
|
|
160
|
+
Index(['namespace', 'startTimestamp'], { where: () => ({ status: TaskStatus.Running }) }),
|
|
161
|
+
Index(['namespace', 'completeTimestamp'], { where: () => ({ status: { $in: terminalStatuses } }) }),
|
|
162
|
+
Index(['parentId'], { where: (table) => isNotNull(table.parentId) }),
|
|
163
|
+
ForeignKey(() => PostgresTask, ['parentId'], ['id'])
|
|
154
164
|
], PostgresTask);
|
|
155
165
|
export { PostgresTask };
|
|
156
166
|
let PostgresTaskArchive = class PostgresTaskArchive extends PostgresTaskBase {
|
|
157
167
|
static entityName = 'TaskArchive';
|
|
158
|
-
parentId;
|
|
159
168
|
};
|
|
160
|
-
__decorate([
|
|
161
|
-
UuidProperty({ nullable: true }),
|
|
162
|
-
__metadata("design:type", Object)
|
|
163
|
-
], PostgresTaskArchive.prototype, "parentId", void 0);
|
|
164
169
|
PostgresTaskArchive = __decorate([
|
|
165
170
|
Table('task_archive', { schema: 'task_queue' }),
|
|
166
171
|
Index(['namespace', 'completeTimestamp'])
|
|
@@ -168,16 +173,11 @@ PostgresTaskArchive = __decorate([
|
|
|
168
173
|
export { PostgresTaskArchive };
|
|
169
174
|
let PostgresTaskDependency = class PostgresTaskDependency extends BaseEntity {
|
|
170
175
|
static entityName = 'TaskDependency';
|
|
171
|
-
namespace;
|
|
172
176
|
taskId;
|
|
173
177
|
dependencyTaskId;
|
|
174
178
|
type;
|
|
175
179
|
requiredStatuses;
|
|
176
180
|
};
|
|
177
|
-
__decorate([
|
|
178
|
-
StringProperty(),
|
|
179
|
-
__metadata("design:type", String)
|
|
180
|
-
], PostgresTaskDependency.prototype, "namespace", void 0);
|
|
181
181
|
__decorate([
|
|
182
182
|
UuidProperty(),
|
|
183
183
|
__metadata("design:type", String)
|
|
@@ -196,9 +196,9 @@ __decorate([
|
|
|
196
196
|
], PostgresTaskDependency.prototype, "requiredStatuses", void 0);
|
|
197
197
|
PostgresTaskDependency = __decorate([
|
|
198
198
|
Table('task_dependency', { schema: 'task_queue' }),
|
|
199
|
-
Unique(['
|
|
200
|
-
Index(['
|
|
201
|
-
ForeignKey(() => PostgresTask, ['
|
|
202
|
-
ForeignKey(() => PostgresTask, ['
|
|
199
|
+
Unique(['taskId', 'dependencyTaskId', 'type']),
|
|
200
|
+
Index(['dependencyTaskId', 'type']),
|
|
201
|
+
ForeignKey(() => PostgresTask, ['taskId'], ['id'], { onDelete: 'cascade' }),
|
|
202
|
+
ForeignKey(() => PostgresTask, ['dependencyTaskId'], ['id'], { onDelete: 'cascade' })
|
|
203
203
|
], PostgresTaskDependency);
|
|
204
204
|
export { PostgresTaskDependency };
|
|
@@ -3,7 +3,7 @@ import type { Logger } from '../logger/index.js';
|
|
|
3
3
|
import type { Transaction } from '../orm/server/index.js';
|
|
4
4
|
import { TaskQueue, type EnqueueManyItem, type EnqueueOptions } from './task-queue.js';
|
|
5
5
|
import type { TaskData, TaskDefinitionMap, TaskOfType, TaskResult, TaskState, TaskTypes } from './types.js';
|
|
6
|
-
|
|
6
|
+
declare class TaskContextImplementation<Definitions extends TaskDefinitionMap, Type extends TaskTypes<Definitions> = TaskTypes<Definitions>> {
|
|
7
7
|
#private;
|
|
8
8
|
constructor(queue: TaskQueue<Definitions>, task: TaskOfType<Definitions, Type>, signal: CancellationToken, logger: Logger);
|
|
9
9
|
get id(): string;
|
|
@@ -27,10 +27,10 @@ export declare class TaskContext<Definitions extends TaskDefinitionMap, Type ext
|
|
|
27
27
|
state?: TaskState<Definitions, Type>;
|
|
28
28
|
transaction?: Transaction;
|
|
29
29
|
}): Promise<void>;
|
|
30
|
-
spawn<
|
|
31
|
-
spawn<OtherDefinitions extends TaskDefinitionMap,
|
|
32
|
-
spawnMany<
|
|
33
|
-
spawnMany<OtherDefinitions extends TaskDefinitionMap,
|
|
30
|
+
spawn<SpawnType extends TaskTypes<Definitions>>(type: SpawnType, data: TaskData<Definitions, SpawnType>, options?: Omit<EnqueueOptions, 'parentId'>): Promise<TaskOfType<Definitions, SpawnType>>;
|
|
31
|
+
spawn<OtherDefinitions extends TaskDefinitionMap, SpawnType extends TaskTypes<OtherDefinitions>>(queue: TaskQueue<OtherDefinitions>, type: SpawnType, data: OtherDefinitions[SpawnType]['data'], options?: Omit<EnqueueOptions, 'parentId'>): Promise<TaskOfType<OtherDefinitions, SpawnType>>;
|
|
32
|
+
spawnMany<SpawnType extends TaskTypes<Definitions>>(items: EnqueueManyItem<Definitions, SpawnType>[]): Promise<TaskOfType<Definitions, SpawnType>[]>;
|
|
33
|
+
spawnMany<OtherDefinitions extends TaskDefinitionMap, SpawnType extends TaskTypes<OtherDefinitions>>(queue: TaskQueue<OtherDefinitions>, items: EnqueueManyItem<OtherDefinitions, SpawnType>[]): Promise<TaskOfType<OtherDefinitions, SpawnType>[]>;
|
|
34
34
|
/** Stop execution and reschedule the task for later without incrementing tries if possible */
|
|
35
35
|
reschedule(timestamp: number, options?: {
|
|
36
36
|
transaction?: Transaction;
|
|
@@ -44,3 +44,8 @@ export declare class TaskContext<Definitions extends TaskDefinitionMap, Type ext
|
|
|
44
44
|
transaction?: Transaction;
|
|
45
45
|
}): Promise<void>;
|
|
46
46
|
}
|
|
47
|
+
export type TaskContext<Definitions extends TaskDefinitionMap, Type extends TaskTypes<Definitions> = TaskTypes<Definitions>> = Type extends any ? TaskContextImplementation<Definitions, Type> : never;
|
|
48
|
+
export declare const TaskContext: {
|
|
49
|
+
new <Definitions extends TaskDefinitionMap, Type extends TaskTypes<Definitions>>(queue: TaskQueue<Definitions>, task: TaskOfType<Definitions, Type>, signal: CancellationToken, logger: Logger): TaskContext<Definitions, Type>;
|
|
50
|
+
};
|
|
51
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { currentTimestamp } from '../utils/date-time.js';
|
|
2
2
|
import { isInstanceOf, isNumber, isUndefined } from '../utils/type-guards.js';
|
|
3
3
|
import { TaskQueue } from './task-queue.js';
|
|
4
|
-
|
|
4
|
+
class TaskContextImplementation {
|
|
5
5
|
#queue;
|
|
6
6
|
#logger;
|
|
7
7
|
#signal;
|
|
@@ -70,14 +70,15 @@ export class TaskContext {
|
|
|
70
70
|
const data = isForOtherQueue ? dataOrOptionsOrNothing : typeOrData;
|
|
71
71
|
const options = (isForOtherQueue ? optionsOrNothing : dataOrOptionsOrNothing);
|
|
72
72
|
if (isForOtherQueue) {
|
|
73
|
-
return await queueOrType.enqueue(type, data, options);
|
|
73
|
+
return await queueOrType.enqueue(type, data, { ...options, parentId: this.#task.id });
|
|
74
74
|
}
|
|
75
75
|
return await this.#queue.enqueue(type, data, { ...options, parentId: this.#task.id });
|
|
76
76
|
}
|
|
77
77
|
async spawnMany(queueOrItems, itemsOrNothing) {
|
|
78
78
|
const isForOtherQueue = isInstanceOf(queueOrItems, TaskQueue);
|
|
79
79
|
if (isForOtherQueue) {
|
|
80
|
-
|
|
80
|
+
const items = itemsOrNothing.map((item) => ({ ...item, parentId: this.#task.id }));
|
|
81
|
+
return await queueOrItems.enqueueMany(items, { returnTasks: true });
|
|
81
82
|
}
|
|
82
83
|
const items = queueOrItems.map((item) => ({ ...item, parentId: this.#task.id }));
|
|
83
84
|
return await this.#queue.enqueueMany(items, { returnTasks: true });
|
|
@@ -95,3 +96,4 @@ export class TaskContext {
|
|
|
95
96
|
this.#signal.set();
|
|
96
97
|
}
|
|
97
98
|
}
|
|
99
|
+
export const TaskContext = TaskContextImplementation;
|