@hardlydifficult/queue 1.1.1 → 1.1.2
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/README.md +123 -108
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hardlydifficult/queue
|
|
2
2
|
|
|
3
|
-
A high-performance priority queue with O(1) enqueue and dequeue operations, supporting FIFO ordering within priority levels.
|
|
3
|
+
A high-performance priority queue implementation with O(1) enqueue and dequeue operations, supporting FIFO ordering within priority levels.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -15,180 +15,195 @@ import { createPriorityQueue } from "@hardlydifficult/queue";
|
|
|
15
15
|
|
|
16
16
|
const queue = createPriorityQueue<string>();
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
queue.enqueue("urgent
|
|
20
|
-
queue.enqueue("
|
|
21
|
-
queue.enqueue("background task", "low");
|
|
18
|
+
queue.enqueue("low-priority", "low");
|
|
19
|
+
queue.enqueue("urgent", "high");
|
|
20
|
+
queue.enqueue("standard"); // defaults to 'medium'
|
|
22
21
|
|
|
23
|
-
//
|
|
24
|
-
console.log(queue.dequeue()?.data); // "urgent
|
|
25
|
-
console.log(queue.dequeue()?.data); // "
|
|
26
|
-
console.log(queue.dequeue()?.data); // "
|
|
22
|
+
// Dequeues in priority order, then by insertion time
|
|
23
|
+
console.log(queue.dequeue()?.data); // "urgent"
|
|
24
|
+
console.log(queue.dequeue()?.data); // "standard"
|
|
25
|
+
console.log(queue.dequeue()?.data); // "low-priority"
|
|
27
26
|
```
|
|
28
27
|
|
|
29
|
-
## Core
|
|
28
|
+
## Core API
|
|
30
29
|
|
|
31
|
-
###
|
|
30
|
+
### createPriorityQueue
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
Creates a new priority queue instance.
|
|
34
33
|
|
|
35
34
|
```typescript
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Enqueue with explicit priority
|
|
39
|
-
const item1 = queue.enqueue("task A", "high");
|
|
40
|
-
const item2 = queue.enqueue("task B", "high");
|
|
41
|
-
const item3 = queue.enqueue("task C", "medium");
|
|
35
|
+
import { createPriorityQueue } from "@hardlydifficult/queue";
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
queue.dequeue()?.data; // "task A" (high, enqueued first)
|
|
45
|
-
queue.dequeue()?.data; // "task B" (high, enqueued second)
|
|
46
|
-
queue.dequeue()?.data; // "task C" (medium)
|
|
37
|
+
const queue = createPriorityQueue<number>();
|
|
47
38
|
```
|
|
48
39
|
|
|
49
|
-
###
|
|
40
|
+
### PriorityQueue Interface
|
|
50
41
|
|
|
51
|
-
|
|
42
|
+
All queue operations are provided via the `PriorityQueue<T>` interface returned by `createPriorityQueue()`.
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
const queue = createPriorityQueue<string>();
|
|
55
|
-
queue.enqueue("first", "high");
|
|
56
|
-
queue.enqueue("second", "low");
|
|
44
|
+
#### enqueue(data, priority?)
|
|
57
45
|
|
|
58
|
-
|
|
59
|
-
queue.size; // Still 2
|
|
60
|
-
```
|
|
46
|
+
Adds an item to the queue.
|
|
61
47
|
|
|
62
|
-
|
|
48
|
+
| Parameter | Type | Default | Description |
|
|
49
|
+
|-----------|-----------|-----------|------------------------------|
|
|
50
|
+
| data | `T` | — | The item data to enqueue |
|
|
51
|
+
| priority | `Priority`| `"medium"`| Priority level: `"high"`, `"medium"`, or `"low"` |
|
|
63
52
|
|
|
64
|
-
|
|
53
|
+
Returns a `QueueItem<T>` with metadata including unique ID and enqueue timestamp.
|
|
65
54
|
|
|
66
55
|
```typescript
|
|
67
|
-
const
|
|
56
|
+
const item = queue.enqueue("task", "high");
|
|
57
|
+
console.log(item.id); // "q_1"
|
|
58
|
+
console.log(item.priority); // "high"
|
|
59
|
+
```
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
queue.size; // 0
|
|
61
|
+
#### dequeue()
|
|
71
62
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
Removes and returns the highest-priority item (FIFO within same priority).
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const item = queue.dequeue();
|
|
67
|
+
if (item) {
|
|
68
|
+
console.log(item.data); // "urgent"
|
|
69
|
+
}
|
|
75
70
|
```
|
|
76
71
|
|
|
77
|
-
|
|
72
|
+
Returns `undefined` if the queue is empty.
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
#### peek()
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
Returns the next item to be dequeued without removing it.
|
|
82
77
|
|
|
83
78
|
```typescript
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
queue.size; // 0
|
|
79
|
+
const next = queue.peek();
|
|
80
|
+
if (next) {
|
|
81
|
+
console.log(next.data); // First item to be dequeued
|
|
82
|
+
}
|
|
89
83
|
```
|
|
90
84
|
|
|
91
|
-
|
|
85
|
+
#### remove(id)
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
Removes an item by its unique ID.
|
|
94
88
|
|
|
95
89
|
```typescript
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
queue.updatePriority(item.id, "high"); // true
|
|
100
|
-
queue.peek()?.data; // "task" (now highest priority)
|
|
90
|
+
const item = queue.enqueue("remove-me");
|
|
91
|
+
const removed = queue.remove(item.id); // true
|
|
92
|
+
const absent = queue.remove("unknown"); // false
|
|
101
93
|
```
|
|
102
94
|
|
|
103
|
-
|
|
95
|
+
#### size
|
|
104
96
|
|
|
105
|
-
|
|
97
|
+
Readonly property returning the total number of items in the queue.
|
|
106
98
|
|
|
107
99
|
```typescript
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
console.log(queue.size); // 5
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### isEmpty
|
|
112
104
|
|
|
113
|
-
|
|
114
|
-
queue.moveBefore(a.id, c.id); // true
|
|
115
|
-
queue.toArray().map(i => i.data); // ["B", "A", "C"]
|
|
105
|
+
Readonly property indicating whether the queue is empty.
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
queue.toArray().map(i => i.data); // ["A", "C", "B"]
|
|
107
|
+
```typescript
|
|
108
|
+
console.log(queue.isEmpty); // false
|
|
120
109
|
```
|
|
121
110
|
|
|
122
|
-
|
|
111
|
+
#### onEnqueue(callback)
|
|
123
112
|
|
|
124
|
-
|
|
113
|
+
Registers a callback invoked whenever an item is enqueued.
|
|
125
114
|
|
|
126
|
-
|
|
115
|
+
Returns an unsubscribe function.
|
|
127
116
|
|
|
128
117
|
```typescript
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
118
|
+
const unsubscribe = queue.onEnqueue((item) => {
|
|
119
|
+
console.log("Enqueued:", item.data);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
queue.enqueue("test");
|
|
123
|
+
unsubscribe();
|
|
124
|
+
queue.enqueue("ignored"); // callback no longer invoked
|
|
125
|
+
```
|
|
133
126
|
|
|
127
|
+
#### toArray()
|
|
128
|
+
|
|
129
|
+
Returns a snapshot of all items in dequeue order (by priority, then FIFO). Does not modify the queue.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
134
132
|
const items = queue.toArray();
|
|
135
|
-
|
|
136
|
-
queue.size; // Still 3
|
|
133
|
+
// Items sorted by priority: high → medium → low, then by insertion order
|
|
137
134
|
```
|
|
138
135
|
|
|
139
|
-
|
|
136
|
+
#### clear()
|
|
140
137
|
|
|
141
|
-
|
|
138
|
+
Removes all items from the queue.
|
|
142
139
|
|
|
143
140
|
```typescript
|
|
144
|
-
|
|
141
|
+
queue.enqueue("a");
|
|
142
|
+
queue.enqueue("b");
|
|
143
|
+
queue.clear();
|
|
144
|
+
console.log(queue.size); // 0
|
|
145
|
+
```
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
console.log(`Enqueued: ${item.data} (priority: ${item.priority})`);
|
|
148
|
-
});
|
|
147
|
+
### Priority Updates
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
// Logs: "Enqueued: task (priority: high)"
|
|
149
|
+
#### updatePriority(id, newPriority)
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
Changes the priority of an existing item.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const item = queue.enqueue("task", "low");
|
|
155
|
+
queue.updatePriority(item.id, "high"); // true
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
Returns `true` if the item was found and updated, `false` otherwise.
|
|
159
|
+
|
|
160
|
+
#### moveBefore(itemId, beforeItemId)
|
|
158
161
|
|
|
159
|
-
|
|
162
|
+
Moves an item before another item within the same priority bucket.
|
|
160
163
|
|
|
161
164
|
```typescript
|
|
162
|
-
const
|
|
163
|
-
queue.enqueue("
|
|
164
|
-
queue.enqueue("
|
|
165
|
+
const a = queue.enqueue("a", "medium");
|
|
166
|
+
const b = queue.enqueue("b", "medium");
|
|
167
|
+
const c = queue.enqueue("c", "medium");
|
|
165
168
|
|
|
166
|
-
queue.
|
|
167
|
-
queue.
|
|
169
|
+
queue.moveBefore(c.id, a.id); // true
|
|
170
|
+
console.log(queue.toArray().map(i => i.data)); // ["c", "a", "b"]
|
|
168
171
|
```
|
|
169
172
|
|
|
170
|
-
|
|
173
|
+
Both items must exist and share the same priority. Returns `true` on success.
|
|
174
|
+
|
|
175
|
+
#### moveToEnd(itemId)
|
|
171
176
|
|
|
172
|
-
|
|
177
|
+
Moves an item to the end of its priority bucket.
|
|
173
178
|
|
|
174
179
|
```typescript
|
|
175
|
-
const
|
|
176
|
-
const
|
|
180
|
+
const a = queue.enqueue("a", "medium");
|
|
181
|
+
const b = queue.enqueue("b", "medium");
|
|
182
|
+
queue.moveToEnd(a.id); // true
|
|
183
|
+
console.log(queue.toArray().map(i => i.data)); // ["b", "a"]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Returns `true` if the item was found (even if already at end), `false` otherwise.
|
|
177
187
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
item
|
|
181
|
-
|
|
188
|
+
## QueueItem Type
|
|
189
|
+
|
|
190
|
+
Represents an item in the queue with metadata:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface QueueItem<T> {
|
|
194
|
+
data: T;
|
|
195
|
+
priority: Priority;
|
|
196
|
+
enqueuedAt: number; // epoch milliseconds
|
|
197
|
+
id: string; // unique identifier
|
|
198
|
+
}
|
|
182
199
|
```
|
|
183
200
|
|
|
184
|
-
## Priority
|
|
201
|
+
## Priority Order
|
|
185
202
|
|
|
186
|
-
|
|
203
|
+
Priority levels are ordered from highest to lowest:
|
|
187
204
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
| `"medium"` | 2nd |
|
|
192
|
-
| `"low"` | 3rd |
|
|
205
|
+
1. `"high"`
|
|
206
|
+
2. `"medium"` (default)
|
|
207
|
+
3. `"low"`
|
|
193
208
|
|
|
194
|
-
|
|
209
|
+
Items with higher priority are dequeued before items with lower priority. Within the same priority, items are dequeued in FIFO order (first-in, first-out).
|