@tstdl/base 0.93.156 → 0.93.157

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.
@@ -42,7 +42,7 @@ let DocumentWorkflowService = DocumentWorkflowService_1 = class DocumentWorkflow
42
42
  documentService = inject(forwardRef(() => DocumentService));
43
43
  repository = injectRepository(DocumentWorkflow);
44
44
  [afterResolve](_, { cancellationSignal }) {
45
- if (this.isInTransaction) {
45
+ if (this.isFork) {
46
46
  return;
47
47
  }
48
48
  this.#taskQueue.process({ concurrency: 5, cancellationSignal }, async (taskContext) => await this.processWorkflowJob(taskContext));
@@ -101,7 +101,7 @@ let EntityRepository = class EntityRepository extends Transactional {
101
101
  return this.#table;
102
102
  }
103
103
  [afterResolve]() {
104
- if (!this.isInTransaction) {
104
+ if (!this.isFork) {
105
105
  void this.expirationLoop();
106
106
  }
107
107
  }
@@ -11,6 +11,7 @@ export type TransactionInitOptions = TransactionConfig & {
11
11
  };
12
12
  export type TransactionHandler<R> = (transaction: Transaction) => Promise<R>;
13
13
  type TransactionalContext<ContextData = unknown> = {
14
+ isFork: boolean;
14
15
  session: Database | PgTransaction;
15
16
  instances: WeakMap<Type, WeakMap<Database | PgTransaction, any>>;
16
17
  data: ContextData;
@@ -26,6 +27,7 @@ export declare abstract class Transactional<ContextData = unknown> {
26
27
  protected transactionalContextData: ContextData | undefined;
27
28
  readonly session: Database | PgTransaction;
28
29
  readonly isInTransaction: boolean;
30
+ readonly isFork: boolean;
29
31
  constructor();
30
32
  /**
31
33
  * Starts a new database transaction.
@@ -42,6 +42,7 @@ export class Transactional {
42
42
  transactionalContextData = this.#context.data;
43
43
  session = this.#context.session ?? inject(Database);
44
44
  isInTransaction = this.session instanceof DrizzlePgTransaction;
45
+ isFork = (this.#context.isFork ?? false) || this.isInTransaction;
45
46
  constructor() {
46
47
  this.#classConstructor = new.target;
47
48
  }
@@ -77,6 +78,7 @@ export class Transactional {
77
78
  return this;
78
79
  }
79
80
  const context = {
81
+ isFork: true,
80
82
  session,
81
83
  instances: this.#instances,
82
84
  data: this.getTransactionalContextData(),
@@ -119,6 +121,7 @@ export class Transactional {
119
121
  return await this.transaction(handler);
120
122
  }
121
123
  const context = {
124
+ isFork: true,
122
125
  session: existingTransaction.pgTransaction,
123
126
  instances: this.#instances,
124
127
  data: this.getTransactionalContextData(),
@@ -139,6 +142,7 @@ export class Transactional {
139
142
  async transaction(handler, config) {
140
143
  const transaction = await this.startTransaction(config);
141
144
  const context = {
145
+ isFork: true,
142
146
  session: transaction.pgTransaction,
143
147
  instances: this.#instances,
144
148
  data: this.getTransactionalContextData(),
package/orm/sqls/sqls.js CHANGED
@@ -8,7 +8,7 @@ import { and, Column, eq, isSQLWrapper, sql, isNotNull as sqlIsNotNull, isNull a
8
8
  import { match, P } from 'ts-pattern';
9
9
  import { distinct, toArray } from '../../utils/array/array.js';
10
10
  import { objectEntries, objectValues } from '../../utils/object/object.js';
11
- import { assertDefined, isArray, isBoolean, isDefined, isInstanceOf, isNotNull, isNull, isNullOrUndefined, isNumber, isObject, isString } from '../../utils/type-guards.js';
11
+ import { assertDefined, isArray, isBoolean, isDefined, isInstanceOf, isLiteralObject, isNotNull, isNull, isNullOrUndefined, isNumber, isString } from '../../utils/type-guards.js';
12
12
  import { getEnumName } from '../enums.js';
13
13
  import { caseWhen } from './case-when.js';
14
14
  const isJsonbSymbol = Symbol('isJsonb');
@@ -454,8 +454,17 @@ export function buildJsonb(value) {
454
454
  const elements = value.map((inner) => buildJsonb(inner));
455
455
  return markAsJsonb(sql `jsonb_build_array(${sql.join(elements, sql `, `)})`);
456
456
  }
457
- if (isObject(value)) {
457
+ if (isLiteralObject(value)) {
458
458
  return jsonbBuildObject(value);
459
459
  }
460
+ if (isString(value)) {
461
+ return markAsJsonb(sql `to_jsonb(${value}::text)`);
462
+ }
463
+ if (isNumber(value)) {
464
+ return markAsJsonb(sql `to_jsonb(${value}::numeric)`);
465
+ }
466
+ if (isBoolean(value)) {
467
+ return markAsJsonb(sql `to_jsonb(${value}::boolean)`);
468
+ }
460
469
  return markAsJsonb(sql `to_jsonb(${value})`);
461
470
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.156",
3
+ "version": "0.93.157",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -135,6 +135,7 @@ export declare class PostgresTaskQueue<Definitions extends TaskDefinitionMap = T
135
135
  private lowFrequencyMaintenanceLoop;
136
136
  private mediumFrequencyMaintenanceLoop;
137
137
  private highFrequencyMaintenanceLoop;
138
+ private logPromiseAllSettledErrors;
138
139
  getBatchConsumer<Type extends TaskTypes<Definitions>>(size: number, cancellationSignal: CancellationSignal, options?: {
139
140
  forceDequeue?: boolean;
140
141
  types?: Type[];
@@ -137,7 +137,7 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
137
137
  result: null,
138
138
  };
139
139
  [afterResolve]() {
140
- if (!this.isInTransaction) {
140
+ if (!this.isFork) {
141
141
  this.maintenanceLoop();
142
142
  }
143
143
  }
@@ -1311,10 +1311,11 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
1311
1311
  async lowFrequencyMaintenanceLoop() {
1312
1312
  while (this.#cancellationSignal.isUnset) {
1313
1313
  try {
1314
- await Promise.allSettled([
1314
+ const results = await Promise.allSettled([
1315
1315
  this.performArchival(),
1316
1316
  this.performArchivePurge(),
1317
1317
  ]);
1318
+ this.logPromiseAllSettledErrors(results, 'low frequency maintenance loop');
1318
1319
  }
1319
1320
  catch (error) {
1320
1321
  this.#logger.error('Error during low frequency maintenance loop', error);
@@ -1327,10 +1328,11 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
1327
1328
  async mediumFrequencyMaintenanceLoop() {
1328
1329
  while (this.#cancellationSignal.isUnset) {
1329
1330
  try {
1330
- await Promise.allSettled([
1331
+ const results = await Promise.allSettled([
1331
1332
  this.processExpirations(),
1332
1333
  this.processPriorityAging(),
1333
1334
  ]);
1335
+ this.logPromiseAllSettledErrors(results, 'medium frequency maintenance loop');
1334
1336
  }
1335
1337
  catch (error) {
1336
1338
  this.#logger.error('Error during medium frequency maintenance loop', error);
@@ -1343,11 +1345,12 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
1343
1345
  async highFrequencyMaintenanceLoop() {
1344
1346
  while (this.#cancellationSignal.isUnset) {
1345
1347
  try {
1346
- await Promise.allSettled([
1348
+ const results = await Promise.allSettled([
1347
1349
  this.processZombieRetries(),
1348
1350
  this.processZombieExhaustions(),
1349
1351
  this.processHardTimeouts(),
1350
1352
  ]);
1353
+ this.logPromiseAllSettledErrors(results, 'high frequency maintenance loop');
1351
1354
  }
1352
1355
  catch (error) {
1353
1356
  this.#logger.error('Error during high frequency maintenance loop', error);
@@ -1357,6 +1360,13 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
1357
1360
  }
1358
1361
  }
1359
1362
  }
1363
+ logPromiseAllSettledErrors(results, context) {
1364
+ for (const result of results) {
1365
+ if (result.status == 'rejected') {
1366
+ this.#logger.error(`Error during ${context}`, result.reason);
1367
+ }
1368
+ }
1369
+ }
1360
1370
  async *getBatchConsumer(size, cancellationSignal, options) {
1361
1371
  const continue$ = merge(this.#messageBus.allMessages$).pipe(filter((namespace) => namespace == this.#namespace));
1362
1372
  const mergedContinue$ = merge(continue$, cancellationSignal);