@tstdl/base 0.93.199 → 0.93.200

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.
@@ -1,6 +1,6 @@
1
1
  import { createDecorator } from '../../reflection/index.js';
2
2
  import { any, Class, object, Property, Schema, schemaTestableToSchema } from '../../schema/index.js';
3
- import { isDefined } from '../../utils/type-guards.js';
3
+ import { isDefined, isUndefined } from '../../utils/type-guards.js';
4
4
  export class JsonSchema extends Schema {
5
5
  name = 'Json';
6
6
  innerSchema;
@@ -21,6 +21,7 @@ export function JsonProperty(options) {
21
21
  if (data.type == 'class') {
22
22
  return Class({ schema: json({ schema: schema ?? object({}, { unknownPropertiesKey: any(), unknownProperties: any(), factory: { type: data.constructor } }) }) })(args[0]);
23
23
  }
24
- return Property(json({ schema: schema ?? object({}, { unknownPropertiesKey: any(), unknownProperties: any(), factory: { type: metadata.type } }) }), optionsRest)(args[0], args[1], args[2]);
24
+ const propertyType = metadata.type;
25
+ return Property(json({ schema: schema ?? object({}, { unknownPropertiesKey: any(), unknownProperties: any(), factory: isUndefined(propertyType) ? undefined : { type: propertyType } }) }), optionsRest)(args[0], args[1], args[2]);
25
26
  });
26
27
  }
@@ -379,7 +379,8 @@ function getPostgresColumnEntries(type, dbSchema, tableName, path = new JsonPath
379
379
  assertDefined(propertyMetadata, `Property "${property}" of type "${type.name}" does not have reflection metadata (path: ${path.toString()}).`);
380
380
  const propertyPrefix = columnReflectionData?.embedded?.prefix;
381
381
  const nestedPrefix = [prefix, isNull(propertyPrefix) ? '' : propertyPrefix ?? `${columnName}_`].join('');
382
- return getPostgresColumnEntries(columnReflectionData?.embedded?.type ?? propertyMetadata.type, dbSchema, tableName, path.add(property), nestedPrefix, { ...options, inherited, table }, rootType);
382
+ const entryType = columnReflectionData?.embedded?.type ?? assertDefinedPass(propertyMetadata.type, 'Missing type for embedded property.');
383
+ return getPostgresColumnEntries(entryType, dbSchema, tableName, path.add(property), nestedPrefix, { ...options, inherited, table }, rootType);
383
384
  }
384
385
  const encrypted = columnReflectionData?.encrypted == true;
385
386
  const unwrappedSchemaIsUint8Array = isInstanceOf(unwrapSchema(schema).schema, Uint8ArraySchema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.199",
3
+ "version": "0.93.200",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -153,8 +153,8 @@
153
153
  "type-fest": "^5.5"
154
154
  },
