js-fundamentals 1.0.1 → 1.0.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 CHANGED
@@ -1 +1,101 @@
1
1
  # fundamentals
2
+
3
+ Small JavaScript data-structure utilities (ESM).
4
+
5
+ Currently included:
6
+
7
+ - `Queue`: FIFO queue
8
+ - `PriorityQueue`: queue ordered by numeric priority (ascending by default)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm i js-fundamentals
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ This package is **ESM-only** (`"type": "module"`).
19
+
20
+ ```js
21
+ import { Queue, PriorityQueue } from "js-fundamentals";
22
+ ```
23
+
24
+ ### Queue
25
+
26
+ ```js
27
+ import { Queue } from "js-fundamentals";
28
+
29
+ const q = new Queue();
30
+ q.enqueue("a");
31
+ q.enqueue("b");
32
+
33
+ q.peek(); // "a"
34
+ q.dequeue(); // "a"
35
+ q.size(); // 1
36
+ q.toArray(); // ["b"]
37
+ ```
38
+
39
+ ### PriorityQueue
40
+
41
+ `PriorityQueue` stores `(item, priority)` pairs internally and always dequeues the next item based on priority.
42
+
43
+ By default it is **ascending** (lower numbers come out first). Pass `{ descending: true }` to the constructor for **descending** order.
44
+
45
+ ```js
46
+ import { PriorityQueue } from "js-fundamentals";
47
+
48
+ const pq = new PriorityQueue(); // ascending
49
+ pq.enqueue("low", 10);
50
+ pq.enqueue("high", 1);
51
+
52
+ pq.dequeue(); // "high"
53
+ pq.toArray(); // ["low"]
54
+ ```
55
+
56
+ Descending order:
57
+
58
+ ```js
59
+ const pq = new PriorityQueue({ descending: true }); // descending
60
+ pq.enqueue("low", 1);
61
+ pq.enqueue("high", 10);
62
+
63
+ pq.dequeue(); // "high"
64
+ ```
65
+
66
+ ## API
67
+
68
+ ### `new Queue()`
69
+
70
+ - `enqueue(item): void`
71
+ - `dequeue(): any | undefined` (returns `undefined` if empty)
72
+ - `peek(): any | undefined` (returns `undefined` if empty)
73
+ - `isEmpty(): boolean`
74
+ - `size(): number`
75
+ - `toArray(): any[]` (returns the internal backing array)
76
+
77
+ ### `new PriorityQueue(options?)`
78
+
79
+ Extends `Queue`.
80
+
81
+ - `options.descending?: boolean` (default: `false`)
82
+ - `enqueue(item, priority): void` (`priority` should be a number)
83
+ - `dequeue(): any | undefined` (returns `undefined` if empty)
84
+ - `peek(): any | undefined` (returns `undefined` if empty)
85
+ - `isEmpty(): boolean`
86
+ - `size(): number`
87
+ - `toArray(): any[]` (returns only items, not priorities)
88
+ - `changePriority(item, newPriority): void`
89
+ - Finds an existing item and updates its priority, then re-sorts the queue.
90
+ - Matching rules:
91
+ - Uses strict equality (`===`) for non-objects
92
+ - For non-null objects, falls back to `JSON.stringify` comparison
93
+ - Throws `Error("Item not found")` if no match is found.
94
+
95
+ ## Development
96
+
97
+ ```bash
98
+ npm test
99
+ npm run lint
100
+ npm run format
101
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-fundamentals",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/eetujukka1/fundamentals#readme",
6
6
  "bugs": {
@@ -1,8 +1,9 @@
1
1
  import Queue from "../queue";
2
2
 
3
3
  class PriorityQueue extends Queue {
4
- constructor(descending = false) {
4
+ constructor(options = {}) {
5
5
  super();
6
+ const { descending = false } = options;
6
7
  this.descending = descending;
7
8
  }
8
9
 
@@ -32,6 +33,31 @@ class PriorityQueue extends Queue {
32
33
  toArray() {
33
34
  return this.items.map((item) => item.item);
34
35
  }
36
+
37
+ changePriority(item, newPriority) {
38
+ const index = this.items.findIndex((i) => {
39
+ if (i.item === item) {
40
+ return true;
41
+ }
42
+
43
+ if (
44
+ typeof i.item === "object" &&
45
+ typeof item === "object" &&
46
+ i.item !== null &&
47
+ item !== null
48
+ ) {
49
+ return JSON.stringify(i.item) === JSON.stringify(item);
50
+ }
51
+ return false;
52
+ });
53
+ if (index === -1) {
54
+ throw new Error("Item not found");
55
+ }
56
+ this.items[index].priority = newPriority;
57
+ this.items.sort((a, b) =>
58
+ this.descending ? b.priority - a.priority : a.priority - b.priority,
59
+ );
60
+ }
35
61
  }
36
62
 
37
63
  export default PriorityQueue;
@@ -23,6 +23,15 @@ describe("PriorityQueue", () => {
23
23
  expect(queue.isEmpty()).toBe(false);
24
24
  });
25
25
 
26
+ it("should dequeue an item with descending priority", () => {
27
+ const queue = new PriorityQueue({ descending: true });
28
+ queue.enqueue(1, 1);
29
+ queue.enqueue(2, 2);
30
+ queue.enqueue(3, 3);
31
+ expect(queue.dequeue()).toBe(3);
32
+ expect(queue.isEmpty()).toBe(false);
33
+ });
34
+
26
35
  it("should peek at the front item", () => {
27
36
  const queue = new PriorityQueue();
28
37
  queue.enqueue(3, 3);
@@ -55,4 +64,13 @@ describe("PriorityQueue", () => {
55
64
  queue.enqueue(1, 1);
56
65
  expect(queue.toArray()).toEqual([1, 2, 3]);
57
66
  });
67
+
68
+ it("should change the priority of an item", () => {
69
+ const queue = new PriorityQueue();
70
+ queue.enqueue({ id: 1 }, 1);
71
+ queue.enqueue({ id: 2 }, 2);
72
+ queue.enqueue({ id: 3 }, 3);
73
+ queue.changePriority({ id: 2 }, 4);
74
+ expect(queue.toArray()).toEqual([{ id: 1 }, { id: 3 }, { id: 2 }]);
75
+ });
58
76
  });