From 27d47e59224cafab1d98fcd49b1a8f2359becb6a Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Tue, 2 May 2023 09:42:16 +1000 Subject: [PATCH 1/3] add typing to queues. --- src/api/queues/v0/queues.ts | 59 +++++++++++++++++-------------------- src/resources/queue.ts | 10 +++++-- src/types.ts | 58 +++++++++++++++++++++--------------- 3 files changed, 69 insertions(+), 58 deletions(-) diff --git a/src/api/queues/v0/queues.ts b/src/api/queues/v0/queues.ts index 0c8814ec..d9d5dd3d 100644 --- a/src/api/queues/v0/queues.ts +++ b/src/api/queues/v0/queues.ts @@ -13,7 +13,7 @@ // limitations under the License. import { QueueServiceClient } from '@nitric/api/proto/queue/v1/queue_grpc_pb'; import { - NitricTask, + NitricTask as NitricTaskPb, QueueSendRequest, QueueSendBatchRequest, QueueReceiveRequest, @@ -21,7 +21,7 @@ import { } from '@nitric/api/proto/queue/v1/queue_pb'; import { SERVICE_BIND } from '../../../constants'; import * as grpc from '@grpc/grpc-js'; -import type { Task } from '../../../types'; +import { NitricTask } from '../../../types'; import { Struct } from 'google-protobuf/google/protobuf/struct_pb'; import { fromGrpcError, @@ -32,8 +32,8 @@ import { /** * A message that has failed to be enqueued */ -interface FailedMessage { - task: Task; +interface FailedMessage { + task: NitricTask; message: string; } @@ -44,8 +44,8 @@ interface FailedMessage { * @param task to convert * @returns the wire representation of the task */ -function taskToWire(task: Task) { - const wireTask = new NitricTask(); +function taskToWire(task: NitricTask) { + const wireTask = new NitricTaskPb(); wireTask.setId(task.id); wireTask.setPayloadType(task.payloadType); @@ -76,16 +76,16 @@ export class Queueing { this.QueueServiceClient = newQueueServiceClient(); } - queue = (name: string): Queue => { + queue = (name: string): Queue => { if (!name) { throw new InvalidArgumentError('A queue name is needed to use a Queue.'); } - return new Queue(this, name); + return new Queue(this, name); }; } -export class Queue { +export class Queue = Record> { queueing: Queueing; name: string; @@ -120,17 +120,17 @@ export class Queue { * }; * }); */ - public async send(tasks: Task[]): Promise; - public async send(tasks: Task): Promise; - public async send(tasks: Task | Task[]): Promise { + public async send(tasks: T[] | NitricTask[]): Promise[]>; + public async send(tasks: T | NitricTask): Promise; + public async send(tasks: T[] | T | NitricTask | NitricTask[]): Promise[]> { return new Promise((resolve, reject) => { const request = new QueueSendBatchRequest(); - request.setTasksList( - Array.isArray(tasks) - ? tasks.map((task) => taskToWire(task)) - : [taskToWire(tasks)] - ); + // Convert to NitricTask if not specified + const tasksArray = Array.isArray(tasks) ? tasks : [tasks]; + const nitricTasksArray = tasksArray.map(t => t instanceof NitricTask ? t : new NitricTask({ payload: t })) + + request.setTasksList(nitricTasksArray.map(taskToWire)); request.setQueue(this.name); this.queueing.QueueServiceClient.sendBatch(request, (error, response) => { @@ -139,11 +139,11 @@ export class Queue { return; } const failedTasks = response.getFailedtasksList().map((m) => ({ - task: { - id: m.getTask().getId(), - payload: m.getTask().getPayload().toJavaScript(), - payloadType: m.getTask().getPayloadType(), - }, + task: new NitricTask({ + id: m.getTask().getId(), + payloadType: m.getTask().getPayloadType(), + payload: m.getTask().getPayload().toJavaScript() as T + }), message: m.getMessage(), })); if (!Array.isArray(tasks)) { @@ -181,7 +181,7 @@ export class Queue { * // do something with task * ``` */ - public async receive(depth?: number): Promise { + public async receive(depth?: number): Promise[]> { return new Promise((resolve, reject) => { const request = new QueueReceiveRequest(); @@ -201,7 +201,7 @@ export class Queue { response.getTasksList().map((m) => { return new ReceivedTask({ id: m.getId(), - payload: m.getPayload().toJavaScript(), + payload: m.getPayload().toJavaScript() as T, payloadType: m.getPayloadType(), leaseId: m.getLeaseId(), queue: this, @@ -214,11 +214,8 @@ export class Queue { } } -export class ReceivedTask implements Task { - id: string; +export class ReceivedTask = Record> extends NitricTask { leaseId: string; - payloadType?: string; - payload?: Record; queue: Queue; constructor({ @@ -227,11 +224,9 @@ export class ReceivedTask implements Task { payload, payloadType, queue, - }: Task & { id: string; leaseId: string; queue: Queue }) { - this.id = id; + }: { id: string; payload: T, payloadType: string, leaseId: string; queue: Queue }) { + super({ id, payloadType, payload }); this.leaseId = leaseId; - this.payloadType = payloadType; - this.payload = payload; this.queue = queue; } diff --git a/src/resources/queue.ts b/src/resources/queue.ts index febc8d83..02e3dbfe 100644 --- a/src/resources/queue.ts +++ b/src/resources/queue.ts @@ -29,7 +29,7 @@ export type QueuePermission = 'sending' | 'receiving'; /** * Queue resource for async send/receive messaging */ -export class QueueResource extends SecureResource { +export class QueueResource = Record> extends SecureResource { /** * Register this queue as a required resource for the calling function/container. * @@ -91,11 +91,15 @@ export class QueueResource extends SecureResource { * @param perms the access that the currently scoped function is requesting to this resource. * @returns a useable queue. */ - public for(...perms: QueuePermission[]): Queue { + public for(...perms: QueuePermission[]): Queue { this.registerPolicy(...perms); return queues().queue(this.name); } } -export const queue = make(QueueResource); +export const queue = make(QueueResource) as < + T extends Record = Record +>( + name: string +) => QueueResource; diff --git a/src/types.ts b/src/types.ts index b8790b05..bc03a8a0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -45,31 +45,43 @@ export class NitricEvent = Record> { } } -export interface Task = Record> { - /** - * Uniquely identifies the task. - * - * Within your app you must ensure the ID is unique. - */ - id?: string; - /** - * The ID for the current lease of this task. - * - * A task may be leased multiple times, resulting in new lease IDs. - */ - leaseId?: string; - /** - * An optional description of the task type. - * - * Can be useful for de-serialization, routing or observability. The format of this value is determined by the producer. - */ - payloadType?: string; - /** - * The task's payload data, with details of the task or work to be done. - */ - payload?: Record; +export class NitricTask = Record> { + public readonly id: string | undefined; + public readonly payloadType: string; + public readonly payload: T; + + constructor({ id = undefined, payload, payloadType = 'none' }: {id?: string, payloadType?: string, payload: T}) { + this.id = id; + this.payload = payload; + this.payloadType = payloadType; + } } +// export interface Task = Record> { +// /** +// * Uniquely identifies the task. +// * +// * Within your app you must ensure the ID is unique. +// */ +// id?: string; +// /** +// * The ID for the current lease of this task. +// * +// * A task may be leased multiple times, resulting in new lease IDs. +// */ +// leaseId?: string; +// /** +// * An optional description of the task type. +// * +// * Can be useful for de-serialization, routing or observability. The format of this value is determined by the producer. +// */ +// payloadType?: string; +// /** +// * The task's payload data, with details of the task or work to be done. +// */ +// payload?: Record; +// } + export type WhereQueryOperator = | '<' | '<=' From 2be86a16d36124deeefb55921365ef3b07d3497d Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Tue, 2 May 2023 09:43:36 +1000 Subject: [PATCH 2/3] prettier. --- src/api/queues/v0/queues.ts | 28 ++++++++++++++++++++-------- src/resources/queue.ts | 4 +++- src/types.ts | 12 ++++++++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/api/queues/v0/queues.ts b/src/api/queues/v0/queues.ts index d9d5dd3d..3915797e 100644 --- a/src/api/queues/v0/queues.ts +++ b/src/api/queues/v0/queues.ts @@ -122,13 +122,17 @@ export class Queue = Record> { */ public async send(tasks: T[] | NitricTask[]): Promise[]>; public async send(tasks: T | NitricTask): Promise; - public async send(tasks: T[] | T | NitricTask | NitricTask[]): Promise[]> { + public async send( + tasks: T[] | T | NitricTask | NitricTask[] + ): Promise[]> { return new Promise((resolve, reject) => { const request = new QueueSendBatchRequest(); // Convert to NitricTask if not specified const tasksArray = Array.isArray(tasks) ? tasks : [tasks]; - const nitricTasksArray = tasksArray.map(t => t instanceof NitricTask ? t : new NitricTask({ payload: t })) + const nitricTasksArray = tasksArray.map((t) => + t instanceof NitricTask ? t : new NitricTask({ payload: t }) + ); request.setTasksList(nitricTasksArray.map(taskToWire)); request.setQueue(this.name); @@ -139,10 +143,10 @@ export class Queue = Record> { return; } const failedTasks = response.getFailedtasksList().map((m) => ({ - task: new NitricTask({ - id: m.getTask().getId(), - payloadType: m.getTask().getPayloadType(), - payload: m.getTask().getPayload().toJavaScript() as T + task: new NitricTask({ + id: m.getTask().getId(), + payloadType: m.getTask().getPayloadType(), + payload: m.getTask().getPayload().toJavaScript() as T, }), message: m.getMessage(), })); @@ -214,7 +218,9 @@ export class Queue = Record> { } } -export class ReceivedTask = Record> extends NitricTask { +export class ReceivedTask< + T extends Record = Record +> extends NitricTask { leaseId: string; queue: Queue; @@ -224,7 +230,13 @@ export class ReceivedTask = Record> e payload, payloadType, queue, - }: { id: string; payload: T, payloadType: string, leaseId: string; queue: Queue }) { + }: { + id: string; + payload: T; + payloadType: string; + leaseId: string; + queue: Queue; + }) { super({ id, payloadType, payload }); this.leaseId = leaseId; this.queue = queue; diff --git a/src/resources/queue.ts b/src/resources/queue.ts index 02e3dbfe..03f7bb99 100644 --- a/src/resources/queue.ts +++ b/src/resources/queue.ts @@ -29,7 +29,9 @@ export type QueuePermission = 'sending' | 'receiving'; /** * Queue resource for async send/receive messaging */ -export class QueueResource = Record> extends SecureResource { +export class QueueResource< + T extends Record = Record +> extends SecureResource { /** * Register this queue as a required resource for the calling function/container. * diff --git a/src/types.ts b/src/types.ts index bc03a8a0..3bfd1ebd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -49,8 +49,16 @@ export class NitricTask = Record> { public readonly id: string | undefined; public readonly payloadType: string; public readonly payload: T; - - constructor({ id = undefined, payload, payloadType = 'none' }: {id?: string, payloadType?: string, payload: T}) { + + constructor({ + id = undefined, + payload, + payloadType = 'none', + }: { + id?: string; + payloadType?: string; + payload: T; + }) { this.id = id; this.payload = payload; this.payloadType = payloadType; From ae7c395ff2682bb7708c1390a8ad68e12a1849b7 Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Tue, 2 May 2023 09:47:38 +1000 Subject: [PATCH 3/3] cleanup commented code. --- src/types.ts | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/types.ts b/src/types.ts index 3bfd1ebd..492e8a12 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,27 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// export interface NitricEvent< -// T extends Record = Record -// > { -// /** -// * Uniquely identifies the event. -// * -// * Within your app you must ensure the ID is unique. -// * Subscribers can assume events with the same ID are duplicates and avoid reprocessing them -// */ -// id?: string; -// /** -// * An optional description of the event type. -// * -// * Can be useful for de-serialization, routing or observability. The format of this value is determined by the producer. -// */ -// payloadType?: string; -// /** -// * The event's payload data, with details of the event. -// */ -// payload: T; -// } export class NitricEvent = Record> { public readonly payload: T; @@ -65,31 +44,6 @@ export class NitricTask = Record> { } } -// export interface Task = Record> { -// /** -// * Uniquely identifies the task. -// * -// * Within your app you must ensure the ID is unique. -// */ -// id?: string; -// /** -// * The ID for the current lease of this task. -// * -// * A task may be leased multiple times, resulting in new lease IDs. -// */ -// leaseId?: string; -// /** -// * An optional description of the task type. -// * -// * Can be useful for de-serialization, routing or observability. The format of this value is determined by the producer. -// */ -// payloadType?: string; -// /** -// * The task's payload data, with details of the task or work to be done. -// */ -// payload?: Record; -// } - export type WhereQueryOperator = | '<' | '<='