@hardlydifficult/queue 1.1.1 → 1.1.3
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 +61 -133
- 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
|
|
3
|
+
A high-performance priority queue with O(1) enqueue/dequeue and FIFO ordering within priority levels.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -15,180 +15,108 @@ import { createPriorityQueue } from "@hardlydifficult/queue";
|
|
|
15
15
|
|
|
16
16
|
const queue = createPriorityQueue<string>();
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
queue.enqueue("
|
|
20
|
-
queue.enqueue("
|
|
21
|
-
queue.enqueue("background task", "low");
|
|
18
|
+
queue.enqueue("low-priority-task", "low");
|
|
19
|
+
queue.enqueue("critical-task", "high");
|
|
20
|
+
queue.enqueue("default-task"); // defaults to 'medium' priority
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
console.log(queue.dequeue()?.data); // "
|
|
25
|
-
console.log(queue.dequeue()?.data); // "
|
|
26
|
-
console.log(queue.dequeue()?.data); // "background task"
|
|
22
|
+
console.log(queue.dequeue()?.data); // "critical-task"
|
|
23
|
+
console.log(queue.dequeue()?.data); // "default-task"
|
|
24
|
+
console.log(queue.dequeue()?.data); // "low-priority-task"
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
## Core
|
|
27
|
+
## Core API
|
|
30
28
|
|
|
31
|
-
###
|
|
29
|
+
### createPriorityQueue<T>()
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
Creates a new priority queue instance.
|
|
34
32
|
|
|
35
33
|
```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");
|
|
42
|
-
|
|
43
|
-
// Dequeue returns highest priority first, FIFO within same priority
|
|
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)
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Peek
|
|
50
|
-
|
|
51
|
-
Inspect the next item without removing it from the queue.
|
|
34
|
+
import { createPriorityQueue } from "@hardlydifficult/queue";
|
|
52
35
|
|
|
53
|
-
```typescript
|
|
54
36
|
const queue = createPriorityQueue<string>();
|
|
55
|
-
queue.enqueue("first", "high");
|
|
56
|
-
queue.enqueue("second", "low");
|
|
57
|
-
|
|
58
|
-
queue.peek()?.data; // "first" (highest priority)
|
|
59
|
-
queue.size; // Still 2
|
|
60
37
|
```
|
|
61
38
|
|
|
62
|
-
###
|
|
39
|
+
### PriorityQueue<T> Methods
|
|
63
40
|
|
|
64
|
-
|
|
41
|
+
| Method | Description |
|
|
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 |
|
|
65
55
|
|
|
66
|
-
|
|
67
|
-
const queue = createPriorityQueue<string>();
|
|
56
|
+
### QueueItem<T>
|
|
68
57
|
|
|
69
|
-
queue
|
|
70
|
-
queue.size; // 0
|
|
71
|
-
|
|
72
|
-
queue.enqueue("item");
|
|
73
|
-
queue.isEmpty; // false
|
|
74
|
-
queue.size; // 1
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Item Management
|
|
78
|
-
|
|
79
|
-
### Remove Items
|
|
80
|
-
|
|
81
|
-
Remove a specific item by its ID. Returns `true` if the item was found and removed.
|
|
58
|
+
Represents an item in the queue with metadata:
|
|
82
59
|
|
|
83
60
|
```typescript
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
61
|
+
interface QueueItem<T> {
|
|
62
|
+
data: T;
|
|
63
|
+
priority: "high" | "medium" | "low";
|
|
64
|
+
enqueuedAt: number;
|
|
65
|
+
id: string;
|
|
66
|
+
}
|
|
89
67
|
```
|
|
90
68
|
|
|
91
|
-
###
|
|
69
|
+
### Priority Levels
|
|
92
70
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
const queue = createPriorityQueue<string>();
|
|
97
|
-
const item = queue.enqueue("task", "low");
|
|
98
|
-
|
|
99
|
-
queue.updatePriority(item.id, "high"); // true
|
|
100
|
-
queue.peek()?.data; // "task" (now highest priority)
|
|
101
|
-
```
|
|
71
|
+
Items are dequeued in priority order: `high` → `medium` → `low`. Within the same priority, items follow FIFO (first-in-first-out) order.
|
|
102
72
|
|
|
103
|
-
|
|
73
|
+
## Observer Pattern
|
|
104
74
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
const queue = createPriorityQueue<string>();
|
|
109
|
-
const a = queue.enqueue("A", "high");
|
|
110
|
-
const b = queue.enqueue("B", "high");
|
|
111
|
-
const c = queue.enqueue("C", "high");
|
|
112
|
-
|
|
113
|
-
// Move A before C
|
|
114
|
-
queue.moveBefore(a.id, c.id); // true
|
|
115
|
-
queue.toArray().map(i => i.data); // ["B", "A", "C"]
|
|
116
|
-
|
|
117
|
-
// Move B to the end
|
|
118
|
-
queue.moveToEnd(b.id); // true
|
|
119
|
-
queue.toArray().map(i => i.data); // ["A", "C", "B"]
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Snapshots and Listeners
|
|
123
|
-
|
|
124
|
-
### Get All Items
|
|
125
|
-
|
|
126
|
-
Retrieve all items in dequeue order without modifying the queue.
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
const queue = createPriorityQueue<string>();
|
|
130
|
-
queue.enqueue("low", "low");
|
|
131
|
-
queue.enqueue("high", "high");
|
|
132
|
-
queue.enqueue("medium", "medium");
|
|
133
|
-
|
|
134
|
-
const items = queue.toArray();
|
|
135
|
-
items.map(i => i.data); // ["high", "medium", "low"]
|
|
136
|
-
queue.size; // Still 3
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Listen for Enqueues
|
|
140
|
-
|
|
141
|
-
Register a callback that fires whenever an item is enqueued. Returns an unsubscribe function.
|
|
75
|
+
Register callbacks to be notified when items are enqueued:
|
|
142
76
|
|
|
143
77
|
```typescript
|
|
144
78
|
const queue = createPriorityQueue<string>();
|
|
145
79
|
|
|
146
80
|
const unsubscribe = queue.onEnqueue((item) => {
|
|
147
|
-
console.log(`Enqueued
|
|
81
|
+
console.log(`Enqueued item: ${item.data}`);
|
|
148
82
|
});
|
|
149
83
|
|
|
150
|
-
queue.enqueue("task"
|
|
151
|
-
// Logs: "Enqueued: task (priority: high)"
|
|
84
|
+
queue.enqueue("new task");
|
|
152
85
|
|
|
153
|
-
unsubscribe();
|
|
154
|
-
queue.enqueue("another"); // No log
|
|
86
|
+
unsubscribe(); // stop notifications
|
|
155
87
|
```
|
|
156
88
|
|
|
157
|
-
|
|
89
|
+
## Priority Manipulation
|
|
158
90
|
|
|
159
|
-
|
|
91
|
+
Update priority and reorder items after enqueue:
|
|
160
92
|
|
|
161
93
|
```typescript
|
|
162
94
|
const queue = createPriorityQueue<string>();
|
|
163
|
-
queue.enqueue("a");
|
|
164
|
-
queue.enqueue("b");
|
|
165
95
|
|
|
166
|
-
queue.
|
|
167
|
-
queue.
|
|
168
|
-
|
|
96
|
+
const a = queue.enqueue("task-a", "low");
|
|
97
|
+
queue.enqueue("task-b", "low");
|
|
98
|
+
queue.enqueue("task-c", "low");
|
|
169
99
|
|
|
170
|
-
|
|
100
|
+
// Move 'task-a' to high priority
|
|
101
|
+
queue.updatePriority(a.id, "high");
|
|
171
102
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
const queue = createPriorityQueue<string>();
|
|
176
|
-
const item = queue.enqueue("my task", "high");
|
|
177
|
-
|
|
178
|
-
item.data; // "my task"
|
|
179
|
-
item.priority; // "high"
|
|
180
|
-
item.id; // "q_1" (unique identifier)
|
|
181
|
-
item.enqueuedAt; // 1699564800000 (epoch milliseconds)
|
|
103
|
+
// Move 'task-c' before 'task-b' in the low bucket
|
|
104
|
+
queue.moveBefore(queue.toArray()[2].id, queue.toArray()[1].id);
|
|
182
105
|
```
|
|
183
106
|
|
|
184
|
-
##
|
|
107
|
+
## Reference
|
|
185
108
|
|
|
186
|
-
|
|
109
|
+
### Priority Order
|
|
187
110
|
|
|
188
111
|
| Priority | Dequeue Order |
|
|
189
112
|
|----------|---------------|
|
|
190
|
-
| `"high"` |
|
|
191
|
-
| `"medium"` |
|
|
192
|
-
| `"low"`
|
|
113
|
+
| `"high"` | First |
|
|
114
|
+
| `"medium"` | Second |
|
|
115
|
+
| `"low"` | Last |
|
|
116
|
+
|
|
117
|
+
### Time Complexity
|
|
193
118
|
|
|
194
|
-
|
|
119
|
+
- `enqueue`: O(1)
|
|
120
|
+
- `dequeue`: O(1)
|
|
121
|
+
- `remove`, `updatePriority`, `moveBefore`, `moveToEnd`: O(n)
|
|
122
|
+
- `toArray`, `peek`: O(1)
|