d-ary-heap 2.1.2 → 2.4.0

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/dist/index.d.cts CHANGED
@@ -1,3 +1,230 @@
1
+ /**
2
+ * Instrumentation utilities for d-ary heap performance analysis.
3
+ *
4
+ * This module provides opt-in instrumentation to count comparisons performed
5
+ * during heap operations. It is designed for:
6
+ *
7
+ * - **Educational purposes**: Understanding the theoretical vs actual cost of heap operations
8
+ * - **Benchmarking**: Measuring real comparison counts across different arities
9
+ * - **Visualization**: Powering interactive demos that show heap behavior
10
+ *
11
+ * ## Design Philosophy: Zero-Cost When Disabled
12
+ *
13
+ * Instrumentation follows these principles:
14
+ *
15
+ * 1. **Opt-in only**: No overhead when not using instrumentation
16
+ * 2. **Non-breaking**: Existing code continues to work unchanged
17
+ * 3. **Per-operation tracking**: Distinguish insert/pop/decreasePriority comparisons
18
+ *
19
+ * ## Cross-Language Consistency
20
+ *
21
+ * Currently, instrumentation is implemented in TypeScript only. The table below
22
+ * shows the idiomatic zero-cost approach for each language, planned for v2.5.0:
23
+ *
24
+ * | Language | Mechanism | Overhead When Disabled | Status |
25
+ * |------------|----------------------------------|------------------------|--------|
26
+ * | TypeScript | Optional hooks + instrumented comparator | Zero (JIT optimization) | ✅ Implemented |
27
+ * | Go | Nil stats pointer | ~1 cycle (nil check) | Planned v2.5.0 |
28
+ * | Rust | Generic over StatsCollector trait | Zero (monomorphization) | Planned v2.5.0 |
29
+ * | C++ | Template policy class | Zero (inlining) | Planned v2.5.0 |
30
+ * | Zig | Comptime bool parameter | Zero (branch elimination) | Planned v2.5.0 |
31
+ *
32
+ * ## Usage Example
33
+ *
34
+ * ```typescript
35
+ * import { PriorityQueue, minBy, instrumentComparator } from 'd-ary-heap';
36
+ *
37
+ * // 1. Wrap your comparator with instrumentation
38
+ * const comparator = instrumentComparator(minBy((v: Vertex) => v.distance));
39
+ *
40
+ * // 2. Create priority queue with operation hooks
41
+ * const pq = new PriorityQueue({
42
+ * d: 4,
43
+ * comparator,
44
+ * keyExtractor: (v) => v.id,
45
+ * onBeforeOperation: (op) => comparator.startOperation(op),
46
+ * onAfterOperation: () => comparator.endOperation(),
47
+ * });
48
+ *
49
+ * // 3. Use normally - comparisons are tracked automatically
50
+ * pq.insert({ id: 'A', distance: 0 });
51
+ * pq.insert({ id: 'B', distance: 5 });
52
+ * pq.pop();
53
+ *
54
+ * // 4. Access statistics
55
+ * console.log(comparator.stats);
56
+ * // { insert: 1, pop: 2, decreasePriority: 0, total: 3 }
57
+ *
58
+ * // 5. Reset for next measurement
59
+ * comparator.stats.reset();
60
+ * ```
61
+ *
62
+ * ## Theoretical Complexity Reference
63
+ *
64
+ * For a d-ary heap with n elements:
65
+ *
66
+ * | Operation | Comparisons (worst case) |
67
+ * |------------------|----------------------------|
68
+ * | insert | ⌊log_d(n)⌋ |
69
+ * | pop | d × ⌊log_d(n)⌋ |
70
+ * | decreasePriority | ⌊log_d(n)⌋ (upward only) |
71
+ * | increasePriority | d × ⌊log_d(n)⌋ (downward) |
72
+ *
73
+ * The demo visualization compares actual counts against these theoretical bounds.
74
+ *
75
+ * @module instrumentation
76
+ * @version 2.4.0
77
+ * @license Apache-2.0
78
+ */
79
+
80
+ /**
81
+ * Operation types that can be tracked.
82
+ *
83
+ * Note: `increasePriority` is tracked separately because in Dijkstra's algorithm
84
+ * it manifests as decreasePriority (lowering distance = higher priority in min-heap).
85
+ */
86
+ type OperationType = 'insert' | 'pop' | 'decreasePriority' | 'increasePriority';
87
+ /**
88
+ * Statistics tracking comparison counts per operation type.
89
+ *
90
+ * All counts start at zero and accumulate until `reset()` is called.
91
+ */
92
+ interface ComparisonStats {
93
+ /** Comparisons during insert operations (moveUp) */
94
+ insert: number;
95
+ /** Comparisons during pop operations (moveDown + bestChildPosition) */
96
+ pop: number;
97
+ /** Comparisons during decreasePriority operations (moveUp + moveDown) */
98
+ decreasePriority: number;
99
+ /** Comparisons during increasePriority operations (moveUp) */
100
+ increasePriority: number;
101
+ /** Total comparisons across all operation types */
102
+ readonly total: number;
103
+ /** Reset all counters to zero */
104
+ reset(): void;
105
+ }
106
+ /**
107
+ * An instrumented comparator that tracks comparison counts.
108
+ *
109
+ * This extends a regular comparator with:
110
+ * - `stats`: Current comparison counts
111
+ * - `startOperation(type)`: Begin tracking for an operation
112
+ * - `endOperation()`: Stop tracking current operation
113
+ *
114
+ * The comparator itself remains a valid `Comparator<T>` and can be used
115
+ * anywhere a regular comparator is expected.
116
+ */
117
+ interface InstrumentedComparator<T> extends Comparator<T> {
118
+ /** Current comparison statistics */
119
+ readonly stats: ComparisonStats;
120
+ /**
121
+ * Signal the start of a heap operation.
122
+ * Comparisons will be attributed to this operation type until `endOperation()`.
123
+ *
124
+ * @param type - The operation type being started
125
+ */
126
+ startOperation(type: OperationType): void;
127
+ /**
128
+ * Signal the end of the current heap operation.
129
+ * Subsequent comparisons will not be counted until the next `startOperation()`.
130
+ */
131
+ endOperation(): void;
132
+ }
133
+ /**
134
+ * Create comparison statistics tracker.
135
+ *
136
+ * @returns Fresh stats object with all counts at zero
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * const stats = createComparisonStats();
141
+ * stats.insert = 5;
142
+ * stats.pop = 10;
143
+ * console.log(stats.total); // 15
144
+ * stats.reset();
145
+ * console.log(stats.total); // 0
146
+ * ```
147
+ */
148
+ declare function createComparisonStats(): ComparisonStats;
149
+ /**
150
+ * Wrap a comparator with instrumentation to track comparison counts.
151
+ *
152
+ * The returned comparator:
153
+ * - Behaves identically to the original for comparison purposes
154
+ * - Tracks how many times it's called, attributed to operation types
155
+ * - Has zero overhead when `startOperation()` hasn't been called
156
+ *
157
+ * ## How It Works
158
+ *
159
+ * 1. Call `startOperation('insert')` before `pq.insert()`
160
+ * 2. The comparator increments `stats.insert` for each comparison
161
+ * 3. Call `endOperation()` after the operation completes
162
+ * 4. Repeat for other operations
163
+ *
164
+ * The `PriorityQueue` class supports `onBeforeOperation` and `onAfterOperation`
165
+ * hooks to automate this.
166
+ *
167
+ * ## Performance Note
168
+ *
169
+ * When `currentOperation` is null (between operations), the instrumented
170
+ * comparator performs only a single null check before calling the original.
171
+ * Modern JavaScript engines optimize this extremely well.
172
+ *
173
+ * @param comparator - The original comparator to instrument
174
+ * @returns An instrumented comparator with stats tracking
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * import { minBy, instrumentComparator } from 'd-ary-heap';
179
+ *
180
+ * const cmp = instrumentComparator(minBy<number, number>(x => x));
181
+ *
182
+ * // Manual usage (without hooks)
183
+ * cmp.startOperation('insert');
184
+ * console.log(cmp(5, 3)); // false, and stats.insert++
185
+ * console.log(cmp(3, 5)); // true, and stats.insert++
186
+ * cmp.endOperation();
187
+ *
188
+ * console.log(cmp.stats.insert); // 2
189
+ * ```
190
+ */
191
+ declare function instrumentComparator<T>(comparator: Comparator<T>): InstrumentedComparator<T>;
192
+ /**
193
+ * Calculate theoretical comparison count for an insert operation.
194
+ *
195
+ * Insert performs at most ⌊log_d(n)⌋ comparisons (one per level during moveUp).
196
+ *
197
+ * @param n - Number of elements in heap AFTER insert
198
+ * @param d - Heap arity
199
+ * @returns Theoretical worst-case comparison count
200
+ */
201
+ declare function theoreticalInsertComparisons(n: number, d: number): number;
202
+ /**
203
+ * Calculate theoretical comparison count for a pop operation.
204
+ *
205
+ * Pop performs at most d × ⌊log_d(n)⌋ comparisons:
206
+ * - At each level, find best among d children (d-1 comparisons)
207
+ * - Compare best child with current (1 comparison)
208
+ * - Total: d comparisons per level × ⌊log_d(n)⌋ levels
209
+ *
210
+ * @param n - Number of elements in heap BEFORE pop
211
+ * @param d - Heap arity
212
+ * @returns Theoretical worst-case comparison count
213
+ */
214
+ declare function theoreticalPopComparisons(n: number, d: number): number;
215
+ /**
216
+ * Calculate theoretical comparison count for a decreasePriority operation.
217
+ *
218
+ * DecreasePriority in our implementation calls both moveUp and moveDown
219
+ * for safety, but typically only moveUp executes (upward movement).
220
+ * Worst case: ⌊log_d(n)⌋ comparisons.
221
+ *
222
+ * @param n - Number of elements in heap
223
+ * @param d - Heap arity
224
+ * @returns Theoretical worst-case comparison count (moveUp path)
225
+ */
226
+ declare function theoreticalDecreasePriorityComparisons(n: number, d: number): number;
227
+
1
228
  /**
2
229
  * d-ary Heap Priority Queue - TypeScript Implementation
3
230
  *
@@ -8,11 +235,13 @@
8
235
  * - O(1) access to highest-priority item
9
236
  * - O(log_d n) insert and priority increase operations
10
237
  * - O(d · log_d n) pop and priority decrease operations
238
+ * - Optional instrumentation hooks for performance analysis
11
239
  *
12
- * @version 2.1.2
240
+ * @version 2.4.0
13
241
  * @license Apache-2.0
14
242
  * @copyright 2023-2025 Eric Jacopin
15
243
  */
