@tstdl/base 0.93.91 → 0.93.93

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.
Files changed (42) hide show
  1. package/authentication/client/authentication.service.js +8 -8
  2. package/document-management/server/services/document-validation.service.js +5 -5
  3. package/document-management/server/services/document-workflow.service.js +2 -2
  4. package/orm/sqls/sqls.d.ts +6 -6
  5. package/package.json +2 -2
  6. package/task-queue/enqueue-batch.d.ts +16 -11
  7. package/task-queue/enqueue-batch.js +2 -2
  8. package/task-queue/index.d.ts +2 -1
  9. package/task-queue/index.js +2 -1
  10. package/task-queue/postgres/drizzle/{0000_thin_black_panther.sql → 0000_simple_invisible_woman.sql} +5 -5
  11. package/task-queue/postgres/drizzle/meta/0000_snapshot.json +11 -11
  12. package/task-queue/postgres/drizzle/meta/_journal.json +2 -2
  13. package/task-queue/postgres/module.js +2 -2
  14. package/task-queue/postgres/schemas.d.ts +1 -1
  15. package/task-queue/postgres/schemas.js +2 -2
  16. package/task-queue/postgres/task-queue.d.ts +101 -47
  17. package/task-queue/postgres/task-queue.js +149 -139
  18. package/task-queue/postgres/task-queue.provider.d.ts +3 -4
  19. package/task-queue/postgres/task-queue.provider.js +2 -2
  20. package/task-queue/postgres/task.model.d.ts +5 -5
  21. package/task-queue/postgres/task.model.js +5 -5
  22. package/task-queue/provider.d.ts +2 -2
  23. package/task-queue/task-context.d.ts +34 -18
  24. package/task-queue/task-context.js +23 -13
  25. package/task-queue/task-queue.d.ts +160 -132
  26. package/task-queue/task-queue.js +8 -8
  27. package/task-queue/tests/complex.test.js +36 -29
  28. package/task-queue/tests/dependencies.test.js +17 -17
  29. package/task-queue/tests/enqueue-item.test.d.ts +1 -0
  30. package/task-queue/tests/enqueue-item.test.js +12 -0
  31. package/task-queue/tests/queue-generic.test.d.ts +1 -0
  32. package/task-queue/tests/queue-generic.test.js +8 -0
  33. package/task-queue/tests/queue.test.js +50 -50
  34. package/task-queue/tests/task-context.test.d.ts +1 -0
  35. package/task-queue/tests/task-context.test.js +7 -0
  36. package/task-queue/tests/task-union.test.d.ts +1 -0
  37. package/task-queue/tests/task-union.test.js +18 -0
  38. package/task-queue/tests/typing.test.d.ts +1 -0
  39. package/task-queue/tests/typing.test.js +9 -0
  40. package/task-queue/tests/worker.test.js +16 -16
  41. package/task-queue/types.d.ts +48 -0
  42. package/task-queue/types.js +1 -0
@@ -24,7 +24,7 @@ import { currentTimestampSeconds } from '../../utils/date-time.js';
24
24
  import { formatError } from '../../utils/format-error.js';
25
25
  import { timeout } from '../../utils/timing.js';
26
26
  import { assertDefinedPass, isDefined, isNotFunction, isNullOrUndefined, isUndefined } from '../../utils/type-guards.js';
27
- import { millisecondsPerSecond } from '../../utils/units.js';
27
+ import { millisecondsPerMinute, millisecondsPerSecond } from '../../utils/units.js';
28
28
  import { AUTHENTICATION_API_CLIENT, INITIAL_AUTHENTICATION_DATA } from './tokens.js';
29
29
  const tokenStorageKey = 'AuthenticationService:token';
30
30
  const rawTokenStorageKey = 'AuthenticationService:raw-token';
@@ -36,6 +36,7 @@ const tokenUpdateBusName = 'AuthenticationService:tokenUpdate';
36
36
  const loggedOutBusName = 'AuthenticationService:loggedOut';
37
37
  const refreshLockResource = 'AuthenticationService:refresh';
38
38
  const refreshBufferSeconds = 15;
39
+ const maxRefreshDelay = 15 * millisecondsPerMinute;
39
40
  const lockTimeout = 10000;
40
41
  const logoutTimeout = 150;
