Skip to content

Commit 4eaf6d2

Browse files
committed
Add CommonJS support via dual ESM/CJS packaging
Enable CommonJS consumers to require tinyqueue by adding an index.cjs entry point with the exports field for conditional resolution. The ESM index.js re-exports from index.cjs to keep a single source of truth.
1 parent 3cac14a commit 4eaf6d2

File tree

5 files changed

+100
-72
lines changed

5 files changed

+100
-72
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ Install using NPM (`npm install tinyqueue`), then import as a module:
4343
import TinyQueue from 'tinyqueue';
4444
```
4545

46+
Or use CommonJS `require`:
47+
48+
```js
49+
const TinyQueue = require('tinyqueue');
50+
```
51+
4652
Or use a browser build from a CDN:
4753

4854
```html

index.cjs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
class TinyQueue {
3+
constructor(data = [], compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0)) {
4+
this.data = data;
5+
this.length = this.data.length;
6+
this.compare = compare;
7+
8+
if (this.length > 0) {
9+
for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);
10+
}
11+
}
12+
13+
push(item) {
14+
this.data.push(item);
15+
this._up(this.length++);
16+
}
17+
18+
pop() {
19+
if (this.length === 0) return undefined;
20+
21+
const top = this.data[0];
22+
const bottom = this.data.pop();
23+
24+
if (--this.length > 0) {
25+
this.data[0] = bottom;
26+
this._down(0);
27+
}
28+
29+
return top;
30+
}
31+
32+
peek() {
33+
return this.data[0];
34+
}
35+
36+
_up(pos) {
37+
const {data, compare} = this;
38+
const item = data[pos];
39+
40+
while (pos > 0) {
41+
const parent = (pos - 1) >> 1;
42+
const current = data[parent];
43+
if (compare(item, current) >= 0) break;
44+
data[pos] = current;
45+
pos = parent;
46+
}
47+
48+
data[pos] = item;
49+
}
50+
51+
_down(pos) {
52+
const {data, compare} = this;
53+
const halfLength = this.length >> 1;
54+
const item = data[pos];
55+
56+
while (pos < halfLength) {
57+
let bestChild = (pos << 1) + 1; // initially it is the left child
58+
const right = bestChild + 1;
59+
60+
if (right < this.length && compare(data[right], data[bestChild]) < 0) {
61+
bestChild = right;
62+
}
63+
if (compare(data[bestChild], item) >= 0) break;
64+
65+
data[pos] = data[bestChild];
66+
pos = bestChild;
67+
}
68+
69+
data[pos] = item;
70+
}
71+
}
72+
73+
module.exports = TinyQueue;
74+
module.exports.default = TinyQueue;

index.js

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,2 @@
11

2-
export default class TinyQueue {
3-
constructor(data = [], compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0)) {
4-
this.data = data;
5-
this.length = this.data.length;
6-
this.compare = compare;
7-
8-
if (this.length > 0) {
9-
for (let i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);
10-
}
11-
}
12-
13-
push(item) {
14-
this.data.push(item);
15-
this._up(this.length++);
16-
}
17-
18-
pop() {
19-
if (this.length === 0) return undefined;
20-
21-
const top = this.data[0];
22-
const bottom = this.data.pop();
23-
24-
if (--this.length > 0) {
25-
this.data[0] = bottom;
26-
this._down(0);
27-
}
28-
29-
return top;
30-
}
31-
32-
peek() {
33-
return this.data[0];
34-
}
35-
36-
_up(pos) {
37-
const {data, compare} = this;
38-
const item = data[pos];
39-
40-
while (pos > 0) {
41-
const parent = (pos - 1) >> 1;
42-
const current = data[parent];
43-
if (compare(item, current) >= 0) break;
44-
data[pos] = current;
45-
pos = parent;
46-
}
47-
48-
data[pos] = item;
49-
}
50-
51-
_down(pos) {
52-
const {data, compare} = this;
53-
const halfLength = this.length >> 1;
54-
const item = data[pos];
55-
56-
while (pos < halfLength) {
57-
let bestChild = (pos << 1) + 1; // initially it is the left child
58-
const right = bestChild + 1;
59-
60-
if (right < this.length && compare(data[right], data[bestChild]) < 0) {
61-
bestChild = right;
62-
}
63-
if (compare(data[bestChild], item) >= 0) break;
64-
65-
data[pos] = data[bestChild];
66-
pos = bestChild;
67-
}
68-
69-
data[pos] = item;
70-
}
71-
}
2+
export {default} from './index.cjs';

package.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
"version": "3.0.0",
44
"description": "The smallest and simplest JavaScript priority queue",
55
"type": "module",
6-
"main": "index.js",
6+
"main": "./index.cjs",
77
"module": "index.js",
88
"types": "index.d.ts",
9+
"exports": {
10+
"types": "./index.d.ts",
11+
"import": "./index.js",
12+
"require": "./index.cjs"
13+
},
914
"scripts": {
1015
"lint": "eslint *.js",
1116
"pretest": "npm run lint",
@@ -14,7 +19,9 @@
1419
"prepublishOnly": "npm test"
1520
},
1621
"files": [
17-
"index.d.ts"
22+
"index.d.ts",
23+
"index.cjs",
24+
"index.js"
1825
],
1926
"repository": {
2027
"type": "git",

test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import test from 'node:test';
33
import assert from 'node:assert/strict';
4+
import {createRequire} from 'node:module';
45

56
import TinyQueue from './index.js';
67

@@ -52,3 +53,12 @@ test('handles init with empty array', () => {
5253

5354
assert.deepEqual(queue.data, []);
5455
});
56+
57+
test('CJS require works', () => {
58+
const require_ = createRequire(import.meta.url);
59+
const Queue = require_('./index.cjs');
60+
const queue = new Queue([3, 1, 2]);
61+
assert.equal(queue.pop(), 1);
62+
assert.equal(queue.pop(), 2);
63+
assert.equal(queue.pop(), 3);
64+
});

0 commit comments

Comments
 (0)