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.
Files changed (125) hide show
  1. package/README.md +40 -36
  2. package/llms-full.txt +743 -0
  3. package/llms.txt +100 -0
  4. package/package.json +40 -32
  5. package/src/cache/cache-fifo.d.ts +6 -0
  6. package/src/cache/cache-fifo.js +7 -4
  7. package/src/cache/cache-lfu.d.ts +18 -0
  8. package/src/cache/cache-lfu.js +18 -6
  9. package/src/cache/cache-lru.d.ts +74 -0
  10. package/src/cache/cache-lru.js +60 -5
  11. package/src/cache/cache-random.d.ts +20 -0
  12. package/src/cache/cache-random.js +17 -6
  13. package/src/cache/decorator.d.ts +46 -0
  14. package/src/cache/decorator.js +26 -2
  15. package/src/cache.d.ts +13 -0
  16. package/src/cache.js +7 -2
  17. package/src/ext-list.d.ts +3 -0
  18. package/src/ext-list.js +0 -2
  19. package/src/ext-slist.d.ts +3 -0
  20. package/src/ext-slist.js +0 -2
  21. package/src/ext-value-list.d.ts +3 -0
  22. package/src/ext-value-list.js +0 -2
  23. package/src/ext-value-slist.d.ts +3 -0
  24. package/src/ext-value-slist.js +0 -2
  25. package/src/heap/basics.d.ts +89 -0
  26. package/src/heap/basics.js +42 -5
  27. package/src/heap/leftist-heap.d.ts +107 -0
  28. package/src/heap/leftist-heap.js +54 -2
  29. package/src/heap/min-heap.d.ts +270 -0
  30. package/src/heap/min-heap.js +186 -2
  31. package/src/heap/skew-heap.d.ts +105 -0
  32. package/src/heap/skew-heap.js +54 -2
  33. package/src/heap.d.ts +3 -0
  34. package/src/heap.js +0 -2
  35. package/src/list/basics.d.ts +43 -0
  36. package/src/list/basics.js +26 -8
  37. package/src/list/core.d.ts +271 -0
  38. package/src/list/core.js +162 -7
  39. package/src/list/ext-value.d.ts +253 -0
  40. package/src/list/ext-value.js +40 -6
  41. package/src/list/ext.d.ts +242 -0
  42. package/src/list/ext.js +148 -10
  43. package/src/list/nodes.d.ts +336 -0
  44. package/src/list/nodes.js +141 -3
  45. package/src/list/ptr.d.ts +72 -0
  46. package/src/list/ptr.js +44 -2
  47. package/src/list/value.d.ts +292 -0
  48. package/src/list/value.js +47 -6
  49. package/src/list-helpers.d.ts +44 -0
  50. package/src/list-helpers.js +36 -3
  51. package/src/list-utils.d.ts +141 -0
  52. package/src/list-utils.js +89 -3
  53. package/src/list.d.ts +3 -0
  54. package/src/list.js +0 -2
  55. package/src/meta-utils.d.ts +212 -0
  56. package/src/meta-utils.js +152 -1
  57. package/src/nt-utils.d.ts +91 -0
  58. package/src/nt-utils.js +65 -4
  59. package/src/queue.d.ts +74 -0
  60. package/src/queue.js +28 -2
  61. package/src/slist/basics.d.ts +47 -0
  62. package/src/slist/basics.js +23 -8
  63. package/src/slist/core.d.ts +251 -0
  64. package/src/slist/core.js +151 -6
  65. package/src/slist/ext-value.d.ts +188 -0
  66. package/src/slist/ext-value.js +35 -6
  67. package/src/slist/ext.d.ts +182 -0
  68. package/src/slist/ext.js +114 -12
  69. package/src/slist/nodes.d.ts +361 -0
  70. package/src/slist/nodes.js +156 -3
  71. package/src/slist/ptr.d.ts +73 -0
  72. package/src/slist/ptr.js +45 -2
  73. package/src/slist/value.d.ts +246 -0
  74. package/src/slist/value.js +38 -6
  75. package/src/slist.d.ts +3 -0
  76. package/src/slist.js +0 -2
  77. package/src/stack.d.ts +59 -0
  78. package/src/stack.js +29 -3
  79. package/src/tree/splay-tree.d.ts +151 -0
  80. package/src/tree/splay-tree.js +94 -3
  81. package/src/value-list.d.ts +3 -0
  82. package/src/value-list.js +0 -2
  83. package/src/value-slist.d.ts +3 -0
  84. package/src/value-slist.js +0 -2
  85. package/cjs/cache/cache-fifo.js +0 -37
  86. package/cjs/cache/cache-lfu.js +0 -76
  87. package/cjs/cache/cache-lru.js +0 -100
  88. package/cjs/cache/cache-random.js +0 -77
  89. package/cjs/cache/decorator.js +0 -47
  90. package/cjs/cache.js +0 -27
  91. package/cjs/ext-list.js +0 -21
  92. package/cjs/ext-slist.js +0 -21
  93. package/cjs/ext-value-list.js +0 -21
  94. package/cjs/ext-value-slist.js +0 -21
  95. package/cjs/heap/basics.js +0 -63
  96. package/cjs/heap/leftist-heap.js +0 -124
  97. package/cjs/heap/min-heap.js +0 -294
  98. package/cjs/heap/skew-heap.js +0 -114
  99. package/cjs/heap.js +0 -21
  100. package/cjs/list/basics.js +0 -88
  101. package/cjs/list/core.js +0 -305
  102. package/cjs/list/ext-value.js +0 -88
  103. package/cjs/list/ext.js +0 -356
  104. package/cjs/list/nodes.js +0 -240
  105. package/cjs/list/ptr.js +0 -61
  106. package/cjs/list/value.js +0 -99
  107. package/cjs/list-helpers.js +0 -91
  108. package/cjs/list-utils.js +0 -141
  109. package/cjs/list.js +0 -21
  110. package/cjs/meta-utils.js +0 -171
  111. package/cjs/nt-utils.js +0 -132
  112. package/cjs/package.json +0 -1
  113. package/cjs/queue.js +0 -58
  114. package/cjs/slist/basics.js +0 -71
  115. package/cjs/slist/core.js +0 -362
  116. package/cjs/slist/ext-value.js +0 -82
  117. package/cjs/slist/ext.js +0 -336
  118. package/cjs/slist/nodes.js +0 -276
  119. package/cjs/slist/ptr.js +0 -87
  120. package/cjs/slist/value.js +0 -90
  121. package/cjs/slist.js +0 -21
  122. package/cjs/stack.js +0 -55
  123. package/cjs/tree/splay-tree.js +0 -362
  124. package/cjs/value-list.js +0 -21
  125. package/cjs/value-slist.js +0 -21
