-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add timeout parameter & fix code
- Loading branch information
Showing
11 changed files
with
399 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
export var DeliveryErrorCode; | ||
(function (DeliveryErrorCode) { | ||
DeliveryErrorCode["Timeout"] = "TIMEOUT"; | ||
DeliveryErrorCode["PromiseNotFound"] = "PROMISE_NOT_FOUND"; | ||
DeliveryErrorCode["PromiseAlreadyRegistered"] = "PROMISE_ALREADY_REGISTERED"; | ||
})(DeliveryErrorCode || (DeliveryErrorCode = {})); | ||
export class DeliveryError extends Error { | ||
code; | ||
constructor(code, message) { | ||
super(message); | ||
this.code = code; | ||
this.name = 'DeliveryError'; | ||
} | ||
/** | ||
* A static method to check if a given error is a `DeliveryError` and if its `code` property is valid. | ||
* | ||
* @param error - The error to be checked. | ||
* @returns `true` if the error is a `DeliveryError` and its `code` property is valid; otherwise, `false`. | ||
* | ||
* @example | ||
* ```typescript | ||
* const error = new DeliveryError(DeliveryErrorCode.Timeout, 'Request timed out'); | ||
* if (DeliveryError.is(error)) { | ||
* console.log(`Error code: ${error.code}`); | ||
* } | ||
* ``` | ||
*/ | ||
static is(error) { | ||
return error instanceof DeliveryError; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,80 +1,90 @@ | ||
import { DeliveryError, DeliveryErrorCode } from './errors.js'; | ||
export const isDeliveryError = (error) => { | ||
return DeliveryError.is(error); | ||
}; | ||
export { DeliveryError, DeliveryErrorCode }; | ||
class Delivery { | ||
promises = {}; | ||
timeout; | ||
constructor(options) { | ||
if (options && options.timeout) { | ||
this.timeout = options.timeout; | ||
} | ||
} | ||
/** | ||
* Registers a new promise with the given key. | ||
* | ||
* This method creates a new promise and stores it along with its resolve and reject functions. | ||
* If a promise with the given key already exists, an error is thrown. | ||
* | ||
* @param key - The unique identifier for the promise to be registered. | ||
* @param options - Optional configuration for this specific promise. | ||
* @param options.timeout - Override default timeout for this promise. | ||
* @throws Will throw an error if a promise with the given key is already registered. | ||
* @returns A Promise<T> that can be used to handle the asynchronous operation. | ||
*/ | ||
register(key) { | ||
register(key, options) { | ||
if (this.promises[key]) { | ||
throw new Error(`Promise with Key: ${key} is already registered`); | ||
throw new DeliveryError(DeliveryErrorCode.PromiseAlreadyRegistered, `Promise with Key: ${key} is already registered`); | ||
} | ||
let timeoutId; | ||
let resolvePromise; | ||
let rejectPromise; | ||
const promise = new Promise((resolve, reject) => { | ||
resolvePromise = resolve; | ||
rejectPromise = reject; | ||
const timeoutValue = options?.timeout ?? this.timeout; | ||
if (timeoutValue) { | ||
timeoutId = setTimeout(() => { | ||
reject(new DeliveryError(DeliveryErrorCode.Timeout, `Promise with Key: ${key} timed out after ${timeoutValue}ms`)); | ||
delete this.promises[key]; | ||
}, timeoutValue); | ||
} | ||
}); | ||
const state = { | ||
promise: null, | ||
resolve: null, | ||
reject: null, | ||
promise, | ||
resolve: resolvePromise, | ||
reject: rejectPromise, | ||
}; | ||
state.promise = new Promise((resolve, reject) => { | ||
state.resolve = resolve; | ||
state.reject = reject; | ||
}); | ||
promise.finally(() => clearTimeout(timeoutId)); | ||
this.promises[key] = state; | ||
return this.promises[key].promise; | ||
return promise; | ||
} | ||
/** | ||
* Resolves the promise associated with the given key with the provided value. | ||
* Resolves the promise associated with the given key. | ||
* | ||
* @param key - The unique identifier for the promise to be resolved. | ||
* @param value - The value to fulfill the promise with. | ||
* | ||
* @param value - The value to resolve the promise with. | ||
* @throws Will throw an error if a promise with the given key is not found. | ||
* | ||
* @returns {void} | ||
*/ | ||
resolve(key, value) { | ||
if (!this.promises[key]) { | ||
throw new Error(`Promise with Key: ${key} is not found`); | ||
throw new DeliveryError(DeliveryErrorCode.PromiseNotFound, `Promise with Key: ${key} is not found`); | ||
} | ||
this.promises[key].resolve(value); | ||
delete this.promises[key]; | ||
} | ||
/** | ||
* Rejects the promise associated with the given key with the provided reason. | ||
* | ||
* This method finds the promise with the specified key, rejects it with the given reason, | ||
* and then removes it from the internal promises storage. | ||
* | ||
* @param key - The unique identifier for the promise to be rejected. | ||
* @param reason - The reason for rejecting the promise. | ||
* @throws Will throw an error if a promise with the given key is not found. | ||
* @returns {void} | ||
*/ | ||
reject(key, reason) { | ||
if (!this.promises[key]) { | ||
throw new Error(`Promise with Key: ${key} is not found`); | ||
throw new DeliveryError(DeliveryErrorCode.PromiseNotFound, `Promise with Key: ${key} is not found`); | ||
} | ||
this.promises[key].reject(reason); | ||
delete this.promises[key]; | ||
} | ||
/** | ||
* Returns the promise associated with the given key. | ||
* | ||
* This method finds the promise with the specified key and returns it. | ||
* Retrieves the promise associated with the given key. | ||
* | ||
* @param key - The unique identifier for the promise to be retrieved. | ||
* @throws Will throw an error if a promise with the given key is not found. | ||
* @returns {Promise<T>} The promise associated with the given key. | ||
* @param key - The unique identifier of the promise to be retrieved. | ||
* @returns The promise associated with the given key if it exists, otherwise undefined. | ||
*/ | ||
getPromise(key) { | ||
if (!this.promises[key]) { | ||
throw new Error(`Promise with Key: ${key} is not found`); | ||
} | ||
return this.promises[key].promise; | ||
return this.promises[key]?.promise; | ||
} | ||
} | ||
export default Delivery; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export enum DeliveryErrorCode { | ||
Timeout = 'TIMEOUT', | ||
PromiseNotFound = 'PROMISE_NOT_FOUND', | ||
PromiseAlreadyRegistered = 'PROMISE_ALREADY_REGISTERED', | ||
} | ||
|
||
export class DeliveryError extends Error { | ||
constructor( | ||
public code: DeliveryErrorCode, | ||
message: string, | ||
) { | ||
super(message); | ||
this.name = 'DeliveryError'; | ||
} | ||
|
||
/** | ||
* A static method to check if a given error is a `DeliveryError` and if its `code` property is valid. | ||
* | ||
* @param error - The error to be checked. | ||
* @returns `true` if the error is a `DeliveryError` and its `code` property is valid; otherwise, `false`. | ||
* | ||
* @example | ||
* ```typescript | ||
* const error = new DeliveryError(DeliveryErrorCode.Timeout, 'Request timed out'); | ||
* if (DeliveryError.is(error)) { | ||
* console.log(`Error code: ${error.code}`); | ||
* } | ||
* ``` | ||
*/ | ||
static is(error: unknown): error is DeliveryError { | ||
return error instanceof DeliveryError; | ||
} | ||
} |
Oops, something went wrong.