list-toolkit 2.3.0 → 2.3.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 +26 -45
- package/package.json +12 -8
- package/src/heap/leftist-heap.js +0 -2
- package/src/heap/min-heap.d.ts +1 -7
- package/src/list/ext.js +1 -1
- package/src/nt-utils.d.ts +1 -1
- package/src/slist/basics.d.ts +2 -2
- package/src/slist/core.d.ts +2 -2
- package/src/slist/core.js +7 -4
- package/src/slist/ext-value.d.ts +1 -1
- package/src/slist/ext-value.js +1 -1
- package/src/slist/ext.js +2 -2
- package/src/slist/value.d.ts +2 -2
package/README.md
CHANGED
|
@@ -3,52 +3,31 @@
|
|
|
3
3
|
[npm-img]: https://img.shields.io/npm/v/list-toolkit.svg
|
|
4
4
|
[npm-url]: https://npmjs.org/package/list-toolkit
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
suitable to use in all environments including browsers.
|
|
9
|
-
|
|
10
|
-
The toolkit provides the following data structures with a full set of efficiently implemented operations:
|
|
11
|
-
|
|
12
|
-
- Converters for `null`-terminated (NT) lists, both singly and doubly linked. They convert in place from NT lists to circular lists and back.
|
|
13
|
-
- Various lists:
|
|
14
|
-
- Doubly linked circular lists (DLL) and singly linked circular lists (SLL).
|
|
15
|
-
- Value-based lists, where a list serves as a container for external objects, and node-based lists, where a list uses custom properties on external objects to link them around.
|
|
16
|
-
- Hosted lists, which use a special head node to manage nodes, and headless lists, which point to an external list without including any headers.
|
|
17
|
-
- Heaps:
|
|
18
|
-
- Priority queues: min heap, leftist heap, skew heap.
|
|
19
|
-
- Various list-based data structures:
|
|
20
|
-
- Caches with various eviction algorithms: least recently used (LRU), least frequently used (LFU), first in first out (FIFO), and random.
|
|
21
|
-
- A decorator is provided to decorate functions, methods, and getters with a cache of your choice.
|
|
22
|
-
- Queue and Stack: adapters for lists.
|
|
23
|
-
- Trees:
|
|
24
|
-
- Splay tree: a self-adjusting binary search tree.
|
|
25
|
-
- Numerous list utilities.
|
|
26
|
-
|
|
27
|
-
All lists can be used without the toolkit. Your existing lists, either doubly or singly linked,
|
|
28
|
-
can be used. The toolkit provides a few utilities that you would write yourself if you wanted to use them.
|
|
29
|
-
|
|
30
|
-
The implementation philosophy was very simple:
|
|
31
|
-
|
|
32
|
-
- Flexibility, efficiency, and simplicity.
|
|
33
|
-
- No dependencies. No unexpected surprises.
|
|
34
|
-
- You never pay for what you don't use.
|
|
35
|
-
- Suitable for all environments.
|
|
36
|
-
- Should be usable with already existing lists.
|
|
37
|
-
- Could be used as a foundation for other list-based data structures.
|
|
6
|
+
Efficient list-based data structures for JavaScript.
|
|
7
|
+
Pure ESM, zero dependencies, works in Node.js, Bun, Deno, and browsers.
|
|
38
8
|
|
|
39
|
-
|
|
9
|
+
Data structures included:
|
|
10
|
+
|
|
11
|
+
- **Linked lists** — doubly and singly linked, circular. Node-based (link properties on your objects) or value-based (wraps values in nodes). Hosted (sentinel head) or headless (external pointer).
|
|
12
|
+
- **NT list converters** — convert null-terminated lists to/from circular lists in place.
|
|
13
|
+
- **Heaps** — min heap, leftist heap, skew heap.
|
|
14
|
+
- **Caches** — LRU, LFU, FIFO, random eviction. Includes a decorator for functions, methods, and getters.
|
|
15
|
+
- **Queue and Stack** — list-backed adapters.
|
|
16
|
+
- **Splay tree** — self-adjusting binary search tree.
|
|
17
|
+
- **Utilities** — push/append values, find, remove, validate, and more.
|
|
40
18
|
|
|
41
|
-
|
|
19
|
+
Works with your existing linked lists — no wrapper objects required.
|
|
42
20
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
|
|
21
|
+
- Flexible, efficient, simple.
|
|
22
|
+
- Zero dependencies, no surprises.
|
|
23
|
+
- Pay only for what you use.
|
|
24
|
+
- Usable as a foundation for other data structures.
|
|
25
|
+
|
|
26
|
+
**Read all about the implemented ideas in the [Backgrounder](https://github.com/uhop/list-toolkit/wiki/Backgrounder).**
|
|
48
27
|
|
|
49
|
-
All
|
|
28
|
+
All lists share a consistent API: create from iterables, push/pop, insert/extract/remove, forward and reverse iterators, sort, reverse, and customizable link names.
|
|
50
29
|
|
|
51
|
-
**
|
|
30
|
+
**Full documentation: [wiki](https://github.com/uhop/list-toolkit/wiki).**
|
|
52
31
|
|
|
53
32
|
## Installation
|
|
54
33
|
|
|
@@ -58,9 +37,9 @@ npm install list-toolkit
|
|
|
58
37
|
|
|
59
38
|
## Introduction
|
|
60
39
|
|
|
61
|
-
|
|
40
|
+
See the [wiki](https://github.com/uhop/list-toolkit/wiki) for full documentation. Quick examples below.
|
|
62
41
|
|
|
63
|
-
Value lists
|
|
42
|
+
Value lists wrap arbitrary values:
|
|
64
43
|
|
|
65
44
|
```js
|
|
66
45
|
import ValueList from 'list-toolkit/value-list.js';
|
|
@@ -130,12 +109,12 @@ for (const node of people) {
|
|
|
130
109
|
// let's extract all people from Jill to Jim
|
|
131
110
|
const ji = people.extractRange({from: jill, to: jim});
|
|
132
111
|
for (const node of people) console.log(node.name); // Jane, John
|
|
133
|
-
for (const node of ji) console.log(node.name); //
|
|
112
|
+
for (const node of ji) console.log(node.name); // Jill, Jim
|
|
134
113
|
|
|
135
114
|
// add them back:
|
|
136
115
|
people.append(ji);
|
|
137
116
|
for (const node of people.getReverseIterator()) {
|
|
138
|
-
console.log(node.name); //
|
|
117
|
+
console.log(node.name); // Jim, Jill, John, Jane
|
|
139
118
|
}
|
|
140
119
|
ji.isEmpty === true;
|
|
141
120
|
|
|
@@ -148,6 +127,8 @@ BSD 3-Clause "New" or "Revised" License. See the LICENSE file for details.
|
|
|
148
127
|
|
|
149
128
|
## Release History
|
|
150
129
|
|
|
130
|
+
- 2.3.2 _Updated dev dependencies._
|
|
131
|
+
- 2.3.1 _Bugfixes. Improved TS typing tests. Updated docs. Updated dev dependencies._
|
|
151
132
|
- 2.3.0 _Added TypeScript declarations for all modules. Added JSDoc. Removed CJS build. Bugfixes. Added missing methods._
|
|
152
133
|
- 2.2.6 _Updated dev dependencies._
|
|
153
134
|
- 2.2.5 _Updated dev dependencies._
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "list-toolkit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Zero-dependency list-based data structures: linked lists (doubly/singly linked, circular), caches (LRU, LFU, FIFO), heaps, queues, stacks, splay trees.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"lint": "prettier --check .",
|
|
11
11
|
"lint:fix": "prettier --write .",
|
|
12
12
|
"ts-check": "tsc --noEmit",
|
|
13
|
-
"ts-test": "tape6 --flags FO '/
|
|
14
|
-
"ts-test:bun": "tape6-bun --flags FO '/
|
|
15
|
-
"ts-test:deno": "tape6-deno --flags FO '/
|
|
13
|
+
"ts-test": "tape6 --flags FO '/tests/test-*.*ts'",
|
|
14
|
+
"ts-test:bun": "tape6-bun --flags FO '/tests/test-*.*ts'",
|
|
15
|
+
"ts-test:deno": "tape6-deno --flags FO '/tests/test-*.*ts'",
|
|
16
16
|
"start": "tape6-server --trace",
|
|
17
17
|
"test": "tape6 --flags FO",
|
|
18
18
|
"test:bun": "tape6-bun --flags FO",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"llms": "https://raw.githubusercontent.com/uhop/list-toolkit/master/llms.txt",
|
|
61
61
|
"llmsFull": "https://raw.githubusercontent.com/uhop/list-toolkit/master/llms-full.txt",
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"nano-benchmark": "^1.0.
|
|
63
|
+
"nano-benchmark": "^1.0.13",
|
|
64
64
|
"prettier": "^3.8.1",
|
|
65
|
-
"tape-six": "^1.7.
|
|
66
|
-
"tape-six-proc": "^1.2.
|
|
65
|
+
"tape-six": "^1.7.12",
|
|
66
|
+
"tape-six-proc": "^1.2.7",
|
|
67
67
|
"typescript": "^5.9.3"
|
|
68
68
|
},
|
|
69
69
|
"files": [
|
|
@@ -73,7 +73,11 @@
|
|
|
73
73
|
],
|
|
74
74
|
"tape6": {
|
|
75
75
|
"tests": [
|
|
76
|
-
"/tests/test
|
|
76
|
+
"/tests/test-*.js",
|
|
77
|
+
"/tests/test-*.mjs"
|
|
78
|
+
],
|
|
79
|
+
"cli": [
|
|
80
|
+
"/tests/test-*.cjs"
|
|
77
81
|
],
|
|
78
82
|
"importmap": {
|
|
79
83
|
"imports": {
|
package/src/heap/leftist-heap.js
CHANGED
package/src/heap/min-heap.d.ts
CHANGED
|
@@ -232,13 +232,7 @@ export class MinHeap<T = unknown> extends HeapBase<T> {
|
|
|
232
232
|
* @param equal - Equality function.
|
|
233
233
|
* @returns The array.
|
|
234
234
|
*/
|
|
235
|
-
static replace<T = unknown>(
|
|
236
|
-
heapArray: T[],
|
|
237
|
-
item: T,
|
|
238
|
-
newItem: T,
|
|
239
|
-
less?: (a: T, b: T) => boolean,
|
|
240
|
-
equal?: (a: T, b: T) => boolean
|
|
241
|
-
): T[];
|
|
235
|
+
static replace<T = unknown>(heapArray: T[], item: T, newItem: T, less?: (a: T, b: T) => boolean, equal?: (a: T, b: T) => boolean): T[];
|
|
242
236
|
|
|
243
237
|
/**
|
|
244
238
|
* Re-sift an element at a given index in a heap array.
|
package/src/list/ext.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ExtListBase, PtrBase} from './nodes.js';
|
|
2
2
|
import {pop, extract, splice, append} from './basics.js';
|
|
3
|
-
import {addAliases, normalizeIterator} from '../meta-utils.js';
|
|
3
|
+
import {addAliases, mapIterator, normalizeIterator} from '../meta-utils.js';
|
|
4
4
|
|
|
5
5
|
/** Pointer for navigating and mutating an external doubly linked list. */
|
|
6
6
|
export class Ptr extends PtrBase {
|
package/src/nt-utils.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export function getNTListTail<T extends object>(head: T | null, options?: NTOpti
|
|
|
40
40
|
* @param options - Link property names (uses `prevName`).
|
|
41
41
|
* @returns The head node, or `null` if empty or circular.
|
|
42
42
|
*/
|
|
43
|
-
export function getNTListHead<T extends object>(node: T | null, options?: {
|
|
43
|
+
export function getNTListHead<T extends object>(node: T | null, options?: {prevName?: string}): T | null;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Count the number of nodes in a null-terminated list.
|
package/src/slist/basics.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {SllOptions} from './nodes.js';
|
|
|
3
3
|
/** Result of extracting or popping nodes from a circular SLL. */
|
|
4
4
|
export interface SllExtractResult<T extends object> {
|
|
5
5
|
/** The extracted sub-range descriptor. */
|
|
6
|
-
extracted: {
|
|
6
|
+
extracted: {prevFrom: T; to: T};
|
|
7
7
|
/** The remaining circular list head, or `null` if nothing remains. */
|
|
8
8
|
rest: T | null;
|
|
9
9
|
}
|
|
@@ -44,4 +44,4 @@ export function splice<T extends object>(options: SllOptions, target: T, range:
|
|
|
44
44
|
/**
|
|
45
45
|
* Alias for {@link splice}.
|
|
46
46
|
*/
|
|
47
|
-
export {
|
|
47
|
+
export {splice as append};
|
package/src/slist/core.d.ts
CHANGED
|
@@ -171,7 +171,7 @@ export class SList<T extends object = object> extends HeadNode {
|
|
|
171
171
|
* Detach all nodes as a null-terminated list.
|
|
172
172
|
* @returns Object with `head` and `tail`, or `null` if empty.
|
|
173
173
|
*/
|
|
174
|
-
releaseNTList(): {
|
|
174
|
+
releaseNTList(): {head: T; tail: T} | null;
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
177
|
* Validate that a range is reachable within this list.
|
|
@@ -247,5 +247,5 @@ export class SList<T extends object = object> extends HeadNode {
|
|
|
247
247
|
static Ptr: typeof Ptr;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
export {
|
|
250
|
+
export {Ptr};
|
|
251
251
|
export default SList;
|
package/src/slist/core.js
CHANGED
|
@@ -469,8 +469,11 @@ export class SList extends HeadNode {
|
|
|
469
469
|
*/
|
|
470
470
|
static fromPtrRange(ptrRange, options) {
|
|
471
471
|
const list = new SList(options);
|
|
472
|
-
|
|
473
|
-
if (ptrRange)
|
|
472
|
+
ptrRange = list.normalizePtrRange(ptrRange);
|
|
473
|
+
if (ptrRange) {
|
|
474
|
+
append(list, list, {prevFrom: ptrRange.from.prevNode, to: ptrRange.to});
|
|
475
|
+
list.last = ptrRange.to;
|
|
476
|
+
}
|
|
474
477
|
return list;
|
|
475
478
|
}
|
|
476
479
|
|
|
@@ -487,7 +490,8 @@ export class SList extends HeadNode {
|
|
|
487
490
|
|
|
488
491
|
const range = extList.range;
|
|
489
492
|
if (range) {
|
|
490
|
-
append(list, list, range);
|
|
493
|
+
append(list, list, {prevFrom: range.to, to: range.to});
|
|
494
|
+
list.last = range.to;
|
|
491
495
|
extList.clear();
|
|
492
496
|
}
|
|
493
497
|
|
|
@@ -499,7 +503,6 @@ SList.Ptr = Ptr;
|
|
|
499
503
|
|
|
500
504
|
addAliases(SList.prototype, {
|
|
501
505
|
popFrontNode: 'popFront, pop',
|
|
502
|
-
popBackNode: 'popBack',
|
|
503
506
|
pushFront: 'push',
|
|
504
507
|
appendBack: 'append',
|
|
505
508
|
getNodeIterator: 'getIterator'
|
package/src/slist/ext-value.d.ts
CHANGED
package/src/slist/ext-value.js
CHANGED
|
@@ -97,7 +97,7 @@ export class ExtValueSList extends ExtSList {
|
|
|
97
97
|
ExtValueSList.Ptr = Ptr;
|
|
98
98
|
ExtValueSList.ValueNode = ValueNode;
|
|
99
99
|
|
|
100
|
-
addAlias(ExtValueSList.prototype, '
|
|
100
|
+
addAlias(ExtValueSList.prototype, 'getValueIterator', 'getIterator');
|
|
101
101
|
|
|
102
102
|
export {ValueNode};
|
|
103
103
|
export default ExtValueSList;
|
package/src/slist/ext.js
CHANGED
|
@@ -359,14 +359,14 @@ export class ExtSList extends ExtListBase {
|
|
|
359
359
|
* @returns {Iterable} An iterable iterator of Ptrs.
|
|
360
360
|
*/
|
|
361
361
|
getPtrIterator(ptrRange = {}) {
|
|
362
|
-
if (!ptrRange.from) ptrRange = Object.assign({from: this.makePtr()}, ptrRange);
|
|
362
|
+
if (!ptrRange.from) ptrRange = Object.assign({from: this.makePtr(this.head)}, ptrRange);
|
|
363
363
|
ptrRange = this.normalizePtrRange(ptrRange);
|
|
364
364
|
const {from: fromPtr, to} = ptrRange;
|
|
365
365
|
return {
|
|
366
366
|
[Symbol.iterator]: () => {
|
|
367
367
|
let current = fromPtr.clone(),
|
|
368
368
|
readyToStop = this.isEmpty;
|
|
369
|
-
const stop = to ? to[this.nextName] : this;
|
|
369
|
+
const stop = to ? to[this.nextName] : this.head;
|
|
370
370
|
return normalizeIterator({
|
|
371
371
|
next: () => {
|
|
372
372
|
if (readyToStop && current.node === stop) return {done: true};
|
package/src/slist/value.d.ts
CHANGED
|
@@ -165,7 +165,7 @@ export class ValueSList<V = unknown> extends HeadNode {
|
|
|
165
165
|
* Detach all nodes as a null-terminated list.
|
|
166
166
|
* @returns Object with `head` and `tail`, or `null` if empty.
|
|
167
167
|
*/
|
|
168
|
-
releaseNTList(): {
|
|
168
|
+
releaseNTList(): {head: ValueNode<V>; tail: ValueNode<V>} | null;
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
171
|
* Validate that a range is reachable within this list.
|
|
@@ -242,5 +242,5 @@ export class ValueSList<V = unknown> extends HeadNode {
|
|
|
242
242
|
static ValueNode: typeof ValueNode;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
export {
|
|
245
|
+
export {ValueNode, Ptr};
|
|
246
246
|
export default ValueSList;
|