41
42
  const unrecoverableErrors = [
@@ -380,7 +381,7 @@ let AuthenticationClientService = class AuthenticationClientService {
380
381
  if (isUndefined(token)) {
381
382
  // Wait for login or dispose.
382
383
  // We ignore forceRefreshToken here because we can't refresh without a token.
383
- await firstValueFrom(race([this.definedToken$, this.disposeToken]));
384
+ await firstValueFrom(race([this.definedToken$, this.disposeToken]), { defaultValue: undefined });
384
385
  continue;
385
386
  }
386
387
  const now = this.estimatedServerTimestampSeconds();
@@ -401,11 +402,11 @@ let AuthenticationClientService = class AuthenticationClientService {
401
402
  if (!lockAcquired) {
402
403
  // Lock held by another instance, wait 5 seconds or until state/token changes.
403
404
  // We ignore forceRefreshToken here to avoid a busy loop if it is already set.
404
- await firstValueFrom(race([timer(5000), this.disposeToken, this.token$.pipe(filter((t) => t !== token))]));
405
+ await firstValueFrom(race([timer(5000), this.disposeToken, this.token$.pipe(filter((t) => t !== token))]), { defaultValue: undefined });
405
406
  continue;
406
407
  }
407
408
  }
408
- const delay = ((this.token()?.exp ?? 0) - this.estimatedServerTimestampSeconds() - refreshBufferSeconds) * millisecondsPerSecond;
409
+ const delay = Math.min(maxRefreshDelay, ((this.token()?.exp ?? 0) - this.estimatedServerTimestampSeconds() - refreshBufferSeconds) * millisecondsPerSecond);
409
410
  const wakeUpSignals = [
410
411
  this.disposeToken,
411
412
  this.token$.pipe(filter((t) => t != token)),
@@ -414,16 +415,15 @@ let AuthenticationClientService = class AuthenticationClientService {
414
415
  wakeUpSignals.push(this.forceRefreshToken);
415
416
  }
416
417
  if (delay > 0) {
417
- await firstValueFrom(race([timer(delay), ...wakeUpSignals]));
418
+ await firstValueFrom(race([timer(delay), ...wakeUpSignals]), { defaultValue: undefined });
418
419
  }
419
420
  else {
420
- // If expired (or within buffer) and we didn't refresh (e.g. refresh failed or lock contention), wait a bit to avoid tight loop
421
- await firstValueFrom(race([timer(5000), ...wakeUpSignals]));
421
+ await firstValueFrom(race([timer(5000), ...wakeUpSignals]), { defaultValue: undefined });
422
422
  }
423
423
  }
424
424
  catch (error) {
425
425
  this.logger.error(error);
426
- await firstValueFrom(race([timer(5000), this.disposeToken, this.token$.pipe(filter((t) => t !== this.token()))]));
426
+ await firstValueFrom(race([timer(5000), this.disposeToken, this.token$.pipe(filter((t) => t !== this.token()))]), { defaultValue: undefined });
427
427
  }
428
428
  }
429
429
  }
@@ -14,7 +14,7 @@ import { injectionToken } from '../../../injector/token.js';
14
14
  import { Logger } from '../../../logger/logger.js';
15
15
  import { getEntityIds } from '../../../orm/index.js';
16
16
  import { injectRepository } from '../../../orm/server/index.js';
17
- import { TaskQueue, TaskResult } from '../../../task-queue/task-queue.js';
17
+ import { TaskProcessResult, TaskQueue } from '../../../task-queue/task-queue.js';
18
18
  import { currentTimestamp } from '../../../utils/date-time.js';
19
19
  import { isNull, isUndefined } from '../../../utils/type-guards.js';
20
20
  import { millisecondsPerMinute } from '../../../utils/units.js';
@@ -45,10 +45,10 @@ let DocumentValidationService = DocumentValidationService_1 = class DocumentVali
45
45
  this.processQueue(cancellationSignal);
46
46
  }
47
47
  processQueue(cancellationSignal) {
48
- this.#taskQueue.process({ concurrency: 5, cancellationSignal }, async (job) => {
49
- this.#logger.verbose(`Processing validation execution "${job.data.executionId}"`);
50
- await this.processValidationExecution(job.data.tenantId, job.data.executionId);
51
- return TaskResult.Complete();
48
+ this.#taskQueue.process({ concurrency: 5, cancellationSignal }, async (task) => {
49
+ this.#logger.verbose(`Processing validation execution "${task.data.executionId}"`);
50
+ await this.processValidationExecution(task.data.tenantId, task.data.executionId);
51
+ return TaskProcessResult.Complete();
52
52
  });
53
53
  }
