🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@cityssm/unique-timed-entry-queue

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cityssm/unique-timed-entry-queue - npm Package Compare versions

Comparing version
0.2.0
to
0.3.0
+17
-0
index.d.ts

@@ -0,1 +1,3 @@

export declare const eventTypes: readonly ["enqueue"];
export type EventType = (typeof eventTypes)[number];
/**

@@ -6,2 +8,3 @@ * A queue that enqueues unique entries after a specified delay.

private readonly enqueueDelayMilliseconds;
private readonly eventListeners;
private readonly pendingEntries;

@@ -15,2 +18,9 @@ private readonly queue;

/**
* Adds an event listener for the specified event type.
* @param eventType - The event type to listen for.
* @param listener - The listener function to call when the event occurs.
* @returns A unique ID for the listener.
*/
addEventListener(eventType: EventType, listener: (entry: T) => void): string;
/**
* Clears all entries from the queue.

@@ -89,2 +99,8 @@ */

/**
* Removes an event listener.
* @param eventType - The event type.
* @param listenerId - The unique ID of the listener to remove.
*/
removeEventListener(eventType: EventType, listenerId: string): void;
/**
* Gets the size of the queue.

@@ -99,2 +115,3 @@ * @returns The number of entries in the queue.

toArray(): T[];
private triggerEvents;
}
+42
-2
import Debug from 'debug';
import exitHook from 'exit-hook';
import { DEBUG_NAMESPACE } from './debug.config.js';
import { valueToString } from './utilities.js';
import { generateUniqueListenerId, valueToString } from './utilities.js';
const debug = Debug(`${DEBUG_NAMESPACE}:index`);
export const eventTypes = ['enqueue'];
/**

@@ -11,2 +12,3 @@ * A queue that enqueues unique entries after a specified delay.

enqueueDelayMilliseconds;
eventListeners;
pendingEntries;

@@ -24,2 +26,5 @@ queue;

}
this.eventListeners = {
enqueue: {}
};
this.pendingEntries = new Map();

@@ -33,2 +38,14 @@ this.queue = [];

/**
* Adds an event listener for the specified event type.
* @param eventType - The event type to listen for.
* @param listener - The listener function to call when the event occurs.
* @returns A unique ID for the listener.
*/
addEventListener(eventType, listener) {
const listenerId = generateUniqueListenerId();
// eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventType][listenerId] = listener;
return listenerId;
}
/**
* Clears all entries from the queue.

@@ -90,2 +107,3 @@ */

this.queue.push(entry);
this.triggerEvents('enqueue', entry);
debug(`Enqueued entry immediately (zero delay): ${valueToString(entry)}`);

@@ -96,5 +114,6 @@ return;

const timeout = setTimeout(() => {
this.pendingEntries.delete(stringEntry);
this.queue.push(entry);
this.triggerEvents('enqueue', entry);
debug(`Enqueued entry: ${stringEntry}`);
this.pendingEntries.delete(stringEntry);
}, delay);

@@ -130,2 +149,3 @@ this.pendingEntries.set(stringEntry, { timeout, value: entry });

this.queue.push(pendingEntry.value);
this.triggerEvents('enqueue', pendingEntry.value);
debug(`Enqueued pending entry immediately: ${stringValue}`);

@@ -176,2 +196,16 @@ }

/**
* Removes an event listener.
* @param eventType - The event type.
* @param listenerId - The unique ID of the listener to remove.
*/
removeEventListener(eventType, listenerId) {
// eslint-disable-next-line security/detect-object-injection
const listeners = this.eventListeners[eventType];
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (listeners !== undefined && Object.hasOwn(listeners, listenerId)) {
// eslint-disable-next-line security/detect-object-injection, @typescript-eslint/no-dynamic-delete
delete listeners[listenerId];
}
}
/**
* Gets the size of the queue.

@@ -190,2 +224,8 @@ * @returns The number of entries in the queue.

}
triggerEvents(eventType, entry) {
// eslint-disable-next-line security/detect-object-injection
for (const listener of Object.values(this.eventListeners[eventType])) {
listener(entry);
}
}
}

@@ -5,6 +5,10 @@ import Debug from 'debug'

import { DEBUG_NAMESPACE } from './debug.config.js'
import { valueToString } from './utilities.js'
import { generateUniqueListenerId, valueToString } from './utilities.js'
const debug = Debug(`${DEBUG_NAMESPACE}:index`)
export const eventTypes = ['enqueue'] as const
export type EventType = (typeof eventTypes)[number]
/**

@@ -15,2 +19,8 @@ * A queue that enqueues unique entries after a specified delay.

private readonly enqueueDelayMilliseconds: number
private readonly eventListeners: Record<
EventType,
Record<string, (entry: T) => void>
>
private readonly pendingEntries: Map<

@@ -23,2 +33,3 @@ string,

>
private readonly queue: T[]

@@ -40,2 +51,6 @@

this.eventListeners = {
enqueue: {}
}
this.pendingEntries = new Map()

@@ -52,2 +67,17 @@

/**
* Adds an event listener for the specified event type.
* @param eventType - The event type to listen for.
* @param listener - The listener function to call when the event occurs.
* @returns A unique ID for the listener.
*/
public addEventListener(eventType: EventType, listener: (entry: T) => void): string {
const listenerId = generateUniqueListenerId()
// eslint-disable-next-line security/detect-object-injection
this.eventListeners[eventType][listenerId] = listener
return listenerId
}
/**
* Clears all entries from the queue.

@@ -119,2 +149,4 @@ */

