@hardlydifficult/queue 1.0.0
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.
- package/dist/PriorityQueue.d.ts +78 -0
- package/dist/PriorityQueue.d.ts.map +1 -0
- package/dist/PriorityQueue.js +91 -0
- package/dist/PriorityQueue.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prioritized FIFO queue.
|
|
3
|
+
*
|
|
4
|
+
* Items with higher priority are dequeued first.
|
|
5
|
+
* Within the same priority level, items are dequeued in insertion order (FIFO).
|
|
6
|
+
*
|
|
7
|
+
* Uses a multi-bucket approach: one array per priority level.
|
|
8
|
+
* O(1) enqueue, O(1) dequeue.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Priority levels for the queue.
|
|
12
|
+
* Dequeue order: high first, then medium, then low.
|
|
13
|
+
*/
|
|
14
|
+
export type Priority = "high" | "medium" | "low";
|
|
15
|
+
/**
|
|
16
|
+
* An item in the queue with metadata.
|
|
17
|
+
*/
|
|
18
|
+
export interface QueueItem<T> {
|
|
19
|
+
/** The queued data */
|
|
20
|
+
readonly data: T;
|
|
21
|
+
/** Priority level */
|
|
22
|
+
readonly priority: Priority;
|
|
23
|
+
/** When the item was enqueued (epoch ms) */
|
|
24
|
+
readonly enqueuedAt: number;
|
|
25
|
+
/** Unique identifier for this queue entry */
|
|
26
|
+
readonly id: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A prioritized FIFO queue.
|
|
30
|
+
*
|
|
31
|
+
* Items with higher priority are dequeued first.
|
|
32
|
+
* Within the same priority, items are dequeued in insertion order (FIFO).
|
|
33
|
+
*/
|
|
34
|
+
export interface PriorityQueue<T> {
|
|
35
|
+
/**
|
|
36
|
+
* Add an item to the queue.
|
|
37
|
+
* @param data - The item data
|
|
38
|
+
* @param priority - Priority level (default: 'medium')
|
|
39
|
+
* @returns The queued item with metadata
|
|
40
|
+
*/
|
|
41
|
+
enqueue(data: T, priority?: Priority): QueueItem<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Remove and return the highest-priority item (FIFO within same priority).
|
|
44
|
+
* Returns undefined if the queue is empty.
|
|
45
|
+
*/
|
|
46
|
+
dequeue(): QueueItem<T> | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Peek at the next item without removing it.
|
|
49
|
+
* Returns undefined if the queue is empty.
|
|
50
|
+
*/
|
|
51
|
+
peek(): QueueItem<T> | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Remove a specific item by its ID.
|
|
54
|
+
* @returns true if the item was found and removed
|
|
55
|
+
*/
|
|
56
|
+
remove(id: string): boolean;
|
|
57
|
+
/** Number of items currently in the queue. */
|
|
58
|
+
readonly size: number;
|
|
59
|
+
/** Whether the queue is empty. */
|
|
60
|
+
readonly isEmpty: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Register a callback invoked whenever an item is enqueued.
|
|
63
|
+
* @returns An unsubscribe function.
|
|
64
|
+
*/
|
|
65
|
+
onEnqueue(callback: (item: QueueItem<T>) => void): () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Get all items in the queue ordered by dequeue priority.
|
|
68
|
+
* Returns a snapshot; does not modify the queue.
|
|
69
|
+
*/
|
|
70
|
+
toArray(): readonly QueueItem<T>[];
|
|
71
|
+
/** Clear all items from the queue. */
|
|
72
|
+
clear(): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a new priority queue.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createPriorityQueue<T>(): PriorityQueue<T>;
|
|
78
|
+
//# sourceMappingURL=PriorityQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriorityQueue.d.ts","sourceRoot":"","sources":["../src/PriorityQueue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAKjD;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,qBAAqB;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAEpD;;;OAGG;IACH,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAEpC;;;OAGG;IACH,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAEjC;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAE5B,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAE9D;;;OAGG;IACH,OAAO,IAAI,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnC,sCAAsC;IACtC,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,CAkFzD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Prioritized FIFO queue.
|
|
4
|
+
*
|
|
5
|
+
* Items with higher priority are dequeued first.
|
|
6
|
+
* Within the same priority level, items are dequeued in insertion order (FIFO).
|
|
7
|
+
*
|
|
8
|
+
* Uses a multi-bucket approach: one array per priority level.
|
|
9
|
+
* O(1) enqueue, O(1) dequeue.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createPriorityQueue = createPriorityQueue;
|
|
13
|
+
/** All priority levels in dequeue order (highest first). */
|
|
14
|
+
const PRIORITY_ORDER = ["high", "medium", "low"];
|
|
15
|
+
/**
|
|
16
|
+
* Create a new priority queue.
|
|
17
|
+
*/
|
|
18
|
+
function createPriorityQueue() {
|
|
19
|
+
const buckets = {
|
|
20
|
+
high: [],
|
|
21
|
+
medium: [],
|
|
22
|
+
low: [],
|
|
23
|
+
};
|
|
24
|
+
const listeners = new Set();
|
|
25
|
+
let counter = 0;
|
|
26
|
+
function getSize() {
|
|
27
|
+
return buckets.high.length + buckets.medium.length + buckets.low.length;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
enqueue(data, priority = "medium") {
|
|
31
|
+
const item = {
|
|
32
|
+
data,
|
|
33
|
+
priority,
|
|
34
|
+
enqueuedAt: Date.now(),
|
|
35
|
+
id: `q_${String(++counter)}`,
|
|
36
|
+
};
|
|
37
|
+
buckets[priority].push(item);
|
|
38
|
+
for (const cb of listeners) {
|
|
39
|
+
cb(item);
|
|
40
|
+
}
|
|
41
|
+
return item;
|
|
42
|
+
},
|
|
43
|
+
dequeue() {
|
|
44
|
+
for (const p of PRIORITY_ORDER) {
|
|
45
|
+
if (buckets[p].length > 0) {
|
|
46
|
+
return buckets[p].shift();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
peek() {
|
|
52
|
+
for (const p of PRIORITY_ORDER) {
|
|
53
|
+
if (buckets[p].length > 0) {
|
|
54
|
+
return buckets[p][0];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
},
|
|
59
|
+
remove(id) {
|
|
60
|
+
for (const p of PRIORITY_ORDER) {
|
|
61
|
+
const idx = buckets[p].findIndex((item) => item.id === id);
|
|
62
|
+
if (idx !== -1) {
|
|
63
|
+
buckets[p].splice(idx, 1);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
},
|
|
69
|
+
get size() {
|
|
70
|
+
return getSize();
|
|
71
|
+
},
|
|
72
|
+
get isEmpty() {
|
|
73
|
+
return getSize() === 0;
|
|
74
|
+
},
|
|
75
|
+
onEnqueue(callback) {
|
|
76
|
+
listeners.add(callback);
|
|
77
|
+
return () => {
|
|
78
|
+
listeners.delete(callback);
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
toArray() {
|
|
82
|
+
return [...buckets.high, ...buckets.medium, ...buckets.low];
|
|
83
|
+
},
|
|
84
|
+
clear() {
|
|
85
|
+
buckets.high.length = 0;
|
|
86
|
+
buckets.medium.length = 0;
|
|
87
|
+
buckets.low.length = 0;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=PriorityQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriorityQueue.js","sourceRoot":"","sources":["../src/PriorityQueue.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,QAAQ,GACd,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPriorityQueue = void 0;
|
|
4
|
+
var PriorityQueue_1 = require("./PriorityQueue");
|
|
5
|
+
Object.defineProperty(exports, "createPriorityQueue", { enumerable: true, get: function () { return PriorityQueue_1.createPriorityQueue; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAKyB;AAJvB,oHAAA,mBAAmB,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hardlydifficult/queue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
13
|
+
"test:coverage": "vitest run --coverage",
|
|
14
|
+
"lint": "tsc --noEmit",
|
|
15
|
+
"clean": "rm -rf dist"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "20.19.31",
|
|
19
|
+
"typescript": "5.8.3",
|
|
20
|
+
"vitest": "1.6.1"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|