54
54
  async startValidationWorkflow(tenantId, documentId) {
@@ -13,7 +13,7 @@ import { inject } from '../../../injector/inject.js';
13
13
  import { afterResolve } from '../../../injector/interfaces.js';
14
14
  import { Logger } from '../../../logger/index.js';
15
15
  import { injectRepository, injectTransactional, Transactional } from '../../../orm/server/index.js';
16
- import { TaskQueue, TaskResult } from '../../../task-queue/task-queue.js';
16
+ import { TaskProcessResult, TaskQueue } from '../../../task-queue/task-queue.js';
17
17
  import { toArray } from '../../../utils/array/array.js';
18
18
  import { currentTimestamp } from '../../../utils/date-time.js';
19
19
  import { _throw } from '../../../utils/throw.js';
@@ -109,7 +109,7 @@ let DocumentWorkflowService = DocumentWorkflowService_1 = class DocumentWorkflow
109
109
  else {
110
110
  await this.setWorkflowState(workflow.id, DocumentWorkflowState.Review);
111
111
  }
112
- return TaskResult.Complete();
112
+ return TaskProcessResult.Complete();
113
113
  }
114
114
  catch (error) {
115
115
  if (task.triesLeft == 0) {
@@ -152,7 +152,7 @@ export declare namespace jsonAgg {
152
152
  * @param columns - The columns or SQL expressions to check.
153
153
  * @returns A Drizzle SQL object representing the coalesced value.
154
154
  */
155
- export declare function coalesce<T extends (Column | SQL)[]>(...columns: T): SQL<SelectResultField<T>[number]>;
155
+ export declare function coalesce<T extends (Column | SQL | SQL.Aliased)[]>(...columns: T): SQL<SelectResultField<T>[number]>;
156
156
  /**
157
157
  * Creates a PostgreSQL `to_jsonb` function call.
158
158
  * Converts the input column or SQL expression to a JSONB value.
@@ -160,26 +160,26 @@ export declare function coalesce<T extends (Column | SQL)[]>(...columns: T): SQL
160
160
  * @param column - The column or SQL expression to convert.
161
161
  * @returns A Drizzle SQL object representing the value as JSONB.
162
162
  */
163
- export declare function toJsonb<T extends (Column | SQL)>(column: T): SQL<SelectResultField<T>>;
163
+ export declare function toJsonb<T extends (Column | SQL | SQL.Aliased)>(column: T): SQL<SelectResultField<T>>;
164
164
  /**
165
165
  * Creates a PostgreSQL `num_nulls` function call.
166
166
  * Counts the number of null arguments.
167
167
  * @param columns - The columns to check for nulls.
168
168
  * @returns A Drizzle SQL object representing the count of nulls.
169
169
  */
170
- export declare function numNulls(...columns: Column[]): SQL<number>;
170
+ export declare function numNulls(...columns: (Column | SQL | SQL.Aliased)[]): SQL<number>;
171
171
  /**
172
172
  * Creates a PostgreSQL `num_nonnulls` function call.
173
173
  * Counts the number of non-null arguments.
174
174
  * @param columns - The columns to check for non-nulls.
175
175
  * @returns A Drizzle SQL object representing the count of non-nulls.
176
176
  */
177
- export declare function numNonNulls(...columns: Column[]): SQL<number>;
178
- export declare function least<T extends (Column | SQL | number)[]>(...values: T): SQL<SelectResultField<{
177
+ export declare function numNonNulls(...columns: (Column | SQL | SQL.Aliased)[]): SQL<number>;
178
+ export declare function least<T extends (Column | SQL | SQL.Aliased | number)[]>(...values: T): SQL<SelectResultField<{
179
179
  [P in keyof T]: T[P] extends number ? Exclude<T[P], number> | SQL<number> : T[P];
180
180
  }[number]>>;
181
181
  export declare function least<T>(...values: T[]): SQL<SelectResultField<T>>;
182
- export declare function greatest<T extends (Column | SQL | number)[]>(...values: T): SQL<SelectResultField<{
182
+ export declare function greatest<T extends (Column | SQL | SQL.Aliased | number)[]>(...values: T): SQL<SelectResultField<{
183
183
  [P in keyof T]: T[P] extends number ? Exclude<T[P], number> | SQL<number> : T[P];
184
184
  }[number]>>;
185
185
  export declare function greatest<T>(...values: T[]): SQL<SelectResultField<T>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.91",
3
+ "version": "0.93.93",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -167,7 +167,7 @@
167
167
  "preact": "^10.28",
168
168
  "preact-render-to-string": "^6.6",
169
169
  "sharp": "^0.34",
170
- "undici": "^7.18",
170
+ "undici": "^7.19",
171
171
  "urlpattern-polyfill": "^10.1",
172
172
  "zod": "^3.25"
173
173
  },
@@ -1,17 +1,22 @@
1
- import type { EnqueueManyItem, EnqueueOptions, Task, TaskQueue } from './task-queue.js';
2
- export interface TaskQueueEnqueueBatchMethods<Data, State, Result> {
3
- add(...args: Parameters<TaskQueue<Data, State, Result>['enqueue']>): void;
4
- enqueue(): ReturnType<TaskQueue<Data, State, Result>['enqueueMany']>;
1
+ import type { EnqueueManyItem, EnqueueManyOptions, EnqueueOptions, Task, TaskQueue } from './task-queue.js';
2
+ import type { TaskData, TaskDefinitionMap, TaskTypes } from './types.js';
3
+ export interface TaskQueueEnqueueBatchMethods<Definitions extends TaskDefinitionMap> {
4
+ add<Type extends TaskTypes<Definitions>>(type: Type, data: TaskData<Definitions, Type>, options?: EnqueueOptions): void;
5
+ enqueue(options?: EnqueueManyOptions): Promise<Task<Definitions>[] | undefined>;
5
6
  }
6
- export declare class TaskQueueEnqueueBatch<Data, State, Result> implements TaskQueueEnqueueBatchMethods<Data, State, Result> {
7
+ export declare class TaskQueueEnqueueBatch<Definitions extends TaskDefinitionMap> implements TaskQueueEnqueueBatchMethods<Definitions> {
7
8
  private readonly queue;
8
9
  /** added items */
9
- items: EnqueueManyItem<Data>[];
10
- constructor(queue: TaskQueue<Data, State, Result>);
10
+ items: EnqueueManyItem<Definitions, TaskTypes<Definitions>>[];
11
+ constructor(queue: TaskQueue<Definitions>);
11
12
  /** add data to items */
12
- add(type: string, data: Data, options?: EnqueueOptions): void;
13
+ add<Type extends TaskTypes<Definitions>>(type: Type, data: TaskData<Definitions, Type>, options?: EnqueueOptions): void;
13
14
  /** enqueues all added items */
14
- enqueue(returnTasks?: false): Promise<void>;
15
- enqueue(returnTasks: true): Promise<Task<Data, State, Result>[]>;
16
- enqueue(returnTasks?: boolean): Promise<Task<Data, State, Result>[] | undefined>;
15
+ enqueue(options?: EnqueueManyOptions & {
16
+ returnTasks?: false;
17
+ }): Promise<void>;
18
+ enqueue(options: EnqueueManyOptions & {
19
+ returnTasks: true;
20
+ }): Promise<Task<Definitions>[]>;
21
+ enqueue(options?: EnqueueManyOptions): Promise<Task<Definitions>[] | undefined>;
17
22
  }
@@ -10,11 +10,11 @@ export class TaskQueueEnqueueBatch {
10
10
  add(type, data, options) {
11
11
  this.items.push({ type, data, ...options });
12
12
  }
13
- async enqueue(returnTasks) {
13
+ async enqueue(options) {
14
14
  const items = this.items;
15
15
  this.items = [];
16
16
  try {
17
- return await this.queue.enqueueMany(items, { returnTasks });
17
+ return await this.queue.enqueueMany(items, options);
18
18
  }
19
19
  catch (error) {
20
20
  this.items.unshift(...items);
@@ -1,4 +1,5 @@
1
1
  export * from './enqueue-batch.js';
2
2
  export * from './provider.js';
3
- export * from './task-queue.js';
4
3
  export * from './task-context.js';
4
+ export * from './task-queue.js';
5
+ export * from './types.js';
@@ -1,4 +1,5 @@
1
1
  export * from './enqueue-batch.js';
2
2
  export * from './provider.js';
3
- export * from './task-queue.js';
4
3
  export * from './task-context.js';
4
+ export * from './task-queue.js';
5
+ export * from './types.js';
@@ -1,10 +1,10 @@
1
1
  CREATE TYPE "task_queue"."dependency_join_mode" AS ENUM('and', 'or');--> statement-breakpoint
2
- CREATE TYPE "task_queue"."task_state" AS ENUM('pending', 'running', 'completed', 'cancelled', 'waiting', 'dead');--> statement-breakpoint
2
+ CREATE TYPE "task_queue"."task_status" AS ENUM('pending', 'running', 'completed', 'cancelled', 'waiting', 'dead');--> statement-breakpoint
3
3
  CREATE TABLE "task_queue"."task" (
4
4
  "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
5
5
  "namespace" text NOT NULL,
6
6
  "type" text NOT NULL,
7
- "status" "task_queue"."task_state" NOT NULL,
7
+ "status" "task_queue"."task_status" NOT NULL,
8
8
  "idempotency_key" text,
9
9
  "trace_id" text,
10
10
  "tags" text[] NOT NULL,
@@ -12,7 +12,7 @@ CREATE TABLE "task_queue"."task" (
12
12
  "schedule_after_tags" text[] NOT NULL,
13
13
  "fail_fast" boolean NOT NULL,
14
14
  "dependency_join_mode" "task_queue"."dependency_join_mode" NOT NULL,
15
- "dependency_trigger_states" "task_queue"."task_state"[] NOT NULL,
15
+ "dependency_trigger_statuses" "task_queue"."task_status"[] NOT NULL,
16
16
  "priority" integer NOT NULL,
17
17
  "token" uuid,
18
18
  "creation_timestamp" timestamp with time zone NOT NULL,
@@ -36,7 +36,7 @@ CREATE TABLE "task_queue"."task_archive" (
36
36
  "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
37
37
  "namespace" text NOT NULL,
38
38
  "type" text NOT NULL,
39
- "status" "task_queue"."task_state" NOT NULL,
39
+ "status" "task_queue"."task_status" NOT NULL,
40
40
  "idempotency_key" text,
41
41
  "trace_id" text,
42
42
  "tags" text[] NOT NULL,
@@ -44,7 +44,7 @@ CREATE TABLE "task_queue"."task_archive" (
44
44
  "schedule_after_tags" text[] NOT NULL,
45
45
  "fail_fast" boolean NOT NULL,
46
46
  "dependency_join_mode" "task_queue"."dependency_join_mode" NOT NULL,
47
- "dependency_trigger_states" "task_queue"."task_state"[] NOT NULL,
47
+ "dependency_trigger_statuses" "task_queue"."task_status"[] NOT NULL,
48
48
  "priority" integer NOT NULL,
49
49
  "token" uuid,
50
50
  "creation_timestamp" timestamp with time zone NOT NULL,
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "0d47b6da-b49b-4717-b789-f4ea71b3b8e7",
2
+ "id": "4a091e17-ecca-4dcc-9681-ee533ba465a9",
3
3
  "prevId": "00000000-0000-0000-0000-000000000000",
4
4
  "version": "7",
5
5
  "dialect": "postgresql",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "status": {
31
31
  "name": "status",
32
- "type": "task_state",
32
+ "type": "task_status",
33
33
  "typeSchema": "task_queue",
34
34
  "primaryKey": false,
35
35
  "notNull": true
@@ -77,9 +77,9 @@
77
77
  "primaryKey": false,
78
78
  "notNull": true
79
79
  },
80
- "dependency_trigger_states": {
81
- "name": "dependency_trigger_states",
82
- "type": "task_state[]",
80
+ "dependency_trigger_statuses": {
81
+ "name": "dependency_trigger_statuses",
82
+ "type": "task_status[]",
83
83
  "typeSchema": "task_queue",
84
84
  "primaryKey": false,
85
85
  "notNull": true
@@ -374,7 +374,7 @@
374
374
  },
375
375
  "status": {
376
376
  "name": "status",
377
- "type": "task_state",
377
+ "type": "task_status",
378
378
  "typeSchema": "task_queue",
379
379
  "primaryKey": false,
380
380
  "notNull": true
@@ -422,9 +422,9 @@
422
422
  "primaryKey": false,
423
423
  "notNull": true
424
424
  },
425
- "dependency_trigger_states": {
426
- "name": "dependency_trigger_states",
427
- "type": "task_state[]",
425
+ "dependency_trigger_statuses": {
426
+ "name": "dependency_trigger_statuses",
427
+ "type": "task_status[]",
428
428
  "typeSchema": "task_queue",
429
429
  "primaryKey": false,
430
430
  "notNull": true
@@ -566,8 +566,8 @@
566
566
  "or"
567
567
  ]
568
568
  },
569
- "task_queue.task_state": {
570
- "name": "task_state",
569
+ "task_queue.task_status": {
570
+ "name": "task_status",
571
571
  "schema": "task_queue",
572
572
  "values": [
573
573
  "pending",
@@ -5,8 +5,8 @@
5
5
  {
6
6
  "idx": 0,
7
7
  "version": "7",
8
- "when": 1768609540962,
9
- "tag": "0000_thin_black_panther",
8
+ "when": 1769034172474,
9
+ "tag": "0000_simple_invisible_woman",
10
10
  "breakpoints": true
11
11
  }
12
12
  ]
@@ -3,7 +3,7 @@ import { Injector } from '../../injector/injector.js';
3
3
  import { Database, migrate } from '../../orm/server/index.js';
4
4
  import { TaskQueueProvider } from '../provider.js';
5
5
  import { TaskQueue } from '../task-queue.js';
6
- import { PostgresQueue } from './task-queue.js';
6
+ import { PostgresTaskQueue } from './task-queue.js';
7
7
  import { PostgresTaskQueueProvider } from './task-queue.provider.js';
8
8
  export class PostgresTaskQueueModuleConfig {
9
9
  database;
@@ -15,7 +15,7 @@ export function configurePostgresTaskQueue({ injector, ...config } = {}) {
15
15
  const targetInjector = injector ?? Injector;
16
16
  targetInjector.register(PostgresTaskQueueModuleConfig, { useValue: config });
17
17
  targetInjector.registerSingleton(TaskQueueProvider, { useToken: PostgresTaskQueueProvider });
18
- targetInjector.registerSingleton(TaskQueue, { useToken: PostgresQueue });
18
+ targetInjector.registerSingleton(TaskQueue, { useToken: PostgresTaskQueue });
19
19
  }
20
20
  export async function migratePostgresTaskQueueSchema() {
21
21
  const connection = inject(PostgresTaskQueueModuleConfig, undefined, { optional: true })?.database?.connection;
@@ -1,6 +1,6 @@
1
1
  import { PostgresTask, PostgresTaskArchive } from './task.model.js';
2
2
  export declare const taskQueueSchema: import("../../orm/server/index.js").DatabaseSchema<"task_queue">;
3
- export declare const taskState: import("../../orm/enums.js").PgEnumFromEnumeration<{
3
+ export declare const taskStatus: import("../../orm/enums.js").PgEnumFromEnumeration<{
4
4
  readonly Pending: "pending";
5
5
  readonly Running: "running";
6
6
  readonly Completed: "completed";
@@ -1,8 +1,8 @@
1
1
  import { databaseSchema } from '../../orm/server/index.js';
2
- import { DependencyJoinMode, TaskState } from '../task-queue.js';
2
+ import { DependencyJoinMode, TaskStatus } from '../task-queue.js';
3
3
  import { PostgresTask, PostgresTaskArchive } from './task.model.js';
4
4
  export const taskQueueSchema = databaseSchema('task_queue');
5
- export const taskState = taskQueueSchema.getEnum(TaskState);
5
+ export const taskStatus = taskQueueSchema.getEnum(TaskStatus);
6
6
  export const dependencyJoinMode = taskQueueSchema.getEnum(DependencyJoinMode);
7
7
  export const task = taskQueueSchema.getTable(PostgresTask);
8
8
  export const taskArchive = taskQueueSchema.getTable(PostgresTaskArchive);
@@ -3,9 +3,9 @@ import { afterResolve } from '../../injector/index.js';
3
3
  import type { Query } from '../../orm/index.js';
4
4
  import { type Transaction } from '../../orm/server/index.js';
5
5
  import type { OneOrMany } from '../../schema/index.js';
6
- import type { ObjectLiteral } from '../../types/index.js';
7
6
  import { TaskQueue, type EnqueueManyItem, type EnqueueManyOptions, type EnqueueOneOptions, type Task } from '../task-queue.js';
8
- export declare class PostgresQueue<Data extends ObjectLiteral, State extends ObjectLiteral, Result extends ObjectLiteral> extends TaskQueue<Data, State, Result> {
7
+ import type { TaskData, TaskDefinitionMap, TaskOfType, TaskResult, TasksResults, TasksStates, TaskState, TaskTypes } from '../types.js';
8
+ export declare class PostgresTaskQueue<Definitions extends TaskDefinitionMap = TaskDefinitionMap> extends TaskQueue<Definitions> {
9
9
  #private;
10
10
  readonly visibilityTimeout: number;
11
11
  readonly maxExecutionTime: number;
@@ -23,61 +23,115 @@ export declare class PostgresQueue<Data extends ObjectLiteral, State extends Obj
23
23
  readonly idempotencyWindow: number;
24
24
  readonly globalConcurrency: number | null;
25
25
  [afterResolve](): void;
26
- enqueue(type: string, data: Data, options?: EnqueueOneOptions): Promise<Task<Data, State, Result>>;
27
- enqueueMany(items: EnqueueManyItem<Data>[], options?: EnqueueManyOptions & {
26
+ enqueue<Type extends TaskTypes<Definitions>>(type: Type, data: TaskData<Definitions, Type>, options?: EnqueueOneOptions): Promise<TaskOfType<Definitions, Type>>;
27
+ enqueueMany<Type extends TaskTypes<Definitions>>(items: EnqueueManyItem<Definitions, Type>[], options?: EnqueueManyOptions & {
28
28
  returnTasks?: false;
29
29
  }): Promise<void>;
30
- enqueueMany(items: EnqueueManyItem<Data>[], options: EnqueueManyOptions & {
30
+ enqueueMany<Type extends TaskTypes<Definitions>>(items: EnqueueManyItem<Definitions, Type>[], options: EnqueueManyOptions & {
31
31
  returnTasks: true;
32
- }): Promise<Task<Data, State, Result>[]>;
33
- enqueueMany(items: EnqueueManyItem<Data>[], options?: EnqueueManyOptions): Promise<Task<Data, State, Result>[] | undefined>;
34
- has(id: string): Promise<boolean>;
35
- countByTags(tags: OneOrMany<string>): Promise<number>;
36
- getTask(id: string): Promise<Task<Data, State, Result> | undefined>;
37
- getManyByTags(tags: OneOrMany<string>): Promise<Task<Data, State, Result>[]>;
38
- getTree(idOrIds: string | string[], transaction?: Transaction): Promise<Task<unknown, unknown, unknown>[]>;
39
- getTreeByQuery(query: Query<Task>, transaction?: Transaction): Promise<Task<unknown, unknown, unknown>[]>;
40
- cancel(id: string, transaction?: Transaction): Promise<void>;
41
- cancelMany(ids: string[], transaction?: Transaction): Promise<void>;
42
- cancelManyByTags(tags: OneOrMany<string>): Promise<void>;
43
- clear(): Promise<void>;
44
- dequeue(options?: {
32
+ }): Promise<TaskOfType<Definitions, Type>[]>;
33
+ enqueueMany<Type extends TaskTypes<Definitions>>(items: EnqueueManyItem<Definitions, Type>[], options?: EnqueueManyOptions): Promise<TaskOfType<Definitions, Type>[] | undefined>;
34
+ has(id: string, options?: {
35
+ transaction?: Transaction;
36
+ }): Promise<boolean>;
37
+ countByTags(tags: OneOrMany<string>, options?: {
38
+ transaction?: Transaction;
39
+ }): Promise<number>;
40
+ getTask<Type extends TaskTypes<Definitions> = TaskTypes<Definitions>>(id: string, options?: {
41
+ transaction?: Transaction;
42
+ }): Promise<TaskOfType<Definitions, Type> | undefined>;
43
+ getManyByTags<Type extends TaskTypes<Definitions>>(tags: OneOrMany<string>, options?: {
44
+ transaction?: Transaction;
45
+ }): Promise<TaskOfType<Definitions, Type>[]>;
46
+ getTree(rootId: string | string[], options?: {
47
+ transaction?: Transaction;
48
+ }): Promise<Task[]>;
49
+ getTreeByQuery(query: Query<Task>, options?: {
50
+ transaction?: Transaction;
51
+ }): Promise<Task[]>;
52
+ cancel(id: string, options?: {
53
+ transaction?: Transaction;
54
+ }): Promise<void>;
55
+ cancelMany(ids: string[], options?: {
56
+ transaction?: Transaction;
57
+ }): Promise<void>;
58
+ cancelManyByTags(tags: OneOrMany<string>, options?: {
59
+ transaction?: Transaction;
60
+ }): Promise<void>;
61
+ clear(options?: {
62
+ transaction?: Transaction;
63
+ }): Promise<void>;
64
+ dequeue<Type extends TaskTypes<Definitions>>(options?: {
45
65
  forceDequeue?: boolean;
46
- types?: string[];
47
- }): Promise<Task<Data, State, Result> | undefined>;
48
- dequeueMany(count: number, options?: {
66
+ types?: Type[];
67
+ transaction?: Transaction;
68
+ }): Promise<TaskOfType<Definitions, Type> | undefined>;
69
+ dequeueMany<Type extends TaskTypes<Definitions>>(count: number, options?: {
49
70
  forceDequeue?: boolean;
50
- types?: string[];
51
- }): Promise<Task<Data, State, Result>[]>;
52
- reschedule(id: string, timestamp: number, transaction?: Transaction): Promise<void>;
53
- rescheduleMany(ids: string[], timestamp: number, transaction?: Transaction): Promise<void>;
54
- rescheduleManyByTags(tags: OneOrMany<string>, timestamp: number, transaction?: Transaction): Promise<void>;
55
- touch(task: Task, options?: {
71
+ types?: Type[];
72
+ transaction?: Transaction;
73
+ }): Promise<TaskOfType<Definitions, Type>[]>;
74
+ reschedule(id: string, timestamp: number, options?: {
75
+ transaction?: Transaction;
76
+ }): Promise<void>;
77
+ rescheduleMany(ids: string[], timestamp: number, options?: {
78
+ transaction?: Transaction;
79
+ }): Promise<void>;
80
+ rescheduleManyByTags(tags: OneOrMany<string>, timestamp: number, options?: {
81
+ transaction?: Transaction;
82
+ }): Promise<void>;
83
+ touch<Type extends TaskTypes<Definitions>>(task: TaskOfType<Definitions, Type>, options?: {
56
84
  progress?: number;
57
- state?: State;
58
- transaction?: Transaction;
59
- }): Promise<Task<Data, State, Result> | undefined>;
60
- touchMany(tasks: Task[], progresses?: number[], states?: State[], transaction?: Transaction): Promise<string[]>;
61
- complete<R>(task: Task<any, any, R>, result?: R, transaction?: Transaction): Promise<void>;
62
- completeMany<R>(tasks: Task<any, any, R>[], results?: R[], transaction?: Transaction): Promise<void>;
63
- fail(task: Task, error: any, fatal?: boolean, transaction?: Transaction): Promise<void>;
64
- triggerTagFanIn(tags: string[], transaction?: Transaction): Promise<void>;
65
- failMany(tasks: Task[], errors: any[], transaction?: Transaction): Promise<void>;
66
- resolveDependencies(targetTags: string[]): Promise<void>;
67
- maintenance(): Promise<void>;
85
+ state?: TaskState<Definitions, Type>;
86
+ transaction?: Transaction;
87
+ }): Promise<TaskOfType<Definitions, Type> | undefined>;
88
+ touchMany<T extends Task<Definitions>[]>(tasks: T, options?: {
89
+ progresses?: number[];
90
+ states?: TasksStates<T>;
91
+ transaction?: Transaction;
92
+ }): Promise<string[]>;
93
+ complete<Type extends TaskTypes<Definitions>>(task: TaskOfType<Definitions, Type>, options?: {
94
+ result?: TaskResult<Definitions, Type>;
95
+ transaction?: Transaction;
96
+ }): Promise<void>;
97
+ completeMany<Tasks extends Task<Definitions>[]>(tasks: Tasks, options?: {
98
+ results?: TasksResults<Tasks>;
99
+ transaction?: Transaction;
100
+ }): Promise<void>;
101
+ fail(task: Task<Definitions>, error: unknown, options?: {
102
+ fatal?: boolean;
103
+ transaction?: Transaction;
104
+ }): Promise<void>;
105
+ triggerTagFanIn(tags: string[], options?: {
106
+ transaction?: Transaction;
107
+ }): Promise<void>;
108
+ failMany(tasks: Task<Definitions>[], errors: unknown[], options?: {
109
+ transaction?: Transaction;
110
+ }): Promise<void>;
111
+ private resolveDependencies;
112
+ maintenance(options?: {
113
+ transaction?: Transaction;
114
+ }): Promise<void>;
68
115
  restart(id: string, options?: {
69
116
  resetState?: boolean;
70
117
  transaction?: Transaction;
71
118
  }): Promise<void>;
72
- getConsumer(cancellationSignal: CancellationSignal, options?: {
119
+ getConsumer<Type extends TaskTypes<Definitions>>(cancellationSignal: CancellationSignal, options?: {
73
120
  forceDequeue?: boolean;
74
- types?: string[];
75
- }): AsyncIterableIterator<Task<Data, State, Result>>;
76
- maintenanceLoop(): Promise<void>;
77
- processPendingFanIn(transaction?: Transaction): Promise<number>;
78
- startSystemWorker(): void;
79
- getBatchConsumer(size: number, cancellationSignal: CancellationSignal, options?: {
121
+ types?: Type[];
122
+ }): AsyncIterableIterator<TaskOfType<Definitions, Type>>;
123
+ private maintenanceLoop;
124
+ /**
125
+ * @internal for internal unit test use only
126
+ * @param options
127
+ * @returns
128
+ */
129
+ processPendingFanIn(options?: {
130
+ transaction?: Transaction;
131
+ }): Promise<number>;
132
+ private startSystemWorker;
133
+ getBatchConsumer<Type extends TaskTypes<Definitions>>(size: number, cancellationSignal: CancellationSignal, options?: {
80
134
  forceDequeue?: boolean;
81
- types?: string[];
82
- }): AsyncIterableIterator<Task<Data, State, Result>[]>;
135
+ types?: Type[];
136
+ }): AsyncIterableIterator<TaskOfType<Definitions, Type>[]>;
83
137
  }