this.queue.push(entry)
this.triggerEvents('enqueue', entry)
debug(`Enqueued entry immediately (zero delay): ${valueToString(entry)}`)

@@ -127,5 +159,8 @@ return

const timeout = setTimeout(() => {
this.pendingEntries.delete(stringEntry)
this.queue.push(entry)
this.triggerEvents('enqueue', entry)
debug(`Enqueued entry: ${stringEntry}`)
this.pendingEntries.delete(stringEntry)
}, delay)

@@ -170,2 +205,3 @@

this.queue.push(pendingEntry.value)
this.triggerEvents('enqueue', pendingEntry.value)

@@ -225,2 +261,18 @@ debug(`Enqueued pending entry immediately: ${stringValue}`)

/**
* Removes an event listener.
* @param eventType - The event type.
* @param listenerId - The unique ID of the listener to remove.
*/
public removeEventListener(eventType: EventType, listenerId: string): void {
// eslint-disable-next-line security/detect-object-injection
const listeners = this.eventListeners[eventType]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (listeners !== undefined && Object.hasOwn(listeners, listenerId)) {
// eslint-disable-next-line security/detect-object-injection, @typescript-eslint/no-dynamic-delete
delete listeners[listenerId]
}
}
/**
* Gets the size of the queue.

@@ -240,2 +292,9 @@ * @returns The number of entries in the queue.

}
private triggerEvents(eventType: EventType, entry: T): void {
// eslint-disable-next-line security/detect-object-injection
for (const listener of Object.values(this.eventListeners[eventType])) {
listener(entry)
}
}
}
+2
-2
{
"name": "@cityssm/unique-timed-entry-queue",
"version": "0.2.0",
"version": "0.3.0",
"description": "A queue with delayed enqueue of unique entries, perfect for queuing update notifications.",

@@ -34,3 +34,3 @@ "keywords": [

"@types/debug": "^4.1.12",
"@types/node": "^25.0.8",
"@types/node": "^25.0.9",
"eslint-config-cityssm": "^36.1.0",

@@ -37,0 +37,0 @@ "prettier-config-cityssm": "^1.0.0"

@@ -90,2 +90,13 @@ # Unique, Timed-Entry Queue for Node

### Event Listeners
Right now, only one event is available.
`addEventListener('enqueue', (entry) => {})`<br />
Adds an event listener that is called when the entry moves to the queue from pending.
Returns an event listener id that can be used to remove the event listener.
`removeEventListener('enqueue', eventListenerId)`<br />
Removes an event listener.
### Export Functions

@@ -92,0 +103,0 @@

@@ -7,1 +7,6 @@ /**

export declare function valueToString(value: unknown): string;
/**
* Generates a unique listener ID.
* @returns A unique string identifier.
*/
export declare function generateUniqueListenerId(): string;

@@ -0,1 +1,3 @@

// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable sonarjs/pseudo-random */
/**

@@ -22,1 +24,10 @@ * Converts a value to its string representation.

}
/**
* Generates a unique listener ID.
* @returns A unique string identifier.
*/
export function generateUniqueListenerId() {
return (Date.now().toString(36) +
Math.random().toString(36).slice(2, 15) +
Math.random().toString(36).slice(2, 15));
}

@@ -0,1 +1,4 @@

// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable sonarjs/pseudo-random */
/**

@@ -21,1 +24,13 @@ * Converts a value to its string representation.

}
/**
* Generates a unique listener ID.
* @returns A unique string identifier.
*/
export function generateUniqueListenerId(): string {
return (
Date.now().toString(36) +
Math.random().toString(36).slice(2, 15) +
Math.random().toString(36).slice(2, 15)
)
}