244
+
16
245
  /** Type alias for position indices (cross-language consistency) */
17
246
  type Position = number;
18
247
  /**
@@ -37,6 +266,35 @@ interface PriorityQueueOptions<T, K> {
37
266
  keyExtractor: KeyExtractor<T, K>;
38
267
  /** Initial capacity hint for pre-allocation */
39
268
  initialCapacity?: number;
269
+ /**
270
+ * Optional hook called before each heap operation.
271
+ *
272
+ * This enables opt-in instrumentation for performance analysis without
273
+ * adding overhead when not used. Pair with an instrumented comparator
274
+ * to track comparison counts per operation type.
275
+ *
276
+ * @param type - The operation about to be performed
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const cmp = instrumentComparator(minBy((v) => v.priority));
281
+ * const pq = new PriorityQueue({
282
+ * comparator: cmp,
283
+ * keyExtractor: (v) => v.id,
284
+ * onBeforeOperation: (op) => cmp.startOperation(op),
285
+ * onAfterOperation: () => cmp.endOperation(),
286
+ * });
287
+ * ```
288
+ *
289
+ * @see instrumentComparator from './instrumentation'
290
+ */
291
+ onBeforeOperation?: (type: OperationType) => void;
292
+ /**
293
+ * Optional hook called after each heap operation completes.
294
+ *
295
+ * @see onBeforeOperation for usage example
296
+ */
297
+ onAfterOperation?: () => void;
40
298
  }