package/src/list/core.js CHANGED
@@ -1,61 +1,105 @@
1
- 'use strict';
2
-
3
1
  import {ExtListBase, HeadNode} from './nodes.js';
4
2
  import {pop, splice, append} from './basics.js';
5
3
  import Ptr from './ptr.js';
6
4
  import {addAliases, mapIterator, normalizeIterator} from '../meta-utils.js';
7
5
 
6
+ /** Hosted node-based doubly linked list with a sentinel head. */
8
7
  export class List extends HeadNode {
8
+ /** Pointer to the first node. */
9
9
  get frontPtr() {
10
10
  return new Ptr(this, this.front);
11
11
  }
12
12
 
13
+ /** Pointer to the last node. */
13
14
  get backPtr() {
14
15
  return new Ptr(this, this.back);
15
16
  }
16
17
 
18
+ /**
19
+ * Create a pointer to a node in this list.
20
+ * @param {object} [node] - Target node, or `undefined` for the front.
21
+ * @returns {Ptr} A new Ptr.
22
+ */
17
23
  makePtr(node) {
18
24
  if (node && !this.isNodeLike(node)) throw new Error('"node" is not a compatible node');
19
25
  return new Ptr(this, node || this.front);
20
26
  }
21
27
 
28
+ /**
29
+ * Create a pointer to the node after `prev`.
30
+ * @param {object} [prev] - Preceding node, or `undefined` for the front.
31
+ * @returns {Ptr} A new Ptr.
32
+ */
22
33
  makePtrFromPrev(prev) {
23
34
  if (prev && !this.isNodeLike(prev)) throw new Error('"prev" is not a compatible node');
24
35
  return new Ptr(this, prev ? prev[this.nextName] : this.front);
25
36
  }
26
37
 
38
+ /**
39
+ * Insert a value at the front.
40
+ * @param {*} value - Node or value to insert.
41
+ * @returns {Ptr} A Ptr to the front.
42
+ */
27
43
  pushFront(value) {
28
44
  const node = this.adoptValue(value);
29
45
  splice(this, this, node);
30
46
  return this.makePtr(node);
31
47
  }
32
48
 
49
+ /**
50
+ * Insert a value at the back.
51
+ * @param {*} value - Node or value to insert.
52
+ * @returns {Ptr} A Ptr to the inserted node.
53
+ */
33
54
  pushBack(value) {
34
55
  const node = this.adoptValue(value);
35
56
  splice(this, this[this.prevName], node);
36
57
  return this.makePtr(node);
37
58
  }
38
59
 
60
+ /**
61
+ * Remove and return the front node.
62
+ * @returns {object|undefined} The removed node, or `undefined` if empty.
63
+ */
39
64
  popFrontNode() {
40
65
  if (!this.isEmpty) return pop(this, this[this.nextName]).extracted;
41
66
  }
42
67
 
68
+ /**
69
+ * Remove and return the back node.
70
+ * @returns {object|undefined} The removed node, or `undefined` if empty.
71
+ */
43
72
  popBackNode() {
44
73
  if (!this.isEmpty) return pop(this, this[this.prevName]).extracted;
45
74
  }
46
75
 
76
+ /**
77
+ * Insert an existing node at the front.
78
+ * @param {object} nodeOrPtr - Node or pointer to insert.
79
+ * @returns {Ptr} A Ptr to the front.
80
+ */
47
81
  pushFrontNode(nodeOrPtr) {
48
82
  const node = this.adoptNode(nodeOrPtr);
49
83
  splice(this, this, node);
50
84
  return this.makePtr(node);
51
85
  }
52
86
 
87
+ /**
88
+ * Insert an existing node at the back.
89
+ * @param {object} nodeOrPtr - Node or pointer to insert.
90
+ * @returns {Ptr} A Ptr to the inserted node.
91
+ */
53
92
  pushBackNode(nodeOrPtr) {
54
93
  const node = this.adoptNode(nodeOrPtr);
55
94
  splice(this, this[this.prevName], node);
56
95
  return this.makePtr(node);
57
96
  }
58
97
 
98
+ /**
99
+ * Move all nodes from another list to the front.
100
+ * @param {HeadNode} list - Compatible list to consume.
101
+ * @returns {Ptr} A Ptr to the new front.
102
+ */
59
103
  appendFront(list) {
60
104
  if (!this.isCompatible(list)) throw new Error('Incompatible lists');
61
105
  if (list.isEmpty) return this;
@@ -66,6 +110,11 @@ export class List extends HeadNode {
66
110
  return this.makePtr();
67
111
  }
68
112
 
113
+ /**
114
+ * Move all nodes from another list to the back.
115
+ * @param {HeadNode} list - Compatible list to consume.
116
+ * @returns {Ptr} A Ptr to the first appended node.
117
+ */
69
118
  appendBack(list) {
70
119
  if (!this.isCompatible(list)) throw new Error('Incompatible lists');
71
120
  if (list.isEmpty) return this;
@@ -76,6 +125,11 @@ export class List extends HeadNode {
76
125
  return this.makePtr(head);
77
126
  }
78
127
 
128
+ /**
129
+ * Move a node to the front.
130
+ * @param {object} nodeOrPtr - Node or pointer to move.
131
+ * @returns {Ptr} A Ptr to the front.
132
+ */
79
133
  moveToFront(nodeOrPtr) {
80
134
  const node = this.normalizeNode(nodeOrPtr);
81
135
  if (this[this.nextName] !== node) {
@@ -84,6 +138,11 @@ export class List extends HeadNode {
84
138
  return this.frontPtr;
85
139
  }
86
140
 
141
+ /**
142
+ * Move a node to the back.
143
+ * @param {object} nodeOrPtr - Node or pointer to move.
144
+ * @returns {Ptr} A Ptr to the back.
145
+ */
87
146
  moveToBack(nodeOrPtr) {
88
147
  const node = this.normalizeNode(nodeOrPtr);
89
148
  if (this[this.prevName] !== node) {
@@ -92,6 +151,11 @@ export class List extends HeadNode {
92
151
  return this.backPtr;
93
152
  }
94
153
 
154
+ /**
155
+ * Remove all nodes.
156
+ * @param {boolean} [drop] - If `true`, make each removed node stand-alone.
157
+ * @returns {List} `this` for chaining.
158
+ */
95
159
  clear(drop) {
96
160
  if (drop) {
97
161
  while (!this.isEmpty) this.popFrontNode();
@@ -101,14 +165,30 @@ export class List extends HeadNode {
101
165
  return this;
102
166
  }
103
167
 
168
+ /**
169
+ * Remove a node from the list.
170
+ * @param {object} nodeOrPtr - Node or pointer to remove.
171
+ * @returns {object} The removed node.
172
+ */
104
173
  removeNode(nodeOrPtr) {
105
174
  return pop(this, this.normalizeNode(nodeOrPtr)).extracted;
106
175
  }
107
176
 
177
+ /**
178
+ * Remove a range and optionally drop nodes.
179
+ * @param {object} [range] - Range to remove.
180
+ * @param {boolean} [drop] - If `true`, make each removed node stand-alone.
181
+ * @returns {List} A new List containing the removed nodes.
182
+ */
108
183
  removeRange(range, drop) {
109
184
  return this.extractRange(range).clear(drop);
110
185
  }
111
186
 
187
+ /**
188
+ * Extract a range into a new list.
189
+ * @param {object} [range={}] - Range to extract (defaults to the whole list).
190
+ * @returns {List} A new List containing the extracted nodes.
191
+ */
112
192
  extractRange(range = {}) {
113
193
  range = this.normalizeRange(range);
114
194
  range.from ||= this.front;
@@ -116,11 +196,16 @@ export class List extends HeadNode {
116
196
  return append(this, this.make(), range);
117
197
  }
118
198
 
199
+ /**
200
+ * Extract nodes that satisfy a condition into a new list.
201
+ * @param {Function} condition - Predicate receiving each node.
202
+ * @returns {List} A new List containing the extracted nodes.
203
+ */
119
204
  extractBy(condition) {
120
205
  const extracted = this.make();
121
206
  if (this.isEmpty) return extracted;
122
207
 
123
- while (this.isEmpty && condition(this.front)) extracted.pushBack(this.popFront());
208
+ while (!this.isEmpty && condition(this.front)) extracted.pushBack(this.popFrontNode());
124
209
  if (this.isOneOrEmpty) return extracted;
125
210
 
126
211
  for (const ptr of this.getPtrIterator({from: this.front[this.nextName]})) {
@@ -130,6 +215,10 @@ export class List extends HeadNode {
130
215
  return extracted;
131
216
  }
132
217
 
218
+ /**
219
+ * Reverse the order of all nodes in place.
220
+ * @returns {List} `this` for chaining.
221
+ */
133
222
  reverse() {
134
223
  let current = this;
135
224
  do {
@@ -141,6 +230,11 @@ export class List extends HeadNode {
141
230
  return this;
142
231
  }
143
232
 
233
+ /**
234
+ * Sort nodes in place using merge sort.
235
+ * @param {Function} lessFn - Returns `true` if `a` should precede `b`.
236
+ * @returns {List} `this` for chaining.
237
+ */
144
238
  sort(lessFn) {
145
239
  if (this.isOneOrEmpty) return this;
146
240
 
@@ -167,10 +261,18 @@ export class List extends HeadNode {
167
261
  return this;
168
262
  }
169
263
 
264
+ /**
265
+ * Detach all nodes as a raw circular list.
266
+ * @returns {object|null} Head of the raw circular list, or `null` if empty.
267
+ */
170
268
  releaseRawList() {
171
269
  return this.isEmpty ? null : pop(this, this).rest;
172
270
  }
173
271
 
272
+ /**
273
+ * Detach all nodes as a null-terminated list.
274
+ * @returns {{head: object, tail: object}|null} Object with `head` and `tail`, or `null` if empty.
275
+ */
174
276
  releaseNTList() {
175
277
  if (this.isEmpty) return null;
176
278
  const head = this[this.nextName],
@@ -180,6 +282,11 @@ export class List extends HeadNode {
180
282
  return {head, tail};
181
283
  }
182
284
 
285
+ /**
286
+ * Validate that a range is reachable within this list.
287
+ * @param {object} [range={}] - Range to validate.
288
+ * @returns {boolean} `true` if the range is valid.
289
+ */
183
290
  validateRange(range = {}) {
184
291
  range = this.normalizeRange(range);
185
292
  let current = range.from;
@@ -190,8 +297,7 @@ export class List extends HeadNode {
190
297
  return true;
191
298
  }
192
299
 
193
- // iterators
194
-
300
+ /** Iterate over nodes from front to back. */
195
301
  [Symbol.iterator]() {
196
302
  let current = this[this.nextName],
197
303
  readyToStop = this.isEmpty;
@@ -206,6 +312,11 @@ export class List extends HeadNode {
206
312
  });
207
313
  }
208
314
 
315
+ /**
316
+ * Get an iterable over nodes in a range.
317
+ * @param {object} [range={}] - Sub-range to iterate.
318
+ * @returns {Iterable} An iterable iterator of nodes.
319
+ */
209
320
  getNodeIterator(range = {}) {
210
321
  range = this.normalizeRange(range);
211
322
  const {from, to} = range;
@@ -227,10 +338,20 @@ export class List extends HeadNode {
227
338
  };
228
339
  }
229
340
 
341
+ /**
342
+ * Get an iterable of Ptr objects over a range.
343
+ * @param {object} [range] - Sub-range to iterate.
344
+ * @returns {Iterable} An iterable iterator of Ptrs.
345
+ */
230
346
  getPtrIterator(range) {
231
347
  return mapIterator(this.getNodeIterator(range), node => new Ptr(this, node));
232
348
  }
233
349
 
350
+ /**
351
+ * Get an iterable over nodes in reverse order.
352
+ * @param {object} [range={}] - Sub-range to iterate.
353
+ * @returns {Iterable} An iterable iterator of nodes.
354
+ */
234
355
  getReverseNodeIterator(range = {}) {
235
356
  range = this.normalizeRange(range);
236
357
  const {from, to} = range;
@@ -252,30 +373,59 @@ export class List extends HeadNode {
252
373
  };
253
374
  }
254
375
 
376
+ /**
377
+ * Get an iterable of Ptr objects in reverse order.
378
+ * @param {object} [range] - Sub-range to iterate.
379
+ * @returns {Iterable} An iterable iterator of Ptrs.
380
+ */
255
381
  getReversePtrIterator(range) {
256
382
  return mapIterator(this.getReverseNodeIterator(range), node => new Ptr(this, node));
257
383
  }
258
384
 
259
- // meta helpers
260
-
385
+ /**
386
+ * Create an empty list with the same options.
387
+ * @returns {List} A new empty List.
388
+ */
261
389
  make() {
262
390
  return new List(this);
263
391
  }
264
392
 
393
+ /**
394
+ * Create a list from values with the same options.
395
+ * @param {Iterable} values - Iterable of node objects.
396
+ * @returns {List} A new List.
397
+ */
265
398
  makeFrom(values) {
266
399
  return List.from(values, this);
267
400
  }
268
401
 
402
+ /**
403
+ * Create a list from a range with the same options.
404
+ * @param {object} range - Range to copy.
405
+ * @returns {List} A new List.
406
+ */
269
407
  makeFromRange(range) {
270
408
  return List.fromRange(range, this);
271
409
  }
272
410
 
411
+ /**
412
+ * Build a List from an iterable of node objects.
413
+ * @param {Iterable} values - Iterable of nodes.
414
+ * @param {object} [options] - Link property names.
415
+ * @returns {List} A new List.
416
+ */
273
417
  static from(values, options) {
274
418
  const list = new List(options);
275
419
  for (const value of values) list.pushBack(value);
276
420
  return list;
277
421
  }
278
422
 
423
+ /**
424
+ * Build a List from a range.
425
+ * @param {object} range - Range to copy.
426
+ * @param {object} [options] - Link property names.
427
+ * @returns {List} A new List.
428
+ */
279
429
  static fromRange(range, options) {
280
430
  const list = new List(options);
281
431
  if (!range) return list;
@@ -286,6 +436,11 @@ export class List extends HeadNode {
286
436
  return append(list, list, range);
287
437
  }
288
438
 
439
+ /**
440
+ * Build a List from an external list, consuming it.
441
+ * @param {ExtListBase} extList - External list to consume.
442
+ * @returns {List} A new List.
443
+ */
289
444
  static fromExtList(extList) {
290
445
  if (!(extList instanceof ExtListBase)) throw new Error('Not a circular list');
291
446
 
@@ -0,0 +1,253 @@
1
+ import {ExtListBase, ValueNode, PtrBase, DllOptions, DllRange} from './nodes.js';
2
+ import {Ptr} from './ext.js';
3
+
4
+ /**
5
+ * External (headless) value-based doubly linked list. Wraps values in {@link ValueNode}.
6
+ *
7
+ * Extends `ExtList` at runtime. Internally nodes are `ValueNode<V>`.
8
+ * The default iterator and `getIterator`/`getReverseIterator` yield
9
+ * unwrapped `V` values; use `getNodeIterator`/`getReverseNodeIterator`
10
+ * for `ValueNode<V>` nodes.
11
+ */
12
+ export class ExtValueList<V = unknown> extends ExtListBase<ValueNode<V>> {
13
+ /**
14
+ * Create a pointer to a node in this list.
15
+ * @param node - Target node, or `undefined` for the head.
16
+ * @returns A new Ptr, or `null` if the list is empty and no node given.
17
+ */
18
+ makePtr(node?: ValueNode<V>): Ptr<ValueNode<V>> | null;
19
+
20
+ /**
21
+ * Create a pointer to the node after `prev`.
22
+ * @param prev - Preceding node, or `undefined` for the front.
23
+ * @returns A new Ptr.
24
+ */
25
+ makePtrFromPrev(prev?: ValueNode<V>): Ptr<ValueNode<V>>;
26
+
27
+ /**
28
+ * Remove the current head node and advance to the next.
29
+ * @returns The removed node, or `null` if empty.
30
+ */
31
+ removeCurrent(): ValueNode<V> | null;
32
+
33
+ /**
34
+ * Remove the node before the head.
35
+ * @returns The removed node, or `null` if empty.
36
+ */
37
+ removeNodeBefore(): ValueNode<V> | null;
38
+
39
+ /** Alias for {@link removeNodeBefore}. */
40
+ removeBefore(): ValueNode<V> | null;
41
+
42
+ /**
43
+ * Remove the node after the head.
44
+ * @returns The removed node, or `null` if empty.
45
+ */
46
+ removeNodeAfter(): ValueNode<V> | null;
47
+
48
+ /** Alias for {@link removeNodeAfter}. */
49
+ removeAfter(): ValueNode<V> | null;
50
+
51
+ /**
52
+ * Adopt a value, pointer, or ValueNode into this list.
53
+ * @param value - Raw value, Ptr, or ValueNode.
54
+ * @returns A ValueNode ready for insertion.
55
+ */
56
+ adoptValue(value: V | ValueNode<V> | PtrBase<ValueNode<V>>): ValueNode<V>;
57
+
58
+ /**
59
+ * Insert a value after the head.
60
+ * @param value - Raw value, ValueNode, or Ptr.
61
+ * @returns A Ptr to the inserted node.
62
+ */
63
+ addAfter(value: V | ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>>;
64
+
65
+ /** Alias for {@link addAfter}. */
66
+ add(value: V | ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>>;
67
+
68
+ /**
69
+ * Insert a value before the head.
70
+ * @param value - Raw value, ValueNode, or Ptr.
71
+ * @returns A Ptr to the inserted node.
72
+ */
73
+ addBefore(value: V | ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>>;
74
+
75
+ /**
76
+ * Insert an existing node before the head.
77
+ * @param nodeOrPtr - ValueNode or pointer to insert.
78
+ * @returns A Ptr to the inserted node.
79
+ */
80
+ addNodeBefore(nodeOrPtr: ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>>;
81
+
82
+ /**
83
+ * Insert an existing node after the head.
84
+ * @param nodeOrPtr - ValueNode or pointer to insert.
85
+ * @returns A Ptr to the inserted node.
86
+ */
87
+ addNodeAfter(nodeOrPtr: ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>>;
88
+
89
+ /**
90
+ * Splice another list's nodes before the head.
91
+ * @param extList - Compatible external list to consume.
92
+ * @returns A Ptr to the first inserted node, or `null` if empty.
93
+ */
94
+ insertBefore(extList: ExtValueList<V>): Ptr<ValueNode<V>> | null;
95
+
96
+ /**
97
+ * Splice another list's nodes after the head.
98
+ * @param extList - Compatible external list to consume.
99
+ * @returns A Ptr to the first inserted node, or `null` if empty.
100
+ */
101
+ insertAfter(extList: ExtValueList<V>): Ptr<ValueNode<V>> | null;
102
+
103
+ /**
104
+ * Move a node to just before the head.
105
+ * @param nodeOrPtr - Node or pointer to move.
106
+ * @returns A Ptr to the moved node, or `this` if already at head.
107
+ */
108
+ moveBefore(nodeOrPtr: ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>> | this;
109
+
110
+ /**
111
+ * Move a node to just after the head.
112
+ * @param nodeOrPtr - Node or pointer to move.
113
+ * @returns A Ptr to the moved node, or `this` if already at head.
114
+ */
115
+ moveAfter(nodeOrPtr: ValueNode<V> | PtrBase<ValueNode<V>>): Ptr<ValueNode<V>> | this;
116
+
117
+ /**
118
+ * Remove all nodes.
119
+ * @param drop - If `true`, make each removed node stand-alone.
120
+ * @returns `this` for chaining.
121
+ */
122
+ clear(drop?: boolean): this;
123
+
124
+ /**
125
+ * Remove a single node from the list.
126
+ * @param nodeOrPtr - Node or pointer to remove.
127
+ * @returns The removed node, or `null` if empty.
128
+ */
129
+ removeNode(nodeOrPtr: ValueNode<V> | PtrBase<ValueNode<V>>): ValueNode<V> | null;
130
+
131
+ /**
132
+ * Remove a range of nodes and optionally drop them.
133
+ * @param range - Range to remove.
134
+ * @param drop - If `true`, make each removed node stand-alone.
135
+ * @returns A new ExtValueList containing the removed values.
136
+ */
137
+ removeRange(range?: DllRange<ValueNode<V>>, drop?: boolean): ExtValueList<V>;
138
+
139
+ /**
140
+ * Extract a range of nodes into a new list.
141
+ * @param range - Range to extract (defaults to the whole list).
142
+ * @returns A new ExtValueList containing the extracted values.
143
+ */
144
+ extractRange(range?: DllRange<ValueNode<V>>): ExtValueList<V>;
145
+
146
+ /**
147
+ * Extract nodes that satisfy a condition into a new list.
148
+ * @param condition - Predicate receiving each ValueNode.
149
+ * @returns A new ExtValueList containing the extracted values.
150
+ */
151
+ extractBy(condition: (node: ValueNode<V>) => boolean): ExtValueList<V>;
152
+
153
+ /**
154
+ * Reverse the order of all nodes in place.
155
+ * @returns `this` for chaining.
156
+ */
157
+ reverse(): this;
158
+
159
+ /**
160
+ * Sort nodes in place using merge sort.
161
+ * @param lessFn - Comparison receiving ValueNodes, returns `true` if `a` should precede `b`.
162
+ * @returns `this` for chaining.
163
+ */
164
+ sort(lessFn: (a: ValueNode<V>, b: ValueNode<V>) => boolean): this;
165
+
166
+ /** Iterate over unwrapped values starting from the head. */
167
+ [Symbol.iterator](): IterableIterator<V>;
168
+
169
+ /**
170
+ * Get an iterable over ValueNodes in a range.
171
+ * @param range - Sub-range to iterate.
172
+ * @returns An iterable iterator of ValueNodes.
173
+ */
174
+ getNodeIterator(range?: DllRange<ValueNode<V>>): IterableIterator<ValueNode<V>>;
175
+
176
+ /**
177
+ * Get an iterable over unwrapped values in a range.
178
+ * @param range - Sub-range to iterate.
179
+ * @returns An iterable iterator of values.
180
+ */
181
+ getValueIterator(range?: DllRange<ValueNode<V>>): IterableIterator<V>;
182
+
183
+ /** Alias for {@link getValueIterator}. */
184
+ getIterator(range?: DllRange<ValueNode<V>>): IterableIterator<V>;
185
+
186
+ /**
187
+ * Get an iterable over ValueNodes in reverse order.
188
+ * @param range - Sub-range to iterate.
189
+ * @returns An iterable iterator of ValueNodes.
190
+ */
191
+ getReverseNodeIterator(range?: DllRange<ValueNode<V>>): IterableIterator<ValueNode<V>>;
192
+
193
+ /**
194
+ * Get an iterable over unwrapped values in reverse order.
195
+ * @param range - Sub-range to iterate.
196
+ * @returns An iterable iterator of values.
197
+ */
198
+ getReverseValueIterator(range?: DllRange<ValueNode<V>>): IterableIterator<V>;
199
+
200
+ /** Alias for {@link getReverseValueIterator}. */
201
+ getReverseIterator(range?: DllRange<ValueNode<V>>): IterableIterator<V>;
202
+
203
+ /**
204
+ * Get an iterable of Ptr objects over a range.
205
+ * @param range - Sub-range to iterate.
206
+ * @returns An iterable iterator of Ptrs.
207
+ */
208
+ getPtrIterator(range?: DllRange<ValueNode<V>>): IterableIterator<Ptr<ValueNode<V>>>;
209
+
210
+ /**
211
+ * Get an iterable of Ptr objects in reverse order.
212
+ * @param range - Sub-range to iterate.
213
+ * @returns An iterable iterator of Ptrs.
214
+ */
215
+ getReversePtrIterator(range?: DllRange<ValueNode<V>>): IterableIterator<Ptr<ValueNode<V>>>;
216
+
217
+ /**
218
+ * Create a shallow clone of this list.
219
+ * @returns A new ExtValueList pointing to the same head.
220
+ */
221
+ clone(): ExtValueList<V>;
222
+
223
+ /**
224
+ * Create an empty list with the same options.
225
+ * @param head - Optional initial head node.
226
+ * @returns A new ExtValueList.
227
+ */
228
+ make(head?: ValueNode<V> | null): ExtValueList<V>;
229
+
230
+ /**
231
+ * Create a list from values with the same options.
232
+ * @param values - Iterable of values.
233
+ * @returns A new ExtValueList.
234
+ */
235
+ makeFrom(values: Iterable<V>): ExtValueList<V>;
236
+
237
+ /**
238
+ * Build an ExtValueList from an iterable.
239
+ * @param values - Iterable of values.
240
+ * @param options - Link property names.
241
+ * @returns A new ExtValueList.
242
+ */
243
+ static from<V = unknown>(values: Iterable<V>, options?: DllOptions): ExtValueList<V>;
244
+
245
+ /** The Ptr class associated with this list type. */
246
+ static Ptr: typeof Ptr;
247
+
248
+ /** The ValueNode class used by this list type. */
249
+ static ValueNode: typeof ValueNode;
250
+ }
251
+
252
+ export {ValueNode};
253
+ export default ExtValueList;
@@ -1,10 +1,17 @@
1
- 'use strict';
2
-
3
1
  import ExtList, {Ptr} from './ext.js';
4
2
  import {ValueNode} from './nodes.js';
5
3
  import {addAliases, mapIterator, normalizeIterator} from '../meta-utils.js';
6
4
 
5
+ /**
6
+ * External (headless) value-based doubly linked list. Wraps values in {@link ValueNode}.
7
+ * Iterators yield unwrapped values; use `getNodeIterator` for ValueNode access.
8
+ */
7
9
  export class ExtValueList extends ExtList {
10
+ /**
11
+ * Adopt a value, pointer, or ValueNode into this list.
12
+ * @param {*} value - Raw value, Ptr, or ValueNode.
13
+ * @returns {ValueNode} A ValueNode ready for insertion.
14
+ */
8
15
  adoptValue(value) {
9
16
  if (value instanceof Ptr) {
10
17
  if (!this.isCompatiblePtr(value)) throw new Error('Incompatible pointer');
@@ -21,8 +28,7 @@ export class ExtValueList extends ExtList {
21
28
  return new ValueNode(value, this);
22
29
  }
23
30
 
24
- // iterators
25
-
31
+ /** Iterate over unwrapped values starting from the head. */
26
32
  [Symbol.iterator]() {
27
33
  let current = this.head,
28
34
  readyToStop = this.isEmpty;
@@ -37,28 +43,56 @@ export class ExtValueList extends ExtList {
37
43
  });
38
44
  }
39
45
 
46
+ /**
47
+ * Get an iterable over unwrapped values in a range.
48
+ * @param {object} [range] - Sub-range to iterate.
49
+ * @returns {Iterable} An iterable iterator of values.
50
+ */
40
51
  getValueIterator(range) {
41
52
  return mapIterator(this.getNodeIterator(range), node => node.value);
42
53
  }
43
54
 
55
+ /**
56
+ * Get an iterable over unwrapped values in reverse order.
57
+ * @param {object} [range] - Sub-range to iterate.
58
+ * @returns {Iterable} An iterable iterator of values.
59
+ */
44
60
  getReverseValueIterator(range) {
45
61
  return mapIterator(this.getReverseNodeIterator(range), node => node.value);
46
62
  }
47
63
 
48
- // meta helpers
49
-
64
+ /**
65
+ * Create a shallow clone of this list.
66
+ * @returns {ExtValueList} A new ExtValueList pointing to the same head.
67
+ */
50
68
  clone() {
51
69
  return new ExtValueList(this);
52
70
  }
53
71
 
72
+ /**
73
+ * Create an empty list with the same options.
74
+ * @param {object|null} [head=null] - Optional initial head node.
75
+ * @returns {ExtValueList} A new ExtValueList.
76
+ */
54
77
  make(head = null) {
55
78
  return new ExtValueList(head, this);
56
79
  }
57
80
 
81
+ /**
82
+ * Create a list from values with the same options.
83
+ * @param {Iterable} values - Iterable of values.
84
+ * @returns {ExtValueList} A new ExtValueList.
85
+ */
58
86
  makeFrom(values) {
59
87
  return ExtValueList.from(values, this);
60
88
  }
61
89
 
90
+ /**
91
+ * Build an ExtValueList from an iterable.
92
+ * @param {Iterable} values - Iterable of values.
93
+ * @param {object} [options] - Link property names.
94
+ * @returns {ExtValueList} A new ExtValueList.
95
+ */
62
96
  static from(values, options) {
63
97
  const list = new ExtValueList(null, options);
64
98
  for (const value of values) {