@hardlydifficult/queue 1.1.3 → 1.1.4
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 +183 -63
- 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/dequeue and FIFO ordering within priority levels.
|
|
3
|
+
A high-performance priority queue with O(1) enqueue/dequeue operations and FIFO ordering within priority levels.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -15,108 +15,228 @@ import { createPriorityQueue } from "@hardlydifficult/queue";
|
|
|
15
15
|
|
|
16
16
|
const queue = createPriorityQueue<string>();
|
|
17
17
|
|
|
18
|
-
queue.enqueue("low-priority
|
|
19
|
-
queue.enqueue("
|
|
20
|
-
queue.enqueue("default-task"); // defaults to 'medium' priority
|
|
18
|
+
queue.enqueue("low-priority task", "low");
|
|
19
|
+
queue.enqueue("urgent fix", "high");
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
console.log(queue.dequeue()?.data); // "
|
|
24
|
-
console.log(queue.dequeue()?.data); // "low-priority
|
|
21
|
+
// High priority item dequeued first
|
|
22
|
+
console.log(queue.dequeue()?.data); // "urgent fix"
|
|
23
|
+
console.log(queue.dequeue()?.data); // "low-priority task"
|
|
25
24
|
```
|
|
26
25
|
|
|
27
|
-
##
|
|
26
|
+
## Priority-Based Ordering
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
Items are dequeued in priority order: high → medium → low. Within each priority level, items follow FIFO (first-in, first-out) order.
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
```typescript
|
|
31
|
+
const queue = createPriorityQueue<string>();
|
|
32
|
+
|
|
33
|
+
queue.enqueue("a", "low");
|
|
34
|
+
queue.enqueue("b", "high");
|
|
35
|
+
queue.enqueue("c", "medium");
|
|
36
|
+
queue.enqueue("d", "high");
|
|
37
|
+
|
|
38
|
+
// Dequeue order: b, d, c, a
|
|
39
|
+
console.log(queue.toArray().map(i => i.data)); // ["b", "d", "c", "a"]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Priority Levels
|
|
43
|
+
|
|
44
|
+
| Priority | Dequeue Order |
|
|
45
|
+
|----------|---------------|
|
|
46
|
+
| `high` | First |
|
|
47
|
+
| `medium` | Second (default) |
|
|
48
|
+
| `low` | Third |
|
|
49
|
+
|
|
50
|
+
## Queue Operations
|
|
51
|
+
|
|
52
|
+
### `enqueue(data, priority?)`
|
|
53
|
+
|
|
54
|
+
Adds an item to the queue.
|
|
55
|
+
|
|
56
|
+
- **Parameters**:
|
|
57
|
+
- `data`: The item to queue
|
|
58
|
+
- `priority`: `"high"`, `"medium"`, or `"low"` (default: `"medium"`)
|
|
59
|
+
- **Returns**: `QueueItem<T>` with metadata (`data`, `priority`, `enqueuedAt`, `id`)
|
|
60
|
+
- **Time complexity**: O(1)
|
|
32
61
|
|
|
33
62
|
```typescript
|
|
34
|
-
|
|
63
|
+
const queue = createPriorityQueue<number>();
|
|
64
|
+
const item = queue.enqueue(42, "high");
|
|
65
|
+
|
|
66
|
+
console.log(item); // { data: 42, priority: "high", enqueuedAt: 1712345678901, id: "q_1" }
|
|
67
|
+
```
|
|
35
68
|
|
|
69
|
+
### `dequeue()`
|
|
70
|
+
|
|
71
|
+
Removes and returns the highest-priority item.
|
|
72
|
+
|
|
73
|
+
- **Returns**: `QueueItem<T> | undefined`
|
|
74
|
+
- **Time complexity**: O(1)
|
|
75
|
+
|
|
76
|
+
### `peek()`
|
|
77
|
+
|
|
78
|
+
Returns the next item without removing it.
|
|
79
|
+
|
|
80
|
+
- **Returns**: `QueueItem<T> | undefined`
|
|
81
|
+
- **Time complexity**: O(1)
|
|
82
|
+
|
|
83
|
+
### `size` & `isEmpty`
|
|
84
|
+
|
|
85
|
+
Accessors for queue state.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
36
88
|
const queue = createPriorityQueue<string>();
|
|
89
|
+
|
|
90
|
+
console.log(queue.size); // 0
|
|
91
|
+
console.log(queue.isEmpty); // true
|
|
92
|
+
|
|
93
|
+
queue.enqueue("item");
|
|
94
|
+
|
|
95
|
+
console.log(queue.size); // 1
|
|
96
|
+
console.log(queue.isEmpty); // false
|
|
37
97
|
```
|
|
38
98
|
|
|
39
|
-
###
|
|
99
|
+
### `toArray()`
|
|
100
|
+
|
|
101
|
+
Returns all items in dequeue order (snapshot).
|
|
40
102
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| `enqueue(data, priority?)` | Add an item to the queue (default priority: `"medium"`) |
|
|
44
|
-
| `dequeue()` | Remove and return the highest-priority item (FIFO within same priority) |
|
|
45
|
-
| `peek()` | View the next item without removing it |
|
|
46
|
-
| `remove(id)` | Remove a specific item by its ID |
|
|
47
|
-
| `size` | Number of items in the queue |
|
|
48
|
-
| `isEmpty` | Whether the queue is empty |
|
|
49
|
-
| `onEnqueue(callback)` | Register a callback for enqueue events |
|
|
50
|
-
| `toArray()` | Get all items in dequeue order as an array |
|
|
51
|
-
| `clear()` | Remove all items from the queue |
|
|
52
|
-
| `updatePriority(id, newPriority)` | Change an item's priority |
|
|
53
|
-
| `moveBefore(itemId, beforeItemId)` | Move an item before another in its priority bucket |
|
|
54
|
-
| `moveToEnd(itemId)` | Move an item to the end of its priority bucket |
|
|
103
|
+
- **Returns**: `readonly QueueItem<T>[]`
|
|
104
|
+
- Does not modify the queue
|
|
55
105
|
|
|
56
|
-
|
|
106
|
+
```typescript
|
|
107
|
+
const queue = createPriorityQueue<string>();
|
|
108
|
+
queue.enqueue("c", "low");
|
|
109
|
+
queue.enqueue("a", "high");
|
|
110
|
+
queue.enqueue("b", "medium");
|
|
111
|
+
|
|
112
|
+
console.log(queue.toArray().map(i => i.data)); // ["a", "b", "c"]
|
|
113
|
+
```
|
|
57
114
|
|
|
58
|
-
|
|
115
|
+
### `clear()`
|
|
116
|
+
|
|
117
|
+
Removes all items from the queue.
|
|
59
118
|
|
|
60
119
|
```typescript
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
id: string;
|
|
66
|
-
}
|
|
120
|
+
const queue = createPriorityQueue<string>();
|
|
121
|
+
queue.enqueue("item");
|
|
122
|
+
queue.clear();
|
|
123
|
+
console.log(queue.size); // 0
|
|
67
124
|
```
|
|
68
125
|
|
|
69
|
-
|
|
126
|
+
## Item Management
|
|
70
127
|
|
|
71
|
-
|
|
128
|
+
### `remove(id)`
|
|
72
129
|
|
|
73
|
-
|
|
130
|
+
Removes a specific item by ID.
|
|
74
131
|
|
|
75
|
-
|
|
132
|
+
- **Returns**: `boolean` (`true` if found and removed)
|
|
133
|
+
- **Time complexity**: O(n) (due to linear search)
|
|
76
134
|
|
|
77
135
|
```typescript
|
|
78
136
|
const queue = createPriorityQueue<string>();
|
|
137
|
+
const item = queue.enqueue("remove-me");
|
|
138
|
+
queue.enqueue("keep-me");
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
140
|
+
console.log(queue.remove(item.id)); // true
|
|
141
|
+
console.log(queue.size); // 1
|
|
142
|
+
console.log(queue.dequeue()?.data); // "keep-me"
|
|
143
|
+
```
|
|
83
144
|
|
|
84
|
-
|
|
145
|
+
### `updatePriority(id, newPriority)`
|
|
85
146
|
|
|
86
|
-
|
|
147
|
+
Changes an item's priority.
|
|
148
|
+
|
|
149
|
+
- **Returns**: `boolean` (`true` if item found)
|
|
150
|
+
- Preserves `data` and `enqueuedAt`; appends to new priority bucket
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const queue = createPriorityQueue<string>();
|
|
154
|
+
const item = queue.enqueue("task", "low");
|
|
155
|
+
queue.enqueue("other", "high");
|
|
156
|
+
|
|
157
|
+
console.log(queue.toArray().map(i => i.priority)); // ["high", "low"]
|
|
158
|
+
|
|
159
|
+
queue.updatePriority(item.id, "high");
|
|
160
|
+
console.log(queue.toArray().map(i => i.priority)); // ["high", "high"]
|
|
87
161
|
```
|
|
88
162
|
|
|
89
|
-
|
|
163
|
+
### `moveBefore(itemId, beforeItemId)`
|
|
90
164
|
|
|
91
|
-
|
|
165
|
+
Reorders items within the same priority bucket.
|
|
166
|
+
|
|
167
|
+
- **Returns**: `boolean` (`true` if move succeeded)
|
|
168
|
+
- Both items must exist and share the same priority
|
|
92
169
|
|
|
93
170
|
```typescript
|
|
94
171
|
const queue = createPriorityQueue<string>();
|
|
172
|
+
const a = queue.enqueue("first");
|
|
173
|
+
const b = queue.enqueue("second");
|
|
174
|
+
const c = queue.enqueue("third");
|
|
175
|
+
|
|
176
|
+
queue.moveBefore(c.id, a.id);
|
|
177
|
+
console.log(queue.toArray().map(i => i.data)); // ["third", "first", "second"]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `moveToEnd(itemId)`
|
|
95
181
|
|
|
96
|
-
|
|
97
|
-
queue.enqueue("task-b", "low");
|
|
98
|
-
queue.enqueue("task-c", "low");
|
|
182
|
+
Moves an item to the end of its priority bucket.
|
|
99
183
|
|
|
100
|
-
|
|
101
|
-
|
|
184
|
+
- **Returns**: `boolean` (`true` if item found)
|
|
185
|
+
- No-op if already at end
|
|
102
186
|
|
|
103
|
-
|
|
104
|
-
queue
|
|
187
|
+
```typescript
|
|
188
|
+
const queue = createPriorityQueue<string>();
|
|
189
|
+
queue.enqueue("first");
|
|
190
|
+
queue.enqueue("second");
|
|
191
|
+
const last = queue.enqueue("third");
|
|
192
|
+
|
|
193
|
+
queue.moveToEnd(last.id); // No change (already at end)
|
|
194
|
+
console.log(queue.toArray().map(i => i.data)); // ["first", "second", "third"]
|
|
105
195
|
```
|
|
106
196
|
|
|
107
|
-
##
|
|
197
|
+
## Observer Pattern
|
|
108
198
|
|
|
109
|
-
###
|
|
199
|
+
### `onEnqueue(callback)`
|
|
110
200
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
201
|
+
Registers a listener for new items.
|
|
202
|
+
|
|
203
|
+
- **Returns**: Unsubscribe function
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const queue = createPriorityQueue<string>();
|
|
207
|
+
const handler = (item) => {
|
|
208
|
+
console.log("Enqueued:", item.data, "at", item.enqueuedAt);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const unsubscribe = queue.onEnqueue(handler);
|
|
212
|
+
|
|
213
|
+
queue.enqueue("test"); // Logs the enqueue event
|
|
214
|
+
unsubscribe();
|
|
215
|
+
queue.enqueue("ignored"); // Not logged
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## API Reference
|
|
219
|
+
|
|
220
|
+
### Types
|
|
221
|
+
|
|
222
|
+
| Name | Description |
|
|
223
|
+
|--------------|------------------------------------------|
|
|
224
|
+
| `Priority` | `"high" | "medium" | "low"` |
|
|
225
|
+
| `QueueItem<T>` | Item with `data`, `priority`, `enqueuedAt`, `id` |
|
|
226
|
+
| `PriorityQueue<T>` | Core queue interface |
|
|
227
|
+
|
|
228
|
+
### Exports
|
|
229
|
+
|
|
230
|
+
| Export | Description |
|
|
231
|
+
|----------------------|----------------------------------|
|
|
232
|
+
| `createPriorityQueue<T>()` | Factory function for new queues |
|
|
233
|
+
| `PriorityQueue<T>` | Queue interface type |
|
|
234
|
+
| `QueueItem<T>` | Item interface type |
|
|
235
|
+
| `Priority` | Priority type alias |
|
|
116
236
|
|
|
117
237
|
### Time Complexity
|
|
118
238
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
239
|
+
| Operation | Complexity |
|
|
240
|
+
|------------------------|------------|
|
|
241
|
+
| `enqueue`, `dequeue`, `peek`, `toArray`, `size`, `isEmpty`, `clear` | O(1) |
|
|
242
|
+
| `remove`, `updatePriority`, `moveBefore`, `moveToEnd` | O(n) |
|