41
299
  /**
42
300
  * Generic d-ary heap priority queue with O(1) lookup.
@@ -73,6 +331,10 @@ declare class PriorityQueue<T, K = string | number> {
73
331
  private readonly comparator;
74
332
  /** Key extractor for identity-based lookup */
75
333
  private readonly keyExtractor;
334
+ /** Optional hook called before operations (for instrumentation) */
335
+ private readonly onBeforeOperation;
336
+ /** Optional hook called after operations (for instrumentation) */
337
+ private readonly onAfterOperation;
76
338
  /**
77
339
  * Create a new d-ary heap priority queue.
78
340
  *
@@ -305,7 +567,7 @@ declare class PriorityQueue<T, K = string | number> {
305
567
  * Pre-built comparator factories for common use cases.
306
568
  *
307
569
  * @module comparators
308
- * @version 2.1.2
570
+ * @version 2.4.0
309
571
  * @license Apache-2.0
310
572
  */
311
573
 
@@ -385,4 +647,4 @@ declare function reverse<T>(cmp: Comparator<T>): Comparator<T>;
385
647
  */
386
648
  declare function chain<T>(...comparators: Comparator<T>[]): Comparator<T>;
387
649
 
388
- export { type Comparator, type KeyExtractor, type Position, PriorityQueue, type PriorityQueueOptions, chain, maxBy, maxNumber, maxString, minBy, minNumber, minString, reverse };
650
+ export { type Comparator, type ComparisonStats, type InstrumentedComparator, type KeyExtractor, type OperationType, type Position, PriorityQueue, type PriorityQueueOptions, chain, createComparisonStats, instrumentComparator, maxBy, maxNumber, maxString, minBy, minNumber, minString, reverse, theoreticalDecreasePriorityComparisons, theoreticalInsertComparisons, theoreticalPopComparisons };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,230 @@
1
+ /**
2
+ * Instrumentation utilities for d-ary heap performance analysis.
3
+ *
4
+ * This module provides opt-in instrumentation to count comparisons performed
5
+ * during heap operations. It is designed for:
6
+ *
7
+ * - **Educational purposes**: Understanding the theoretical vs actual cost of heap operations
8
+ * - **Benchmarking**: Measuring real comparison counts across different arities
9
+ * - **Visualization**: Powering interactive demos that show heap behavior
10
+ *
11
+ * ## Design Philosophy: Zero-Cost When Disabled
12
+ *
13
+ * Instrumentation follows these principles:
14
+ *
15
+ * 1. **Opt-in only**: No overhead when not using instrumentation
16
+ * 2. **Non-breaking**: Existing code continues to work unchanged
17
+ * 3. **Per-operation tracking**: Distinguish insert/pop/decreasePriority comparisons
18
+ *
19
+ * ## Cross-Language Consistency
20
+ *
21
+ * Currently, instrumentation is implemented in TypeScript only. The table below
22
+ * shows the idiomatic zero-cost approach for each language, planned for v2.5.0:
23
+ *
24
+ * | Language | Mechanism | Overhead When Disabled | Status |
25
+ * |------------|----------------------------------|------------------------|--------|
26
+ * | TypeScript | Optional hooks + instrumented comparator | Zero (JIT optimization) | ✅ Implemented |
27
+ * | Go | Nil stats pointer | ~1 cycle (nil check) | Planned v2.5.0 |
28
+ * | Rust | Generic over StatsCollector trait | Zero (monomorphization) | Planned v2.5.0 |
29
+ * | C++ | Template policy class | Zero (inlining) | Planned v2.5.0 |
30
+ * | Zig | Comptime bool parameter | Zero (branch elimination) | Planned v2.5.0 |
31
+ *
32
+ * ## Usage Example
33
+ *
34
+ * ```typescript
35
+ * import { PriorityQueue, minBy, instrumentComparator } from 'd-ary-heap';
36
+ *
37
+ * // 1. Wrap your comparator with instrumentation
38
+ * const comparator = instrumentComparator(minBy((v: Vertex) => v.distance));
39
+ *
40
+ * // 2. Create priority queue with operation hooks
41
+ * const pq = new PriorityQueue({
42
+ * d: 4,
43
+ * comparator,
44
+ * keyExtractor: (v) => v.id,
45
+ * onBeforeOperation: (op) => comparator.startOperation(op),
46
+ * onAfterOperation: () => comparator.endOperation(),
47
+ * });
48
+ *
49
+ * // 3. Use normally - comparisons are tracked automatically
50
+ * pq.insert({ id: 'A', distance: 0 });
51
+ * pq.insert({ id: 'B', distance: 5 });
52
+ * pq.pop();
53
+ *
54
+ * // 4. Access statistics
55
+ * console.log(comparator.stats);
56
+ * // { insert: 1, pop: 2, decreasePriority: 0, total: 3 }
57
+ *
58
+ * // 5. Reset for next measurement
59
+ * comparator.stats.reset();
60
+ * ```
61
+ *
62
+ * ## Theoretical Complexity Reference
63
+ *
64
+ * For a d-ary heap with n elements:
65
+ *
66
+ * | Operation | Comparisons (worst case) |
67
+ * |------------------|----------------------------|
68
+ * | insert | ⌊log_d(n)⌋ |
69
+ * | pop | d × ⌊log_d(n)⌋ |
70
+ * | decreasePriority | ⌊log_d(n)⌋ (upward only) |
71
+ * | increasePriority | d × ⌊log_d(n)⌋ (downward) |
72
+ *
73
+ * The demo visualization compares actual counts against these theoretical bounds.
74
+ *
75
+ * @module instrumentation
76
+ * @version 2.4.0
77
+ * @license Apache-2.0
78
+ */
79
+
80
+ /**
81
+ * Operation types that can be tracked.
82
+ *
83
+ * Note: `increasePriority` is tracked separately because in Dijkstra's algorithm
84
+ * it manifests as decreasePriority (lowering distance = higher priority in min-heap).
85
+ */
86
+ type OperationType = 'insert' | 'pop' | 'decreasePriority' | 'increasePriority';
87
+ /**
88
+ * Statistics tracking comparison counts per operation type.
89
+ *
90
+ * All counts start at zero and accumulate until `reset()` is called.
91
+ */
92
+ interface ComparisonStats {
93
+ /** Comparisons during insert operations (moveUp) */
94
+ insert: number;
95
+ /** Comparisons during pop operations (moveDown + bestChildPosition) */
96
+ pop: number;
97
+ /** Comparisons during decreasePriority operations (moveUp + moveDown) */
98
+ decreasePriority: number;
99
+ /** Comparisons during increasePriority operations (moveUp) */
100
+ increasePriority: number;
101
+ /** Total comparisons across all operation types */
102
+ readonly total: number;
103
+ /** Reset all counters to zero */
104
+ reset(): void;
105
+ }
106
+ /**
107
+ * An instrumented comparator that tracks comparison counts.
108
+ *
109
+ * This extends a regular comparator with:
110
+ * - `stats`: Current comparison counts
111
+ * - `startOperation(type)`: Begin tracking for an operation
112
+ * - `endOperation()`: Stop tracking current operation
113
+ *
114
+ * The comparator itself remains a valid `Comparator<T>` and can be used
115
+ * anywhere a regular comparator is expected.
116
+ */
117
+ interface InstrumentedComparator<T> extends Comparator<T> {
118
+ /** Current comparison statistics */
119
+ readonly stats: ComparisonStats;
120
+ /**
121
+ * Signal the start of a heap operation.
122
+ * Comparisons will be attributed to this operation type until `endOperation()`.
123
+ *
124
+ * @param type - The operation type being started
125
+ */
126
+ startOperation(type: OperationType): void;
127
+ /**
128
+ * Signal the end of the current heap operation.
129
+ * Subsequent comparisons will not be counted until the next `startOperation()`.
130
+ */
131
+ endOperation(): void;
132
+ }
133
+ /**
134
+ * Create comparison statistics tracker.
135
+ *
136
+ * @returns Fresh stats object with all counts at zero
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * const stats = createComparisonStats();
141
+ * stats.insert = 5;
142
+ * stats.pop = 10;
143
+ * console.log(stats.total); // 15
144
+ * stats.reset();
145
+ * console.log(stats.total); // 0
146
+ * ```
147
+ */
148
+ declare function createComparisonStats(): ComparisonStats;
149
+ /**
150
+ * Wrap a comparator with instrumentation to track comparison counts.
151
+ *
152
+ * The returned comparator:
153
+ * - Behaves identically to the original for comparison purposes
154
+ * - Tracks how many times it's called, attributed to operation types
155
+ * - Has zero overhead when `startOperation()` hasn't been called
156
+ *
157
+ * ## How It Works
158
+ *
159
+ * 1. Call `startOperation('insert')` before `pq.insert()`
160
+ * 2. The comparator increments `stats.insert` for each comparison
161
+ * 3. Call `endOperation()` after the operation completes
162
+ * 4. Repeat for other operations
163
+ *
164
+ * The `PriorityQueue` class supports `onBeforeOperation` and `onAfterOperation`
165
+ * hooks to automate this.
166
+ *
167
+ * ## Performance Note
168
+ *
169
+ * When `currentOperation` is null (between operations), the instrumented
170
+ * comparator performs only a single null check before calling the original.
171
+ * Modern JavaScript engines optimize this extremely well.
172
+ *
173
+ * @param comparator - The original comparator to instrument
174
+ * @returns An instrumented comparator with stats tracking
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * import { minBy, instrumentComparator } from 'd-ary-heap';
179
+ *
180
+ * const cmp = instrumentComparator(minBy<number, number>(x => x));
181
+ *
182
+ * // Manual usage (without hooks)
183
+ * cmp.startOperation('insert');
184
+ * console.log(cmp(5, 3)); // false, and stats.insert++
185
+ * console.log(cmp(3, 5)); // true, and stats.insert++
186
+ * cmp.endOperation();
187
+ *
188
+ * console.log(cmp.stats.insert); // 2
189
+ * ```
190
+ */
191
+ declare function instrumentComparator<T>(comparator: Comparator<T>): InstrumentedComparator<T>;
192
+ /**
193
+ * Calculate theoretical comparison count for an insert operation.
194
+ *
195
+ * Insert performs at most ⌊log_d(n)⌋ comparisons (one per level during moveUp).
196
+ *
197
+ * @param n - Number of elements in heap AFTER insert
198
+ * @param d - Heap arity
199
+ * @returns Theoretical worst-case comparison count
200
+ */
201
+ declare function theoreticalInsertComparisons(n: number, d: number): number;
202
+ /**
203
+ * Calculate theoretical comparison count for a pop operation.
204
+ *
205
+ * Pop performs at most d × ⌊log_d(n)⌋ comparisons:
206
+ * - At each level, find best among d children (d-1 comparisons)
207
+ * - Compare best child with current (1 comparison)
208
+ * - Total: d comparisons per level × ⌊log_d(n)⌋ levels
209
+ *
210
+ * @param n - Number of elements in heap BEFORE pop
211
+ * @param d - Heap arity
212
+ * @returns Theoretical worst-case comparison count
213
+ */
214
+ declare function theoreticalPopComparisons(n: number, d: number): number;
215
+ /**
216
+ * Calculate theoretical comparison count for a decreasePriority operation.
217
+ *
218
+ * DecreasePriority in our implementation calls both moveUp and moveDown
219
+ * for safety, but typically only moveUp executes (upward movement).
220
+ * Worst case: ⌊log_d(n)⌋ comparisons.
221
+ *
222
+ * @param n - Number of elements in heap
223
+ * @param d - Heap arity
224
+ * @returns Theoretical worst-case comparison count (moveUp path)
225
+ */
226
+ declare function theoreticalDecreasePriorityComparisons(n: number, d: number): number;
227
+
1
228
  /**
2
229
  * d-ary Heap Priority Queue - TypeScript Implementation
3
230
  *
@@ -8,11 +235,13 @@
8
235
  * - O(1) access to highest-priority item
9
236
  * - O(log_d n) insert and priority increase operations
10
237
  * - O(d · log_d n) pop and priority decrease operations
238
+ * - Optional instrumentation hooks for performance analysis
11
239
  *
12
- * @version 2.1.2
240
+ * @version 2.4.0
13
241
  * @license Apache-2.0
14
242
  * @copyright 2023-2025 Eric Jacopin
15
243
  */