155
155
  "peerDependencies": {
156
- "@aws-sdk/client-s3": "^3.1026",
157
- "@aws-sdk/s3-request-presigner": "^3.1026",
156
+ "@aws-sdk/client-s3": "3",
157
+ "@aws-sdk/s3-request-presigner": "3",
158
158
  "@genkit-ai/google-genai": "^1.31",
159
159
  "@google-cloud/storage": "^7.19",
160
160
  "@toon-format/toon": "^2.1.0",
@@ -19,7 +19,7 @@ export type TypeMetadata = MetadataBase<'type'> & {
19
19
  };
20
20
  export type PropertyMetadata = MetadataBase<'property'> & {
21
21
  key: string | symbol;
22
- type: AbstractConstructor;
22
+ type: AbstractConstructor | undefined;
23
23
  isAccessor: boolean;
24
24
  data: ContextDataMap;
25
25
  inherited: boolean;
@@ -36,7 +36,7 @@ export type ConstructorParameterMetadata = MetadataBase<'constructor-parameter'>
36
36
  data: ContextDataMap;
37
37
  };
38
38
  export type MethodParameterMetadata = MetadataBase<'method-parameter'> & {
39
- type: AbstractConstructor;
39
+ type: AbstractConstructor | undefined;
40
40
  index: number;
41
41
  data: ContextDataMap;
42
42
  };
@@ -85,20 +85,20 @@ export function getTypeInfoString(type) {
85
85
  lines.push(`${type.name}(${constructorParameters})`);
86
86
  for (const [key, propertyMetadata] of (metadata?.staticProperties ?? [])) {
87
87
  const propertyKey = isSymbol(key) ? `[${key.toString()}]` : key;
88
- lines.push(` static ${propertyKey}: ${propertyMetadata.type.name}`);
88
+ lines.push(` static ${propertyKey}: ${propertyMetadata.type?.name ?? '<unknown>'}`);
89
89
  }
90
90
  for (const [key, methodMetadata] of (metadata?.staticMethods ?? [])) {
91
91
  const propertyKey = isSymbol(key) ? `[${key.toString()}]` : key;
92
- const parameters = methodMetadata.parameters.map((parameter) => parameter.type.name).join(', ');
92
+ const parameters = methodMetadata.parameters.map((parameter) => parameter.type?.name ?? '<unknown>').join(', ');
93
93
  lines.push(` static ${propertyKey}(${parameters}): ${methodMetadata.returnType?.name ?? 'void'}`);
94
94
  }
95
95
  for (const [key, propertyMetadata] of (metadata?.properties ?? [])) {
96
96
  const propertyKey = isSymbol(key) ? `[${key.toString()}]` : key;
97
- lines.push(` ${propertyKey}: ${propertyMetadata.type.name}`);
97
+ lines.push(` ${propertyKey}: ${propertyMetadata.type?.name ?? '<unknown>'}`);
98
98
  }
99
99
  for (const [key, methodMetadata] of (metadata?.methods ?? [])) {
100
100
  const propertyKey = isSymbol(key) ? `[${key.toString()}]` : key;
101
- const parameters = methodMetadata.parameters.map((parameter) => parameter.type.name).join(', ');
101
+ const parameters = methodMetadata.parameters.map((parameter) => parameter.type?.name ?? '<unknown>').join(', ');
102
102
  lines.push(` ${propertyKey}(${parameters}): ${methodMetadata.returnType?.name ?? 'void'}`);
103
103
  }
104
104
  return lines.join('\n');
@@ -56,7 +56,7 @@ export function tryGetFunctionSchemaFromReflection(type, method) {
56
56
  }
57
57
  const parameterSchemas = methodMetadata.parameters.map((parameterMetadata) => {
58
58
  const parameterData = parameterMetadata.data.tryGet('schema') ?? {};
59
- return schemaReflectionDataToSchema(parameterData, parameterMetadata.type, { type, key: `${String(method)}(parameter:${parameterMetadata.index})` });
59
+ return schemaReflectionDataToSchema(parameterData, parameterMetadata.type ?? null, { type, key: `${String(method)}(parameter:${parameterMetadata.index})` });
60
60
  });
61
61
  const parameterNames = methodMetadata.parameters.map((parameterMetadata) => {
62
62
  const parameterData = parameterMetadata.data.tryGet('schema') ?? {};
@@ -219,7 +219,7 @@ function getObjectSchemaPropertiesFromReflection(metadata, type) {
219
219
  const properties = {};
220
220
  for (const [key, propertyMetadata] of metadata.properties) {
221
221
  const reflectionData = propertyMetadata.data.tryGet('schema');
222
- const propertySchema = schemaReflectionDataToSchema(reflectionData, propertyMetadata.type, { type, key });
222
+ const propertySchema = schemaReflectionDataToSchema(reflectionData, propertyMetadata.type ?? null, { type, key });
223
223
  properties[key] = propertySchema;
224
224
  }
225
225
  for (const [key] of metadata.methods) {
@@ -77,12 +77,15 @@ export declare class PostgresTaskQueue<Definitions extends TaskDefinitionMap = T
77
77
  transaction?: Transaction;
78
78
  }): Promise<TaskOfType<Definitions, Type>[]>;
79
79
  reschedule(id: string, timestamp: number, options?: {
80
+ refundRateLimit?: boolean;
80
81
  transaction?: Transaction;
81
82
  }): Promise<void>;
82
83
  rescheduleMany(ids: string[], timestamp: number, options?: {
84
+ refundRateLimit?: boolean;
83
85
  transaction?: Transaction;
84
86
  }): Promise<void>;
85
87
  rescheduleManyByTags(tags: OneOrMany<string>, timestamp: number, options?: {
88
+ refundRateLimit?: boolean;
86
89
  transaction?: Transaction;
87
90
  }): Promise<void>;
88
91
  touch<Type extends TaskTypes<Definitions>>(task: TaskOfType<Definitions, Type>, options?: {
@@ -691,7 +691,7 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
691
691
  }
692
692
  async rescheduleMany(ids, timestamp, options) {
693
693
  const session = options?.transaction?.pgTransaction ?? this.#repository.session;
694
- await session
694
+ const result = await session
695
695
  .update(taskTable)
696
696
  .set({
697
697
  status: caseWhen(gt(taskTable.unresolvedScheduleDependencies, 0), enumValue(taskStatus, TaskStatus.Waiting)).else(enumValue(taskStatus, TaskStatus.Pending)),
@@ -700,11 +700,20 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
700
700
  visibilityDeadline: null,
701
701
  tries: caseWhen(eq(taskTable.status, enumValue(taskStatus, TaskStatus.Running)), greatest(0, sql `${taskTable.tries} - 1`)).else(taskTable.tries),
702
702
  })
703
- .where(and(inArray(taskTable.id, ids), notInArray(taskTable.status, terminalStatuses)));
703
+ .where(and(inArray(taskTable.id, ids), notInArray(taskTable.status, terminalStatuses)))
704
+ .returning({ id: taskTable.id });
705
+ if ((result.length > 0) && (options?.refundRateLimit == true)) {
706
+ try {
707
+ await this.#rateLimiter.refund(this.#namespace, result.length);
708
+ }
709
+ catch (error) {
710
+ this.#logger.error(error);
711
+ }
712
+ }
704
713
  }
705
714
  async rescheduleManyByTags(tags, timestamp, options) {
706
715
  const session = options?.transaction?.pgTransaction ?? this.#repository.session;
707
- await session
716
+ const result = await session
708
717
  .update(taskTable)
709
718
  .set({
710
719
  status: caseWhen(gt(taskTable.unresolvedScheduleDependencies, 0), enumValue(taskStatus, TaskStatus.Waiting)).else(enumValue(taskStatus, TaskStatus.Pending)),
@@ -713,7 +722,16 @@ let PostgresTaskQueue = class PostgresTaskQueue extends TaskQueue {
713
722
  visibilityDeadline: null,
714
723
  tries: caseWhen(eq(taskTable.status, enumValue(taskStatus, TaskStatus.Running)), greatest(0, sql `${taskTable.tries} - 1`)).else(taskTable.tries),
715
724
  })
716
- .where(and(eq(taskTable.namespace, this.#namespace), arrayOverlaps(taskTable.tags, toArray(tags)), notInArray(taskTable.status, terminalStatuses)));
725
+ .where(and(eq(taskTable.namespace, this.#namespace), arrayOverlaps(taskTable.tags, toArray(tags)), notInArray(taskTable.status, terminalStatuses)))
726
+ .returning({ id: taskTable.id });
727
+ if ((result.length > 0) && (options?.refundRateLimit == true)) {
728
+ try {
729
+ await this.#rateLimiter.refund(this.#namespace, result.length);
730
+ }
731
+ catch (error) {
732
+ this.#logger.error(error);
733
+ }
734
+ }
717
735
  }
718
736
  async touch(task, options) {
719
737
  if (isNull(task.token)) {
@@ -33,10 +33,12 @@ declare class TaskContextImplementation<Definitions extends TaskDefinitionMap, T
33
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
+ refundRateLimit?: boolean;
36
37
  transaction?: Transaction;
37
38
  }): Promise<void>;
38
39
  reschedule(rescheduleOptions: {
39
40
  delay: number;
41
+ refundRateLimit?: boolean;
40
42
  transaction?: Transaction;
41
43
  }): Promise<void>;
42
44
  fail(error: unknown, options?: {
@@ -83,12 +83,12 @@ class TaskContextImplementation {
83
83
  const items = queueOrItems.map((item) => ({ ...item, parentId: this.#task.id }));
84
84
  return await this.#queue.enqueueMany(items, { returnTasks: true });
85
85
  }
86
- async reschedule(timestampOrDelay) {
86
+ async reschedule(timestampOrDelay, maybeOptions) {
87
87
  const isTimestamp = isNumber(timestampOrDelay);
88
88
  const timestamp = isTimestamp ? timestampOrDelay : (currentTimestamp() + timestampOrDelay.delay);
89
- const transaction = isTimestamp ? undefined : timestampOrDelay.transaction;
89
+ const options = isTimestamp ? maybeOptions : timestampOrDelay;
90
90
  this.#logger.debug(`Rescheduling task for ${new Date(timestamp).toISOString()}.`);
91
- await this.#queue.reschedule(this.#task.id, timestamp, { transaction });
91
+ await this.#queue.reschedule(this.#task.id, timestamp, options);
92
92
  this.#signal.set();
93
93
  }
94
94
  async fail(error, options) {
@@ -31,13 +31,19 @@ export declare class TaskProcessResult<Result = unknown> {
31
31
  /**
32
32
  * Creates a result that reschedules the task to a specific timestamp.
33
33
  * @param timestamp The timestamp to reschedule to.
34
+ * @param options Optional refund flags.
34
35
  */
35
- static RescheduleTo<R>(timestamp: number): TaskProcessResult<R>;
36
+ static RescheduleTo<R>(timestamp: number, options?: {
37
+ refundRateLimit?: boolean;
38
+ }): TaskProcessResult<R>;
36
39
  /**
37
40
  * Creates a result that reschedules the task by a specific number of milliseconds.
38
41
  * @param milliseconds The number of milliseconds to reschedule by.
42
+ * @param options Optional refund flags.
39
43
  */
40
- static RescheduleBy<R>(milliseconds: number): TaskProcessResult<R>;
44
+ static RescheduleBy<R>(milliseconds: number, options?: {
45
+ refundRateLimit?: boolean;
46
+ }): TaskProcessResult<R>;
41
47
  }
42
48
  /**
43
49
  * Represents the status of a task in the queue.
@@ -521,27 +527,30 @@ export declare abstract class TaskQueue<Definitions extends TaskDefinitionMap =
521
527
  * Reschedules a task to run at a specific time.
522
528
  * @param id The ID of the task.
523
529
  * @param timestamp The timestamp when the task should run.
524
- * @param options Optional transaction.
530
+ * @param options Optional transaction and refund flags.
525
531
  */
526
532
  abstract reschedule(id: string, timestamp: number, options?: {
533
+ refundRateLimit?: boolean;
527
534
  transaction?: Transaction;
528
535
  }): Promise<void>;
529
536
  /**
530
537
  * Reschedules multiple tasks to run at a specific time.
531
538
  * @param ids The IDs of the tasks.
532
539
  * @param timestamp The timestamp when the tasks should run.
533
- * @param options Optional transaction.
540
+ * @param options Optional transaction and refund flags.
534
541
  */
535
542
  abstract rescheduleMany(ids: string[], timestamp: number, options?: {
543
+ refundRateLimit?: boolean;
536
544
  transaction?: Transaction;
537
545
  }): Promise<void>;
538
546
  /**
539
547
  * Reschedules tasks with the given tags to run at a specific time.
540
548
  * @param tags One or more tags.
541
549
  * @param timestamp The timestamp when the tasks should run.
542
- * @param options Optional transaction.
550
+ * @param options Optional transaction and refund flags.
543
551
  */
544
552
  abstract rescheduleManyByTags(tags: OneOrMany<string>, timestamp: number, options?: {
553
+ refundRateLimit?: boolean;
545
554
  transaction?: Transaction;
546
555
  }): Promise<void>;
547
556
  /**
@@ -87,17 +87,19 @@ export class TaskProcessResult {
87
87
  /**
88
88
  * Creates a result that reschedules the task to a specific timestamp.
89
89
  * @param timestamp The timestamp to reschedule to.
90
+ * @param options Optional refund flags.
90
91
  */
91
- static RescheduleTo(timestamp) {
92
- return new TaskProcessResult({ action: 'reschedule', timestamp });
92
+ static RescheduleTo(timestamp, options) {
93
+ return new TaskProcessResult({ action: 'reschedule', timestamp, ...options });
93
94
  }
94
95
  /**
95
96
  * Creates a result that reschedules the task by a specific number of milliseconds.
96
97
  * @param milliseconds The number of milliseconds to reschedule by.
98
+ * @param options Optional refund flags.
97
99
  */
98
- static RescheduleBy(milliseconds) {
100
+ static RescheduleBy(milliseconds, options) {
99
101
  const timestamp = currentTimestamp() + milliseconds;
100
- return this.RescheduleTo(timestamp);
102
+ return this.RescheduleTo(timestamp, options);
101
103
  }
102
104
  }
103
105
  /**
@@ -275,7 +277,7 @@ export class TaskQueue extends Transactional {
275
277
  break;
276
278
  case 'reschedule':
277
279
  context.logger.verbose('Rescheduling task');
278
- await this.reschedule(task.id, result.payload.timestamp);
280
+ await this.reschedule(task.id, result.payload.timestamp, { refundRateLimit: result.payload.refundRateLimit });
279
281
  break;
280
282
  default:
281
283
  throw new Error('Unsupported task result action.');
@@ -31,6 +31,7 @@ export type TaskProcessResultPayload<Result> = {
31
31
  } | {
32
32
  action: 'reschedule';
33
33
  timestamp: number;
34
+ refundRateLimit?: boolean;
34
35
  };
35
36
  export interface ProcessWorker<Definitions extends TaskDefinitionMap, Type extends TaskTypes<Definitions>> {
36
37
  /**
package/test2.js CHANGED
@@ -1,16 +1,34 @@
1
- import { inject, Singleton } from './injector/index.js';
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
2
10
  import { Application } from './application/application.js';
3
11
  import { provideModule } from './application/providers.js';
12
+ import { defineEnum } from './enumeration/enumeration.js';
4
13
  import { PrettyPrintLogFormatter, provideConsoleLogTransport } from './logger/index.js';
5
- import { object, string } from './schema/index.js';
6
- const schema = object({
7
- value: string({ lowercase: true })
14
+ import { Enumeration } from './schema/index.js';
15
+ import { getDesignType } from './utils/reflection.js';
16
+ const Status = defineEnum('Status', {
17
+ Active: 'active',
18
+ Inactive: 'inactive',
19
+ Suspended: 'suspended',
8
20
  });
21
+ class TestClass {
22
+ status;
23
+ }
24
+ __decorate([
25
+ Enumeration(Status),
26
+ __metadata("design:type", String)
27
+ ], TestClass.prototype, "status", void 0);
9
28
  function main() {
10
- const value = schema.parse({ value: 'HELLO WORLD' });
11
- console.log(value);
29
+ console.log(getDesignType(TestClass.prototype, 'status'));
12
30
  }
13
31
  Application.run('Test', [
14
32
  provideModule(main),
15
- provideConsoleLogTransport(PrettyPrintLogFormatter)
33
+ provideConsoleLogTransport(PrettyPrintLogFormatter),
16
34
  ]);