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 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
- List-based **efficient** data structures to organize your objects.
7
- This is a pure JavaScript module with no dependencies
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
- **Read all about the implemented ideas in the [Backgrounder](https://github.com/uhop/list-toolkit/wiki/Backgrounder).**
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
- All lists support similar intuitive interfaces:
19
+ Works with your existing linked lists no wrapper objects required.
42
20
 
43
- - Creating from existing objects.
44
- - Adding, inserting, extracting and removing nodes.
45
- - Forward and reverse iterators.
46
- - General manipulations like reversing and sorting.
47
- - Link names for the next and previous links (for doubly linked lists) are customizable.
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 facilities are efficient, well-debugged, and battle-tested.
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
- **All documentation is in the [wiki](https://github.com/uhop/list-toolkit/wiki).**
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
- The full documentation is available in the project's [wiki](https://github.com/uhop/list-toolkit/wiki). Below is a cheat sheet of the API.
40
+ See the [wiki](https://github.com/uhop/list-toolkit/wiki) for full documentation. Quick examples below.
62
41
 
63
- Value lists are containers for arbitrary values:
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); // Jim, Jill
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); // Jill, Jim, John, Jane
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.0",
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 '/ts-tests/test-*.*ts'",
14
- "ts-test:bun": "tape6-bun --flags FO '/ts-tests/test-*.*ts'",
15
- "ts-test:deno": "tape6-deno --flags FO '/ts-tests/test-*.*ts'",
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.10",
63
+ "nano-benchmark": "^1.0.13",
64
64
  "prettier": "^3.8.1",
65
- "tape-six": "^1.7.2",
66
- "tape-six-proc": "^1.2.3",
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-*.*js"
76
+ "/tests/test-*.js",
77
+ "/tests/test-*.mjs"
78
+ ],
79
+ "cli": [
80
+ "/tests/test-*.cjs"
77
81
  ],
78
82
  "importmap": {
79
83
  "imports": {
@@ -1,7 +1,5 @@
1
1
  import HeapBase from './basics.js';
2
2
 
3
- const defaultLess = (a, b) => a < b;
4
-
5
3
  const merge = (a, b, less) => {
6
4
  if (!a) return b;
7
5
  if (!b) return a;
@@ -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?: { prevName?: string }): T | null;
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.
@@ -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: { prevFrom: T; to: T };
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 { splice as append };
47
+ export {splice as append};
@@ -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(): { head: T; tail: T } | null;
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 { Ptr };
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
- if (!list.isCompatiblePtrRange(ptrRange)) throw new Error('"range" is not a compatible range');
473
- if (ptrRange) append(list, list, 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'
@@ -184,5 +184,5 @@ export class ExtValueSList<V = unknown> extends ExtListBase<ValueNode<V>> {
184
184
  static ValueNode: typeof ValueNode;
185
185
  }
186
186
 
187
- export { ValueNode };
187
+ export {ValueNode};
188
188
  export default ExtValueSList;
@@ -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, 'getIterator', 'getValueIterator');
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};
@@ -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(): { head: ValueNode<V>; tail: ValueNode<V> } | null;
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 { ValueNode, Ptr };
245
+ export {ValueNode, Ptr};
246
246
  export default ValueSList;