244
+
16
245
  /** Type alias for position indices (cross-language consistency) */
17
246
  type Position = number;
18
247
  /**
@@ -37,6 +266,35 @@ interface PriorityQueueOptions<T, K> {
37
266
  keyExtractor: KeyExtractor<T, K>;
38
267
  /** Initial capacity hint for pre-allocation */
39
268
  initialCapacity?: number;
269
+ /**
270
+ * Optional hook called before each heap operation.
271
+ *
272
+ * This enables opt-in instrumentation for performance analysis without
273
+ * adding overhead when not used. Pair with an instrumented comparator
274
+ * to track comparison counts per operation type.
275
+ *
276
+ * @param type - The operation about to be performed
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const cmp = instrumentComparator(minBy((v) => v.priority));
281
+ * const pq = new PriorityQueue({
282
+ * comparator: cmp,
283
+ * keyExtractor: (v) => v.id,
284
+ * onBeforeOperation: (op) => cmp.startOperation(op),
285
+ * onAfterOperation: () => cmp.endOperation(),
286
+ * });
287
+ * ```
288
+ *
289
+ * @see instrumentComparator from './instrumentation'
290
+ */
291
+ onBeforeOperation?: (type: OperationType) => void;
292
+ /**
293
+ * Optional hook called after each heap operation completes.
294
+ *
295
+ * @see onBeforeOperation for usage example
296
+ */
297
+ onAfterOperation?: () => void;
40
298
  }
