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