list-toolkit 2.2.5 → 2.3.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/README.md +40 -36
- package/llms-full.txt +743 -0
- package/llms.txt +100 -0
- package/package.json +40 -32
- package/src/cache/cache-fifo.d.ts +6 -0
- package/src/cache/cache-fifo.js +7 -4
- package/src/cache/cache-lfu.d.ts +18 -0
- package/src/cache/cache-lfu.js +18 -6
- package/src/cache/cache-lru.d.ts +74 -0
- package/src/cache/cache-lru.js +60 -5
- package/src/cache/cache-random.d.ts +20 -0
- package/src/cache/cache-random.js +17 -6
- package/src/cache/decorator.d.ts +46 -0
- package/src/cache/decorator.js +26 -2
- package/src/cache.d.ts +13 -0
- package/src/cache.js +7 -2
- package/src/ext-list.d.ts +3 -0
- package/src/ext-list.js +0 -2
- package/src/ext-slist.d.ts +3 -0
- package/src/ext-slist.js +0 -2
- package/src/ext-value-list.d.ts +3 -0
- package/src/ext-value-list.js +0 -2
- package/src/ext-value-slist.d.ts +3 -0
- package/src/ext-value-slist.js +0 -2
- package/src/heap/basics.d.ts +89 -0
- package/src/heap/basics.js +42 -5
- package/src/heap/leftist-heap.d.ts +107 -0
- package/src/heap/leftist-heap.js +54 -2
- package/src/heap/min-heap.d.ts +270 -0
- package/src/heap/min-heap.js +186 -2
- package/src/heap/skew-heap.d.ts +105 -0
- package/src/heap/skew-heap.js +54 -2
- package/src/heap.d.ts +3 -0
- package/src/heap.js +0 -2
- package/src/list/basics.d.ts +43 -0
- package/src/list/basics.js +26 -8
- package/src/list/core.d.ts +271 -0
- package/src/list/core.js +162 -7
- package/src/list/ext-value.d.ts +253 -0
- package/src/list/ext-value.js +40 -6
- package/src/list/ext.d.ts +242 -0
- package/src/list/ext.js +148 -10
- package/src/list/nodes.d.ts +336 -0
- package/src/list/nodes.js +141 -3
- package/src/list/ptr.d.ts +72 -0
- package/src/list/ptr.js +44 -2
- package/src/list/value.d.ts +292 -0
- package/src/list/value.js +47 -6
- package/src/list-helpers.d.ts +44 -0
- package/src/list-helpers.js +36 -3
- package/src/list-utils.d.ts +141 -0
- package/src/list-utils.js +89 -3
- package/src/list.d.ts +3 -0
- package/src/list.js +0 -2
- package/src/meta-utils.d.ts +212 -0
- package/src/meta-utils.js +152 -1
- package/src/nt-utils.d.ts +91 -0
- package/src/nt-utils.js +65 -4
- package/src/queue.d.ts +74 -0
- package/src/queue.js +28 -2
- package/src/slist/basics.d.ts +47 -0
- package/src/slist/basics.js +23 -8
- package/src/slist/core.d.ts +251 -0
- package/src/slist/core.js +151 -6
- package/src/slist/ext-value.d.ts +188 -0
- package/src/slist/ext-value.js +35 -6
- package/src/slist/ext.d.ts +182 -0
- package/src/slist/ext.js +114 -12
- package/src/slist/nodes.d.ts +361 -0
- package/src/slist/nodes.js +156 -3
- package/src/slist/ptr.d.ts +73 -0
- package/src/slist/ptr.js +45 -2
- package/src/slist/value.d.ts +246 -0
- package/src/slist/value.js +38 -6
- package/src/slist.d.ts +3 -0
- package/src/slist.js +0 -2
- package/src/stack.d.ts +59 -0
- package/src/stack.js +29 -3
- package/src/tree/splay-tree.d.ts +151 -0
- package/src/tree/splay-tree.js +94 -3
- package/src/value-list.d.ts +3 -0
- package/src/value-list.js +0 -2
- package/src/value-slist.d.ts +3 -0
- package/src/value-slist.js +0 -2
- package/cjs/cache/cache-fifo.js +0 -37
- package/cjs/cache/cache-lfu.js +0 -76
- package/cjs/cache/cache-lru.js +0 -100
- package/cjs/cache/cache-random.js +0 -77
- package/cjs/cache/decorator.js +0 -47
- package/cjs/cache.js +0 -27
- package/cjs/ext-list.js +0 -21
- package/cjs/ext-slist.js +0 -21
- package/cjs/ext-value-list.js +0 -21
- package/cjs/ext-value-slist.js +0 -21
- package/cjs/heap/basics.js +0 -63
- package/cjs/heap/leftist-heap.js +0 -124
- package/cjs/heap/min-heap.js +0 -294
- package/cjs/heap/skew-heap.js +0 -114
- package/cjs/heap.js +0 -21
- package/cjs/list/basics.js +0 -88
- package/cjs/list/core.js +0 -305
- package/cjs/list/ext-value.js +0 -88
- package/cjs/list/ext.js +0 -356
- package/cjs/list/nodes.js +0 -240
- package/cjs/list/ptr.js +0 -61
- package/cjs/list/value.js +0 -99
- package/cjs/list-helpers.js +0 -91
- package/cjs/list-utils.js +0 -141
- package/cjs/list.js +0 -21
- package/cjs/meta-utils.js +0 -171
- package/cjs/nt-utils.js +0 -132
- package/cjs/package.json +0 -1
- package/cjs/queue.js +0 -58
- package/cjs/slist/basics.js +0 -71
- package/cjs/slist/core.js +0 -362
- package/cjs/slist/ext-value.js +0 -82
- package/cjs/slist/ext.js +0 -336
- package/cjs/slist/nodes.js +0 -276
- package/cjs/slist/ptr.js +0 -87
- package/cjs/slist/value.js +0 -90
- package/cjs/slist.js +0 -21
- package/cjs/stack.js +0 -55
- package/cjs/tree/splay-tree.js +0 -362
- package/cjs/value-list.js +0 -21
- package/cjs/value-slist.js +0 -21
package/llms-full.txt
ADDED
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
# list-toolkit
|
|
2
|
+
|
|
3
|
+
> A zero-dependency JavaScript library providing efficient list-based data structures: doubly and singly linked circular lists, caches, heaps, queues, stacks, splay trees, and null-terminated list utilities.
|
|
4
|
+
|
|
5
|
+
- NPM: https://npmjs.org/package/list-toolkit
|
|
6
|
+
- GitHub: https://github.com/uhop/list-toolkit
|
|
7
|
+
- Wiki: https://github.com/uhop/list-toolkit/wiki
|
|
8
|
+
- License: BSD-3-Clause
|
|
9
|
+
- Runtime: Node.js, Bun, Deno, browsers
|
|
10
|
+
- Module system: ESM (CJS supported via Node.js 22+ native ESM loader)
|
|
11
|
+
- TypeScript: built-in `.d.ts` declarations for all modules
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install list-toolkit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import ValueList from 'list-toolkit/value-list.js';
|
|
23
|
+
|
|
24
|
+
const list = ValueList.from([1, 2, 3]);
|
|
25
|
+
for (const value of list) console.log(value); // 1, 2, 3
|
|
26
|
+
|
|
27
|
+
list.pushBack(4);
|
|
28
|
+
list.pushFront(0);
|
|
29
|
+
console.log(list.popFront()); // 0
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import List from 'list-toolkit/list.js';
|
|
34
|
+
|
|
35
|
+
// Node-based: link properties added directly to your objects
|
|
36
|
+
const a = {name: 'Alice'}, b = {name: 'Bob'};
|
|
37
|
+
const people = List.from([a, b]);
|
|
38
|
+
for (const node of people) console.log(node.name); // Alice, Bob
|
|
39
|
+
|
|
40
|
+
// Custom link names allow objects in multiple lists
|
|
41
|
+
const team = List.from([a, b], {nextName: 'teamNext', prevName: 'teamPrev'});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Key concepts
|
|
47
|
+
|
|
48
|
+
- All lists are **circular** — the last node links back to the head.
|
|
49
|
+
- **Hosted lists** use a `HeadNode` sentinel. **External (headless) lists** point into an existing circular list.
|
|
50
|
+
- **Value lists** wrap values in `ValueNode` containers. **Node lists** use link properties directly on user objects.
|
|
51
|
+
- **DLL** (doubly linked) uses `nextName`/`prevName` (default: `'next'`/`'prev'`). **SLL** (singly linked) uses `nextName` (default: `'next'`).
|
|
52
|
+
- Custom link names allow the same object to participate in multiple lists simultaneously.
|
|
53
|
+
- **Pointers** (`Ptr`) provide safe iteration with insert/remove during traversal.
|
|
54
|
+
- Method aliases (e.g., `popFront` → `pop`) are created via `addAlias`/`addAliases`.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Module: List (`list-toolkit/list.js`)
|
|
59
|
+
|
|
60
|
+
Hosted node-based doubly linked circular list. Link properties are added directly to user objects.
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import List from 'list-toolkit/list.js';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Constructor
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
new List({nextName = 'next', prevName = 'prev'} = {})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Static methods
|
|
73
|
+
|
|
74
|
+
- `List.from(values, options)` — create a list from an iterable.
|
|
75
|
+
- `List.fromRange(range, options)` — create from a `{from, to}` range.
|
|
76
|
+
- `List.fromExtList(extList)` — create from an `ExtList`.
|
|
77
|
+
|
|
78
|
+
### Properties
|
|
79
|
+
|
|
80
|
+
- `isEmpty` — true if list has no nodes.
|
|
81
|
+
- `isOne` — true if list has exactly one node.
|
|
82
|
+
- `isOneOrEmpty` — true if list has zero or one node.
|
|
83
|
+
- `front` — first node.
|
|
84
|
+
- `back` — last node.
|
|
85
|
+
- `frontPtr` — `Ptr` to first node.
|
|
86
|
+
- `backPtr` — `Ptr` to last node.
|
|
87
|
+
- `range` — `{from, to, list}` or null if empty.
|
|
88
|
+
- `head` — the sentinel `HeadNode`.
|
|
89
|
+
|
|
90
|
+
### Methods
|
|
91
|
+
|
|
92
|
+
- `pushFront(value)` — add node to front. Returns `Ptr`. Alias: `push`.
|
|
93
|
+
- `pushBack(value)` — add node to back. Returns `Ptr`.
|
|
94
|
+
- `popFrontNode()` — remove and return front node. Aliases: `popFront`, `pop`.
|
|
95
|
+
- `popBackNode()` — remove and return back node. Alias: `popBack`.
|
|
96
|
+
- `pushFrontNode(nodeOrPtr)` — add existing node to front. Returns `Ptr`.
|
|
97
|
+
- `pushBackNode(nodeOrPtr)` — add existing node to back. Returns `Ptr`.
|
|
98
|
+
- `appendFront(list)` — move all nodes from another list to front.
|
|
99
|
+
- `appendBack(list)` — move all nodes from another list to back. Alias: `append`.
|
|
100
|
+
- `moveToFront(nodeOrPtr)` — move a node to front.
|
|
101
|
+
- `moveToBack(nodeOrPtr)` — move a node to back.
|
|
102
|
+
- `removeNode(nodeOrPtr)` — remove a specific node.
|
|
103
|
+
- `removeRange(range, drop)` — remove a range of nodes.
|
|
104
|
+
- `extractRange(range)` — extract a range into a new list.
|
|
105
|
+
- `extractBy(condition)` — extract nodes matching condition into a new list.
|
|
106
|
+
- `reverse()` — reverse the list in place.
|
|
107
|
+
- `sort(lessFn)` — merge sort in place. `lessFn(a, b)` returns true if a < b.
|
|
108
|
+
- `clear(drop)` — remove all nodes.
|
|
109
|
+
- `getLength()` — count nodes (O(n)).
|
|
110
|
+
- `makePtr(node)` — create a `Ptr` to a node.
|
|
111
|
+
- `validateRange(range)` — check if range is valid.
|
|
112
|
+
- `releaseRawList()` — detach nodes as a raw circular list.
|
|
113
|
+
- `releaseNTList()` — detach nodes as a null-terminated list `{head, tail}`.
|
|
114
|
+
|
|
115
|
+
### Iterators
|
|
116
|
+
|
|
117
|
+
- `[Symbol.iterator]()` — iterates over nodes.
|
|
118
|
+
- `getNodeIterator(range)` — node iterator over optional range. Alias: `getIterator`.
|
|
119
|
+
- `getPtrIterator(range)` — `Ptr` iterator (safe for insert/remove).
|
|
120
|
+
- `getReverseNodeIterator(range)` — reverse node iterator. Alias: `getReverseIterator`.
|
|
121
|
+
- `getReversePtrIterator(range)` — reverse `Ptr` iterator.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Module: ValueList (`list-toolkit/value-list.js`)
|
|
126
|
+
|
|
127
|
+
Hosted value-based doubly linked circular list. Extends `List`. Wraps values in `ValueNode` containers.
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
import ValueList from 'list-toolkit/value-list.js';
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Static methods
|
|
134
|
+
|
|
135
|
+
- `ValueList.from(values, options)` — create from iterable.
|
|
136
|
+
|
|
137
|
+
### Additional/overridden methods
|
|
138
|
+
|
|
139
|
+
- `pushFront(value)` — wraps value in `ValueNode`, adds to front.
|
|
140
|
+
- `pushBack(value)` — wraps value in `ValueNode`, adds to back.
|
|
141
|
+
- `popFront()` — remove front node, return its `.value`. Alias: `pop`.
|
|
142
|
+
- `popBack()` — remove back node, return its `.value`.
|
|
143
|
+
- `clone()` — deep clone the list.
|
|
144
|
+
|
|
145
|
+
### Iterators
|
|
146
|
+
|
|
147
|
+
- `[Symbol.iterator]()` — iterates over **values** (not nodes).
|
|
148
|
+
- `getValueIterator(range)` — value iterator. Alias: `getIterator`.
|
|
149
|
+
- `getReverseValueIterator(range)` — reverse value iterator. Alias: `getReverseIterator`.
|
|
150
|
+
- `getNodeIterator(range)` — node iterator (inherited from `List`).
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Module: SList (`list-toolkit/slist.js`)
|
|
155
|
+
|
|
156
|
+
Hosted node-based singly linked circular list. Same API pattern as `List` but without `prev` links.
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
import SList from 'list-toolkit/slist.js';
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Constructor: `new SList({nextName = 'next'} = {})`
|
|
163
|
+
|
|
164
|
+
Same methods as `List` where applicable. Key differences:
|
|
165
|
+
- `back` is O(1) via a cached `last` pointer (kept in sync by all mutations).
|
|
166
|
+
- No reverse iterators.
|
|
167
|
+
- No `popBack` — removing the last node requires traversal in an SLL.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Module: ValueSList (`list-toolkit/value-slist.js`)
|
|
172
|
+
|
|
173
|
+
Hosted value-based singly linked circular list. Extends `SList`. Same relationship as `ValueList` to `List`.
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
import ValueSList from 'list-toolkit/value-slist.js';
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Module: ExtList (`list-toolkit/ext-list.js`)
|
|
182
|
+
|
|
183
|
+
External (headless) node-based doubly linked list. Points into an existing circular list without a sentinel.
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
import ExtList from 'list-toolkit/ext-list.js';
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Constructor: `new ExtList(head = null, {nextName = 'next', prevName = 'prev'} = {})`
|
|
190
|
+
|
|
191
|
+
### Properties
|
|
192
|
+
|
|
193
|
+
- `isEmpty` — true if no head.
|
|
194
|
+
- `isOne` — true if single node.
|
|
195
|
+
- `front` — head node.
|
|
196
|
+
- `back` — node before head.
|
|
197
|
+
- `head` — current head node.
|
|
198
|
+
|
|
199
|
+
### Methods
|
|
200
|
+
|
|
201
|
+
- `attach(head)` — set head node. Returns old head.
|
|
202
|
+
- `detach()` — clear head. Returns old head.
|
|
203
|
+
- `next()` — advance head to next node.
|
|
204
|
+
- `prev()` — advance head to previous node.
|
|
205
|
+
- Plus node manipulation methods similar to `List`.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Module: ExtValueList (`list-toolkit/ext-value-list.js`)
|
|
210
|
+
|
|
211
|
+
External (headless) value-based doubly linked list.
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
import ExtValueList from 'list-toolkit/ext-value-list.js';
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Module: ExtSList (`list-toolkit/ext-slist.js`)
|
|
220
|
+
|
|
221
|
+
External (headless) node-based singly linked list.
|
|
222
|
+
|
|
223
|
+
```js
|
|
224
|
+
import ExtSList from 'list-toolkit/ext-slist.js';
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Module: ExtValueSList (`list-toolkit/ext-value-slist.js`)
|
|
230
|
+
|
|
231
|
+
External (headless) value-based singly linked list.
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
import ExtValueSList from 'list-toolkit/ext-value-slist.js';
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Module: Ptr (`list-toolkit/list/ptr.js`)
|
|
240
|
+
|
|
241
|
+
Pointer for safe DLL traversal with insert/remove during iteration.
|
|
242
|
+
|
|
243
|
+
```js
|
|
244
|
+
// Usually obtained from list methods, not imported directly
|
|
245
|
+
const ptr = list.frontPtr;
|
|
246
|
+
const ptr = list.makePtr(node);
|
|
247
|
+
for (const ptr of list.getPtrIterator()) { /* ... */ }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Properties
|
|
251
|
+
|
|
252
|
+
- `list` — the owning list.
|
|
253
|
+
- `node` — the current node.
|
|
254
|
+
- `isHead` — true if pointing at the sentinel.
|
|
255
|
+
- `nextNode` — next node.
|
|
256
|
+
- `prevNode` — previous node.
|
|
257
|
+
|
|
258
|
+
### Methods
|
|
259
|
+
|
|
260
|
+
- `next()` — advance to next node. Returns `this`.
|
|
261
|
+
- `prev()` — advance to previous node. Returns `this`.
|
|
262
|
+
- `clone()` — create a copy of this pointer.
|
|
263
|
+
- `removeCurrent()` — remove current node, advance to next. Returns removed node.
|
|
264
|
+
- `addBefore(value)` — insert value before current. Returns `Ptr` to new node.
|
|
265
|
+
- `addAfter(value)` — insert value after current. Returns `Ptr` to new node.
|
|
266
|
+
- `addNodeBefore(node)` — insert existing node before current.
|
|
267
|
+
- `addNodeAfter(node)` — insert existing node after current.
|
|
268
|
+
- `insertBefore(list)` — splice entire list before current.
|
|
269
|
+
- `insertAfter(list)` — splice entire list after current.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Module: CacheLRU (`list-toolkit/cache.js`)
|
|
274
|
+
|
|
275
|
+
Least recently used cache. Default export of `cache.js`.
|
|
276
|
+
|
|
277
|
+
```js
|
|
278
|
+
import CacheLRU from 'list-toolkit/cache.js';
|
|
279
|
+
// or: import {CacheLRU} from 'list-toolkit/cache/cache-lru.js';
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Constructor
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
new CacheLRU(capacity = 10)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Properties
|
|
289
|
+
|
|
290
|
+
- `isEmpty` — true if cache is empty.
|
|
291
|
+
- `size` — number of entries.
|
|
292
|
+
- `capacity` — maximum entries.
|
|
293
|
+
|
|
294
|
+
### Methods
|
|
295
|
+
|
|
296
|
+
- `has(key)` — check if key exists.
|
|
297
|
+
- `find(key)` — get value by key (marks as recently used). Alias: `get`.
|
|
298
|
+
- `register(key, value)` — add or update entry. Aliases: `add`, `set`.
|
|
299
|
+
- `remove(key)` — remove entry. Alias: `delete`.
|
|
300
|
+
- `clear()` — remove all entries.
|
|
301
|
+
- `[Symbol.iterator]()` — iterate over entries.
|
|
302
|
+
- `getReverseIterator()` — reverse iterator.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Module: CacheFIFO (`list-toolkit/cache/cache-fifo.js`)
|
|
307
|
+
|
|
308
|
+
First in first out cache. Same API as `CacheLRU`.
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
import {CacheFIFO} from 'list-toolkit/cache/cache-fifo.js';
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Module: CacheLFU (`list-toolkit/cache/cache-lfu.js`)
|
|
317
|
+
|
|
318
|
+
Least frequently used cache. Same API as `CacheLRU`.
|
|
319
|
+
|
|
320
|
+
```js
|
|
321
|
+
import {CacheLFU} from 'list-toolkit/cache/cache-lfu.js';
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Module: CacheRandom (`list-toolkit/cache/cache-random.js`)
|
|
327
|
+
|
|
328
|
+
Random eviction cache. Same API as `CacheLRU`.
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
import {CacheRandom} from 'list-toolkit/cache/cache-random.js';
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Module: Cache decorator (`list-toolkit/cache.js`)
|
|
337
|
+
|
|
338
|
+
Decorator to cache function/method results based on the first argument.
|
|
339
|
+
|
|
340
|
+
```js
|
|
341
|
+
import {cacheDecorator} from 'list-toolkit/cache.js';
|
|
342
|
+
import {decorateFn, decorate, decorateMethod, getCache} from 'list-toolkit/cache/decorator.js';
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
- `cacheDecorator(object, key, cache?)` — decorate a method on an object.
|
|
346
|
+
- `decorateFn(fn, cache)` — wrap a function with caching.
|
|
347
|
+
- `decorate(object, key, cache)` — decorate via property descriptor.
|
|
348
|
+
- `decorateMethod(object, key, cache)` — decorate by direct assignment.
|
|
349
|
+
- `getCache(object, key)` — retrieve the cache from a decorated property.
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Module: MinHeap (`list-toolkit/heap.js`)
|
|
354
|
+
|
|
355
|
+
Array-based binary min-heap. Default export of `heap.js`.
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
import MinHeap from 'list-toolkit/heap.js';
|
|
359
|
+
// or: import {MinHeap} from 'list-toolkit/heap/min-heap.js';
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Constructor
|
|
363
|
+
|
|
364
|
+
```js
|
|
365
|
+
new MinHeap(options?, ...initialData)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Options: `{less, equal, compare}`. If `compare` is provided, `less` is derived from it.
|
|
369
|
+
|
|
370
|
+
### Properties
|
|
371
|
+
|
|
372
|
+
- `isEmpty` — true if heap is empty.
|
|
373
|
+
- `length` — number of elements.
|
|
374
|
+
- `top` — minimum element (without removing).
|
|
375
|
+
- `array` — the underlying array.
|
|
376
|
+
|
|
377
|
+
### Instance methods
|
|
378
|
+
|
|
379
|
+
- `peek()` — alias for `top`.
|
|
380
|
+
- `push(value)` — add element. Returns `this`.
|
|
381
|
+
- `pop()` — remove and return minimum.
|
|
382
|
+
- `pushPop(value)` — push then pop (optimized).
|
|
383
|
+
- `replaceTop(value)` — replace minimum with value, re-heapify.
|
|
384
|
+
- `has(value)` — check if value exists.
|
|
385
|
+
- `findIndex(value)` — find index of value.
|
|
386
|
+
- `remove(value)` — remove a value.
|
|
387
|
+
- `removeByIndex(index)` — remove by array index.
|
|
388
|
+
- `replace(value, newValue)` — replace a value.
|
|
389
|
+
- `replaceByIndex(index, newValue)` — replace by index.
|
|
390
|
+
- `updateTop()` — re-heapify after mutating top element.
|
|
391
|
+
- `updateByIndex(index, isDecreased)` — re-heapify after mutation.
|
|
392
|
+
- `clear()` — remove all elements.
|
|
393
|
+
- `merge(...heapsOrArrays)` — merge other heaps/arrays into this one.
|
|
394
|
+
- `clone()` — shallow clone.
|
|
395
|
+
- `releaseSorted()` — extract sorted array, clear heap.
|
|
396
|
+
|
|
397
|
+
### Static methods (operate on raw arrays)
|
|
398
|
+
|
|
399
|
+
- `MinHeap.build(array, less?)` — heapify an array in place.
|
|
400
|
+
- `MinHeap.push(heapArray, item, less?)` — push to heap array.
|
|
401
|
+
- `MinHeap.pop(heapArray, less?)` — pop from heap array.
|
|
402
|
+
- `MinHeap.pushPop(heapArray, item, less?)` — push then pop.
|
|
403
|
+
- `MinHeap.replaceTop(heapArray, item, less?)` — replace top.
|
|
404
|
+
- `MinHeap.has(heapArray, item, equal?)` — check existence.
|
|
405
|
+
- `MinHeap.findIndex(heapArray, item, equal?)` — find index.
|
|
406
|
+
- `MinHeap.remove(heapArray, item, less?, equal?)` — remove item.
|
|
407
|
+
- `MinHeap.removeByIndex(heapArray, index, less?)` — remove by index.
|
|
408
|
+
- `MinHeap.replace(heapArray, item, newItem, less?, equal?)` — replace.
|
|
409
|
+
- `MinHeap.replaceByIndex(heapArray, index, newItem, less?)` — replace by index.
|
|
410
|
+
- `MinHeap.updateByIndex(heapArray, index, isDecreased, less?)` — re-heapify.
|
|
411
|
+
- `MinHeap.sort(heapArray, less?)` — heap sort in place.
|
|
412
|
+
- `MinHeap.from(array, options?)` — create heap from array.
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Module: LeftistHeap (`list-toolkit/heap/leftist-heap.js`)
|
|
417
|
+
|
|
418
|
+
Node-based merge heap using the leftist property. Efficient O(log n) merge.
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
import {LeftistHeap} from 'list-toolkit/heap/leftist-heap.js';
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Constructor
|
|
425
|
+
|
|
426
|
+
```js
|
|
427
|
+
new LeftistHeap(options?, ...heapsToMerge)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Methods
|
|
431
|
+
|
|
432
|
+
- `push(value)` — add element. Returns `this`.
|
|
433
|
+
- `pop()` — remove and return minimum.
|
|
434
|
+
- `pushPop(value)` — push then pop (optimized).
|
|
435
|
+
- `replaceTop(value)` — replace minimum.
|
|
436
|
+
- `merge(...heaps)` — merge other heaps (destructive to arguments).
|
|
437
|
+
- `clone()` — deep clone.
|
|
438
|
+
- `clear()` — remove all.
|
|
439
|
+
- `LeftistHeap.from(array, options?)` — create from array.
|
|
440
|
+
|
|
441
|
+
Properties: `isEmpty`, `length` (alias: `size`), `top`, `peek()`.
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Module: SkewHeap (`list-toolkit/heap/skew-heap.js`)
|
|
446
|
+
|
|
447
|
+
Node-based merge heap. Simpler than leftist, same asymptotic complexity (amortized).
|
|
448
|
+
|
|
449
|
+
```js
|
|
450
|
+
import {SkewHeap} from 'list-toolkit/heap/skew-heap.js';
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
Same API as `LeftistHeap`.
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Module: Queue (`list-toolkit/queue.js`)
|
|
458
|
+
|
|
459
|
+
FIFO queue adapter wrapping a `ValueList`.
|
|
460
|
+
|
|
461
|
+
```js
|
|
462
|
+
import Queue from 'list-toolkit/queue.js';
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Constructor
|
|
466
|
+
|
|
467
|
+
```js
|
|
468
|
+
new Queue(underlyingList = new ValueList())
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Properties
|
|
472
|
+
|
|
473
|
+
- `isEmpty` — true if empty.
|
|
474
|
+
- `size` — number of elements.
|
|
475
|
+
- `top` — front element value.
|
|
476
|
+
|
|
477
|
+
### Methods
|
|
478
|
+
|
|
479
|
+
- `peek()` — return front value.
|
|
480
|
+
- `add(value)` — add to back. Aliases: `push`, `pushBack`, `enqueue`.
|
|
481
|
+
- `remove()` — remove from front. Aliases: `pop`, `popFront`, `dequeue`.
|
|
482
|
+
- `addValues(values)` — add multiple values.
|
|
483
|
+
- `clear()` — remove all.
|
|
484
|
+
- `[Symbol.iterator]()` — iterate over values.
|
|
485
|
+
- `getReverseIterator()` — reverse iterator.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Module: Stack (`list-toolkit/stack.js`)
|
|
490
|
+
|
|
491
|
+
LIFO stack adapter wrapping a `ValueList`.
|
|
492
|
+
|
|
493
|
+
```js
|
|
494
|
+
import Stack from 'list-toolkit/stack.js';
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Constructor
|
|
498
|
+
|
|
499
|
+
```js
|
|
500
|
+
new Stack(UnderlyingList = ValueList)
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Properties
|
|
504
|
+
|
|
505
|
+
- `isEmpty` — true if empty.
|
|
506
|
+
- `size` — number of elements.
|
|
507
|
+
- `top` — top element value.
|
|
508
|
+
|
|
509
|
+
### Methods
|
|
510
|
+
|
|
511
|
+
- `peek()` — return top value.
|
|
512
|
+
- `push(value)` — push to top. Alias: `pushFront`.
|
|
513
|
+
- `pop()` — remove and return top value.
|
|
514
|
+
- `pushValues(values)` — push multiple values.
|
|
515
|
+
- `clear()` — remove all.
|
|
516
|
+
- `[Symbol.iterator]()` — iterate over values.
|
|
517
|
+
- `getReverseIterator()` — reverse iterator.
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## Module: SplayTree (`list-toolkit/tree/splay-tree.js`)
|
|
522
|
+
|
|
523
|
+
Self-adjusting binary search tree. Frequently accessed elements move to the root.
|
|
524
|
+
|
|
525
|
+
```js
|
|
526
|
+
import SplayTree from 'list-toolkit/tree/splay-tree.js';
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### Constructor
|
|
530
|
+
|
|
531
|
+
```js
|
|
532
|
+
new SplayTree({less?, compare?} = {})
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
If `compare` is provided, `less` is derived. Default `less`: `(a, b) => a < b`.
|
|
536
|
+
|
|
537
|
+
### Properties
|
|
538
|
+
|
|
539
|
+
- `isEmpty` — true if tree is empty.
|
|
540
|
+
- `length` (alias: `size`) — number of nodes.
|
|
541
|
+
- `root` — root `SplayTreeNode` or null.
|
|
542
|
+
|
|
543
|
+
### Methods
|
|
544
|
+
|
|
545
|
+
- `insert(value)` — insert value (no duplicates). Returns `this`.
|
|
546
|
+
- `find(value)` — find node by value. Returns `SplayTreeNode` or null.
|
|
547
|
+
- `promote(value)` — find and splay to root. Returns node or null.
|
|
548
|
+
- `splay(node)` — splay a node to root. Returns `this`.
|
|
549
|
+
- `remove(value)` — remove by value. Returns `this`.
|
|
550
|
+
- `getMin()` — return node with minimum value.
|
|
551
|
+
- `getMax()` — return node with maximum value.
|
|
552
|
+
- `splitMaxTree(value)` — split: values > value go to new tree. Returns new `SplayTree`.
|
|
553
|
+
- `join(tree)` — merge another tree into this one (destructive to argument).
|
|
554
|
+
- `clear()` — remove all nodes.
|
|
555
|
+
- `[Symbol.iterator]()` — in-order iteration over values.
|
|
556
|
+
- `getReverseIterator()` — reverse in-order iteration.
|
|
557
|
+
- `SplayTree.from(values, options?)` — create from iterable.
|
|
558
|
+
|
|
559
|
+
### SplayTreeNode
|
|
560
|
+
|
|
561
|
+
- `value` — the stored value.
|
|
562
|
+
- `left`, `right`, `parent` — child and parent pointers.
|
|
563
|
+
- `getMin()` — find minimum in subtree.
|
|
564
|
+
- `getMax()` — find maximum in subtree.
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## Module: list-utils (`list-toolkit/list-utils.js`)
|
|
569
|
+
|
|
570
|
+
Utility functions for working with lists.
|
|
571
|
+
|
|
572
|
+
```js
|
|
573
|
+
import {pushValuesFront, pushValuesBack, findNodeBy, removeNodeBy} from 'list-toolkit/list-utils.js';
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
- `isValidList(list)` — validate DLL circular structure.
|
|
577
|
+
- `isValidSList(list)` — validate SLL circular structure.
|
|
578
|
+
- `pushValuesFront(list, values)` — push multiple values to front.
|
|
579
|
+
- `pushValuesBack(list, values)` — push multiple values to back.
|
|
580
|
+
- `appendValuesFront(list, values)` — append values to front (uses `appendFront` if compatible).
|
|
581
|
+
- `appendValuesBack(list, values)` — append values to back (uses `appendBack` if compatible).
|
|
582
|
+
- `addValuesBefore(ptr, values)` — add values before pointer.
|
|
583
|
+
- `addValuesAfter(ptr, values)` — add values after pointer.
|
|
584
|
+
- `insertValuesBefore(ptr, values)` — insert values before pointer (bulk if compatible).
|
|
585
|
+
- `insertValuesAfter(ptr, values)` — insert values after pointer (bulk if compatible).
|
|
586
|
+
- `findNodeBy(list, condition)` — find first node matching condition.
|
|
587
|
+
- `findPtrBy(list, condition)` — find first `Ptr` matching condition.
|
|
588
|
+
- `removeNodeBy(list, condition)` — remove first node matching condition.
|
|
589
|
+
- `backPusher(ExtListClass, options)` — create adapter for building lists by pushing to back.
|
|
590
|
+
- `frontPusher(ExtListClass, options)` — create adapter for building lists by pushing to front.
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## Module: nt-utils (`list-toolkit/nt-utils.js`)
|
|
595
|
+
|
|
596
|
+
Utilities for null-terminated lists. Convert between NT and circular formats.
|
|
597
|
+
|
|
598
|
+
```js
|
|
599
|
+
import {makeListFromNTList, makeNTListFromList} from 'list-toolkit/nt-utils.js';
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
- `isNTList(head, {nextName?})` — check if list is null-terminated.
|
|
603
|
+
- `getNTListTail(head, {nextName?})` — find tail of NT list.
|
|
604
|
+
- `getNTListHead(node, {prevName?})` — find head of NT list (via prev links).
|
|
605
|
+
- `getNTListLength(head, {nextName?})` — count nodes in NT list.
|
|
606
|
+
- `makeListFromNTList(node, {nextName?, prevName?})` — convert NT DLL to circular. Returns `{head, tail}`.
|
|
607
|
+
- `makeSListFromNTList(head, {nextName?})` — convert NT SLL to circular. Returns `{head, tail}`.
|
|
608
|
+
- `makeNTListFromList(head, {nextName?, prevName?})` — convert circular DLL to NT. Returns `{head, tail}`.
|
|
609
|
+
- `makeNTListFromSList(head, {nextName?})` — convert circular SLL to NT. Returns `{head, tail}`.
|
|
610
|
+
- `makeNTListFromSListFast(head, {nextName?})` — fast convert (head becomes tail). Returns `{head, tail}`.
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## Module: meta-utils (`list-toolkit/meta-utils.js`)
|
|
615
|
+
|
|
616
|
+
Internal utilities used throughout the library. Also useful for extending it.
|
|
617
|
+
|
|
618
|
+
```js
|
|
619
|
+
import {addAlias, addAliases, copyOptions} from 'list-toolkit/meta-utils.js';
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
- `addAlias(object, name, aliases, force?)` — create method aliases.
|
|
623
|
+
- `addAliases(object, dict, force?)` — create multiple aliases. Dict: `{methodName: 'alias1, alias2'}`.
|
|
624
|
+
- `copyOptions(target, pattern, ...sources)` — copy known keys from sources to target.
|
|
625
|
+
- `copyDescriptors(target, source, names, force?)` — copy property descriptors.
|
|
626
|
+
- `mapIterator(iterator, callbackFn)` — map over an iterator.
|
|
627
|
+
- `normalizeIterator(iterator)` — ensure `[Symbol.iterator]` is present.
|
|
628
|
+
- Name-casing utilities: `capitalize`, `toCamelCase`, `fromCamelCase`, `toPascalCase`, `toSnakeCase`, `toKebabCase`, etc.
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Common patterns
|
|
633
|
+
|
|
634
|
+
### Creating and iterating a value list
|
|
635
|
+
|
|
636
|
+
```js
|
|
637
|
+
import ValueList from 'list-toolkit/value-list.js';
|
|
638
|
+
|
|
639
|
+
const list = ValueList.from([10, 20, 30]);
|
|
640
|
+
for (const value of list) console.log(value); // 10, 20, 30
|
|
641
|
+
|
|
642
|
+
list.pushBack(40);
|
|
643
|
+
list.pushFront(0);
|
|
644
|
+
console.log(list.popFront()); // 0
|
|
645
|
+
console.log(list.getLength()); // 4
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### Node-based list with custom link names
|
|
649
|
+
|
|
650
|
+
```js
|
|
651
|
+
import List from 'list-toolkit/list.js';
|
|
652
|
+
|
|
653
|
+
const a = {id: 1}, b = {id: 2}, c = {id: 3};
|
|
654
|
+
const list1 = List.from([a, b, c]);
|
|
655
|
+
const list2 = List.from([a, c], {nextName: 'n2', prevName: 'p2'});
|
|
656
|
+
|
|
657
|
+
// a is now in both lists simultaneously
|
|
658
|
+
for (const node of list1) console.log(node.id); // 1, 2, 3
|
|
659
|
+
for (const node of list2) console.log(node.id); // 1, 3
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Safe iteration with Ptr (insert/remove during traversal)
|
|
663
|
+
|
|
664
|
+
```js
|
|
665
|
+
import List from 'list-toolkit/list.js';
|
|
666
|
+
|
|
667
|
+
const list = List.from([{v: 1}, {v: 2}, {v: 3}, {v: 4}]);
|
|
668
|
+
for (const ptr of list.getPtrIterator()) {
|
|
669
|
+
if (ptr.node.v % 2 === 0) ptr.removeCurrent();
|
|
670
|
+
}
|
|
671
|
+
// list now contains: {v: 1}, {v: 3}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### LRU cache
|
|
675
|
+
|
|
676
|
+
```js
|
|
677
|
+
import CacheLRU from 'list-toolkit/cache.js';
|
|
678
|
+
|
|
679
|
+
const cache = new CacheLRU(100);
|
|
680
|
+
cache.set('key1', 'value1');
|
|
681
|
+
cache.set('key2', 'value2');
|
|
682
|
+
console.log(cache.get('key1')); // 'value1'
|
|
683
|
+
console.log(cache.has('key3')); // false
|
|
684
|
+
cache.delete('key2');
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Min-heap as priority queue
|
|
688
|
+
|
|
689
|
+
```js
|
|
690
|
+
import MinHeap from 'list-toolkit/heap.js';
|
|
691
|
+
|
|
692
|
+
const heap = new MinHeap();
|
|
693
|
+
heap.push(5).push(1).push(3);
|
|
694
|
+
console.log(heap.top); // 1
|
|
695
|
+
console.log(heap.pop()); // 1
|
|
696
|
+
console.log(heap.pop()); // 3
|
|
697
|
+
|
|
698
|
+
// With custom comparator
|
|
699
|
+
const maxHeap = new MinHeap({less: (a, b) => a > b});
|
|
700
|
+
maxHeap.push(1).push(5).push(3);
|
|
701
|
+
console.log(maxHeap.pop()); // 5
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Splay tree
|
|
705
|
+
|
|
706
|
+
```js
|
|
707
|
+
import SplayTree from 'list-toolkit/tree/splay-tree.js';
|
|
708
|
+
|
|
709
|
+
const tree = SplayTree.from([5, 3, 7, 1, 4]);
|
|
710
|
+
console.log(tree.find(3)?.value); // 3
|
|
711
|
+
tree.insert(6);
|
|
712
|
+
tree.remove(1);
|
|
713
|
+
for (const value of tree) console.log(value); // 3, 4, 5, 6, 7
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Queue and Stack
|
|
717
|
+
|
|
718
|
+
```js
|
|
719
|
+
import Queue from 'list-toolkit/queue.js';
|
|
720
|
+
import Stack from 'list-toolkit/stack.js';
|
|
721
|
+
|
|
722
|
+
const q = new Queue();
|
|
723
|
+
q.enqueue(1).enqueue(2).enqueue(3);
|
|
724
|
+
console.log(q.dequeue()); // 1
|
|
725
|
+
|
|
726
|
+
const s = new Stack();
|
|
727
|
+
s.push(1).push(2).push(3);
|
|
728
|
+
console.log(s.pop()); // 3
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Converting null-terminated lists
|
|
732
|
+
|
|
733
|
+
```js
|
|
734
|
+
import {makeListFromNTList, makeNTListFromList} from 'list-toolkit/nt-utils.js';
|
|
735
|
+
|
|
736
|
+
// Convert an existing NT doubly-linked list to circular
|
|
737
|
+
const head = {value: 1, next: {value: 2, next: null, prev: null}, prev: null};
|
|
738
|
+
head.next.prev = head;
|
|
739
|
+
const {head: circHead} = makeListFromNTList(head);
|
|
740
|
+
|
|
741
|
+
// Convert back
|
|
742
|
+
const {head: ntHead, tail: ntTail} = makeNTListFromList(circHead);
|
|
743
|
+
```
|