41
299
  /**
42
300
  * Generic d-ary heap priority queue with O(1) lookup.
@@ -73,6 +331,10 @@ declare class PriorityQueue<T, K = string | number> {
73
331
  private readonly comparator;
74
332
  /** Key extractor for identity-based lookup */
75
333
  private readonly keyExtractor;
334
+ /** Optional hook called before operations (for instrumentation) */
335
+ private readonly onBeforeOperation;
336
+ /** Optional hook called after operations (for instrumentation) */
337
+ private readonly onAfterOperation;
76
338
  /**
77
339
  * Create a new d-ary heap priority queue.
78
340
  *
@@ -305,7 +567,7 @@ declare class PriorityQueue<T, K = string | number> {
305
567
  * Pre-built comparator factories for common use cases.
306
568
  *
307
569
  * @module comparators
308
- * @version 2.1.2
570
+ * @version 2.4.0
309
571
  * @license Apache-2.0
310
572
  */
311
573
 
@@ -385,4 +647,4 @@ declare function reverse<T>(cmp: Comparator<T>): Comparator<T>;
385
647
  */
386
648
  declare function chain<T>(...comparators: Comparator<T>[]): Comparator<T>;
387
649
 
388
- export { type Comparator, type KeyExtractor, type Position, PriorityQueue, type PriorityQueueOptions, chain, maxBy, maxNumber, maxString, minBy, minNumber, minString, reverse };
650
+ export { type Comparator, type ComparisonStats, type InstrumentedComparator, type KeyExtractor, type OperationType, type Position, PriorityQueue, type PriorityQueueOptions, chain, createComparisonStats, instrumentComparator, maxBy, maxNumber, maxString, minBy, minNumber, minString, reverse, theoreticalDecreasePriorityComparisons, theoreticalInsertComparisons, theoreticalPopComparisons };