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/meta-utils.js CHANGED
@@ -1,32 +1,107 @@
1
+ /**
2
+ * Capitalize the first letter of a string.
3
+ * @param {string} name - Input string.
4
+ * @returns {string} The capitalized string.
5
+ */
1
6
  export const capitalize = name => (name ? name[0].toUpperCase() + name.substring(1).toLowerCase() : name);
2
7
 
8
+ /**
9
+ * Convert an array of name parts to camelCase.
10
+ * @param {string[]} names - Name parts.
11
+ * @returns {string} The camelCase string.
12
+ */
3
13
  export const toCamelCase = names => names.map((name, index) => (index ? capitalize(name) : name.toLowerCase())).join('');
14
+
15
+ /**
16
+ * Split a camelCase string into parts.
17
+ * @param {string} name - camelCase string.
18
+ * @returns {string[]} Array of name parts.
19
+ */
4
20
  export const fromCamelCase = name => name.split(/(?=[A-Z])/g);
5
21
 
22
+ /**
23
+ * Convert an array of name parts to PascalCase.
24
+ * @param {string[]} names - Name parts.
25
+ * @returns {string} The PascalCase string.
26
+ */
6
27
  export const toPascalCase = names => names.map(name => capitalize(name)).join('');
28
+
29
+ /**
30
+ * Split a PascalCase string into parts.
31
+ * @param {string} name - PascalCase string.
32
+ * @returns {string[]} Array of name parts.
33
+ */
7
34
  export const fromPascalCase = name => name.split(/(?=[A-Z])/g);
8
35
 
36
+ /**
37
+ * Convert an array of name parts to ALL_CAPS_SNAKE_CASE.
38
+ * @param {string[]} names - Name parts.
39
+ * @returns {string} The ALL_CAPS_SNAKE_CASE string.
40
+ */
9
41
  export const toAllCapsSnakeCase = names => names.map(name => name.toUpperCase()).join('_');
42
+
43
+ /**
44
+ * Convert an array of name parts to snake_case.
45
+ * @param {string[]} names - Name parts.
46
+ * @returns {string} The snake_case string.
47
+ */
10
48
  export const toSnakeCase = names => names.map(name => name.toLowerCase()).join('_');
49
+
50
+ /**
51
+ * Split a snake_case string into parts.
52
+ * @param {string} name - snake_case string.
53
+ * @returns {string[]} Array of name parts.
54
+ */
11
55
  export const fromSnakeCase = name => name.split('_');
12
56
 
57
+ /**
58
+ * Convert an array of name parts to kebab-case.
59
+ * @param {string[]} names - Name parts.
60
+ * @returns {string} The kebab-case string.
61
+ */
13
62
  export const toKebabCase = names => names.map(name => name.toLowerCase()).join('-');
63
+
64
+ /**
65
+ * Split a kebab-case string into parts.
66
+ * @param {string} name - kebab-case string.
67
+ * @returns {string[]} Array of name parts.
68
+ */
14
69
  export const fromKebabCase = name => name.split('-');
15
70
 
71
+ /** @type {PropertyDescriptor} Default property descriptor: configurable and enumerable. */
16
72
  export const defaultDescriptor = {configurable: true, enumerable: true};
17
73
 
74
+ /**
75
+ * Create a property descriptor from a getter function.
76
+ * @param {Function} [getter] - Getter function.
77
+ * @param {PropertyDescriptor} [defaultDescriptor] - Base descriptor to extend.
78
+ * @returns {PropertyDescriptor} A property descriptor with `get`.
79
+ */
18
80
  export const fromGetter = (getter, defaultDescriptor = defaultDescriptor) => {
19
81
  const descriptor = {...defaultDescriptor};
20
82
  if (typeof getter == 'function') descriptor.get = getter;
21
83
  return descriptor;
22
84
  };
23
85
 
86
+ /**
87
+ * Create a property descriptor from a setter function.
88
+ * @param {Function} [setter] - Setter function.
89
+ * @param {PropertyDescriptor} [defaultDescriptor] - Base descriptor to extend.
90
+ * @returns {PropertyDescriptor} A property descriptor with `set`.
91
+ */
24
92
  export const fromSetter = (setter, defaultDescriptor = defaultDescriptor) => {
25
93
  const descriptor = {...defaultDescriptor};
26
94
  if (typeof setter == 'function') descriptor.set = setter;
27
95
  return descriptor;
28
96
  };
29
97
 
98
+ /**
99
+ * Create a property descriptor from getter and setter functions.
100
+ * @param {Function} [getter] - Getter function.
101
+ * @param {Function} [setter] - Setter function.
102
+ * @param {PropertyDescriptor} [defaultDescriptor] - Base descriptor to extend.
103
+ * @returns {PropertyDescriptor} A property descriptor with `get` and/or `set`.
104
+ */
30
105
  export const fromAccessors = (getter, setter, defaultDescriptor = defaultDescriptor) => {
31
106
  const descriptor = {...defaultDescriptor};
32
107
  if (typeof getter == 'function') descriptor.get = getter;
@@ -34,6 +109,14 @@ export const fromAccessors = (getter, setter, defaultDescriptor = defaultDescrip
34
109
  return descriptor;
35
110
  };
36
111
 
112
+ /**
113
+ * Define a property descriptor on a target for one or more names.
114
+ * @param {object} target - Object to define properties on.
115
+ * @param {string|PropertyKey[]} names - Comma-separated string, array, or single name/symbol.
116
+ * @param {PropertyDescriptor} [descriptor] - Property descriptor to apply.
117
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
118
+ * @returns {object} The target object.
119
+ */
37
120
  export const addDescriptor = (target, names, descriptor, force) => {
38
121
  if (!descriptor) return target;
39
122
  if (typeof names == 'string') names = names.trim().split(/\s*,\s*/);
@@ -45,6 +128,12 @@ export const addDescriptor = (target, names, descriptor, force) => {
45
128
  return target;
46
129
  };
47
130
 
131
+ /**
132
+ * Define multiple property descriptors on a target.
133
+ * @param {object} target - Object to define properties on.
134
+ * @param {Object<string, PropertyDescriptor>} dict - Map of comma-separated names to descriptors.
135
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
136
+ */
48
137
  export const addDescriptors = (target, dict, force) => {
49
138
  for (const [names, descriptor] of Object.entries(dict)) {
50
139
  addDescriptor(target, names, descriptor, force);
@@ -56,19 +145,42 @@ export const addDescriptors = (target, dict, force) => {
56
145
  }
57
146
  };
58
147
 
148
+ /**
149
+ * Define an accessor (getter/setter) on a target.
150
+ * @param {object} target - Object to define the accessor on.
151
+ * @param {string|PropertyKey[]} names - Comma-separated string, array, or single name/symbol.
152
+ * @param {Function} [getter] - Getter function.
153
+ * @param {Function} [setter] - Setter function.
154
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
155
+ * @returns {object} The target object.
156
+ */
59
157
  export const addAccessor = (target, names, getter, setter, force) => addDescriptor(target, names, fromAccessors(getter, setter), force);
60
158
 
159
+ /**
160
+ * Define multiple getter-based descriptors on a target.
161
+ * @param {object} target - Object to define getters on.
162
+ * @param {Object<string, Function>} dict - Map of comma-separated names to getter functions.
163
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
164
+ */
61
165
  export const addGetters = (target, dict, force) => {
62
166
  for (const [names, getter] of Object.entries(dict)) {
63
167
  addDescriptor(target, names, fromGetter(getter), force);
64
168
  }
65
169
  for (const symbol of Object.getOwnPropertySymbols(dict)) {
66
- const descriptor = Object.getOwnPropertyDescriptor(source, symbol);
170
+ const descriptor = Object.getOwnPropertyDescriptor(dict, symbol);
67
171
  if (!descriptor || !descriptor.enumerable) continue;
68
172
  addDescriptor(target, [symbol], fromGetter(dict[symbol]), force);
69
173
  }
70
174
  };
71
175
 
176
+ /**
177
+ * Copy property descriptors from a source to a target.
178
+ * @param {object} target - Destination object.
179
+ * @param {object} source - Source object.
180
+ * @param {string|symbol|PropertyKey[]|Object<string, string|PropertyKey[]>} names - Names to copy (string, symbol, array, or alias map).
181
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
182
+ * @returns {object} The target object.
183
+ */
72
184
  export const copyDescriptors = (target, source, names, force) => {
73
185
  switch (typeof names) {
74
186
  case 'string':
@@ -95,10 +207,30 @@ export const copyDescriptors = (target, source, names, force) => {
95
207
  return target;
96
208
  };
97
209
 
210
+ /**
211
+ * Create an alias for an existing property.
212
+ * @param {object} object - Object owning the property.
213
+ * @param {PropertyKey} name - Original property name.
214
+ * @param {string|PropertyKey[]} aliases - Comma-separated alias names or array.
215
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
216
+ * @returns {object} The object.
217
+ */
98
218
  export const addAlias = (object, name, aliases, force) => addDescriptor(object, aliases, Object.getOwnPropertyDescriptor(object, name), force);
99
219
 
220
+ /**
221
+ * Create multiple aliases from a dictionary.
222
+ * @param {object} object - Object owning the properties.
223
+ * @param {Object<string, string>} dict - Map of original names to comma-separated alias strings.
224
+ * @param {boolean} [force] - If `true`, overwrite existing own properties.
225
+ * @returns {object} The object.
226
+ */
100
227
  export const addAliases = (object, dict, force) => copyDescriptors(object, object, dict, force);
101
228
 
229
+ /**
230
+ * Ensure an iterator object has a `[Symbol.iterator]` method.
231
+ * @param {Iterator} iterator - Iterator to augment.
232
+ * @returns {IterableIterator} The augmented iterator.
233
+ */
102
234
  export const augmentIterator = iterator => {
103
235
  if (!iterator.hasOwnProperty(Symbol.iterator)) {
104
236
  iterator[Symbol.iterator] = function () {
@@ -108,12 +240,23 @@ export const augmentIterator = iterator => {
108
240
  return iterator;
109
241
  };
110
242
 
243
+ /**
244
+ * Normalize an iterator, using `Iterator.from` when available.
245
+ * @param {Iterator} iterator - Iterator to normalize.
246
+ * @returns {IterableIterator} An iterable iterator.
247
+ */
111
248
  let normalizeIterator = augmentIterator;
112
249
  if (typeof globalThis.Iterator?.from == 'function') {
113
250
  normalizeIterator = iterator => Iterator.from(iterator);
114
251
  }
115
252
  export {normalizeIterator};
116
253
 
254
+ /**
255
+ * Map over an iterator, producing a new iterable.
256
+ * @param {Iterable} iterator - Source iterable.
257
+ * @param {Function} callbackFn - Mapping function receiving value and index.
258
+ * @returns {Iterable} An iterable of mapped values.
259
+ */
117
260
  export const mapIterator = (iterator, callbackFn) => {
118
261
  if (typeof iterator?.map == 'function') return iterator.map(callbackFn);
119
262
  return {
@@ -131,8 +274,16 @@ export const mapIterator = (iterator, callbackFn) => {
131
274
  };
132
275
  };
133
276
 
277
+ /** @type {Object<string, number>} Map of `typeof` results that can have properties set on them. */
134
278
  export const canHaveProps = {object: 1, function: 1};
135
279
 
280
+ /**
281
+ * Copy option keys from a pattern and optional sources onto a target.
282
+ * @param {object} target - Target object (created if falsy).
283
+ * @param {object} pattern - Object defining which keys to copy and their defaults.
284
+ * @param {...object} sources - Additional source objects to override values from.
285
+ * @returns {object} The target object.
286
+ */
136
287
  export const copyOptions = (target, pattern, ...sources) => {
137
288
  target = target || {};
138
289
  const keys = Object.keys(pattern);
@@ -0,0 +1,91 @@
1
+ /** Options for null-terminated list utilities. */
2
+ export interface NTOptions {
3
+ /** Property name for the next link (default `'next'`). */
4
+ nextName?: string;
5
+ }
6
+
7
+ /** Options for null-terminated DLL utilities. */
8
+ export interface NTDllOptions extends NTOptions {
9
+ /** Property name for the previous link (default `'prev'`). */
10
+ prevName?: string;
11
+ }
12
+
13
+ /** A head/tail pair returned by conversion functions. */
14
+ export interface NTListResult<T extends object> {
15
+ /** First node. */
16
+ head: T;
17
+ /** Last node. */
18
+ tail: T;
19
+ }
20
+
21
+ /**
22
+ * Check whether a linked structure is a valid null-terminated list.
23
+ * @param head - First node, or `null` for an empty list.
24
+ * @param options - Link property names.
25
+ * @returns `true` if the list is null-terminated (not circular).
26
+ */
27
+ export function isNTList<T extends object>(head: T | null, options?: NTOptions): boolean;
28
+
29
+ /**
30
+ * Find the tail of a null-terminated list by following next links.
31
+ * @param head - First node, or `null`.
32
+ * @param options - Link property names.
33
+ * @returns The tail node, or `null` if empty or circular.
34
+ */
35
+ export function getNTListTail<T extends object>(head: T | null, options?: NTOptions): T | null;
36
+
37
+ /**
38
+ * Find the head of a null-terminated list by following prev links.
39
+ * @param node - Any node in the list, or `null`.
40
+ * @param options - Link property names (uses `prevName`).
41
+ * @returns The head node, or `null` if empty or circular.
42
+ */
43
+ export function getNTListHead<T extends object>(node: T | null, options?: { prevName?: string }): T | null;
44
+
45
+ /**
46
+ * Count the number of nodes in a null-terminated list.
47
+ * @param head - First node, or `null`.
48
+ * @param options - Link property names.
49
+ * @returns The node count.
50
+ */
51
+ export function getNTListLength<T extends object>(head: T | null, options?: NTOptions): number;
52
+
53
+ /**
54
+ * Convert a null-terminated DLL into a circular DLL.
55
+ * @param node - Any node in the null-terminated list, or `null`.
56
+ * @param options - Link property names.
57
+ * @returns Head/tail pair, or `null` if empty.
58
+ */
59
+ export function makeListFromNTList<T extends object>(node: T | null, options?: NTDllOptions): NTListResult<T> | null;
60
+
61
+ /**
62
+ * Convert a null-terminated SLL into a circular SLL.
63
+ * @param head - First node, or `null`.
64
+ * @param options - Link property names.
65
+ * @returns Head/tail pair, or `null` if empty.
66
+ */
67
+ export function makeSListFromNTList<T extends object>(head: T | null, options?: NTOptions): NTListResult<T> | null;
68
+
69
+ /**
70
+ * Convert a circular DLL into a null-terminated DLL.
71
+ * @param head - Head of the circular list, or `null`.
72
+ * @param options - Link property names.
73
+ * @returns Head/tail pair, or `null` if empty.
74
+ */
75
+ export function makeNTListFromList<T extends object>(head: T | null, options?: NTDllOptions): NTListResult<T> | null;
76
+
77
+ /**
78
+ * Convert a circular SLL into a null-terminated SLL (fast: head becomes second node).
79
+ * @param head - Head of the circular list, or `null`.
80
+ * @param options - Link property names.
81
+ * @returns Head/tail pair, or `null` if empty.
82
+ */
83
+ export function makeNTListFromSListFast<T extends object>(head: T | null, options?: NTOptions): NTListResult<T> | null;
84
+
85
+ /**
86
+ * Convert a circular SLL into a null-terminated SLL (traverses to find the tail).
87
+ * @param head - Head of the circular list, or `null`.
88
+ * @param options - Link property names.
89
+ * @returns Head/tail pair, or `null` if empty.
90
+ */
91
+ export function makeNTListFromSList<T extends object>(head: T | null, options?: NTOptions): NTListResult<T> | null;
package/src/nt-utils.js CHANGED
@@ -1,7 +1,10 @@
1
- 'use strict';
2
-
3
- // utilities for working with null-terminated lists
4
-
1
+ /**
2
+ * Check whether a linked structure is a valid null-terminated list.
3
+ * @param {object|null} head - First node, or `null` for an empty list.
4
+ * @param {object} [options] - Link property names.
5
+ * @param {string} [options.nextName='next'] - Property name for the next link.
6
+ * @returns {boolean} `true` if the list is null-terminated (not circular).
7
+ */
5
8
  export const isNTList = (head, {nextName = 'next'} = {}) => {
6
9
  if (head === null) return true;
7
10
  let current = head;
@@ -14,6 +17,13 @@ export const isNTList = (head, {nextName = 'next'} = {}) => {
14
17
  return false;
15
18
  };
16
19
 
20
+ /**
21
+ * Find the tail of a null-terminated list by following next links.
22
+ * @param {object|null} head - First node, or `null`.
23
+ * @param {object} [options] - Link property names.
24
+ * @param {string} [options.nextName='next'] - Property name for the next link.
25
+ * @returns {object|null} The tail node, or `null` if empty or circular.
26
+ */
17
27
  export const getNTListTail = (head, {nextName = 'next'} = {}) => {
18
28
  if (head === null) return null;
19
29
  let current = head;
@@ -25,8 +35,22 @@ export const getNTListTail = (head, {nextName = 'next'} = {}) => {
25
35
  return null;
26
36
  };
27
37
 
38
+ /**
39
+ * Find the head of a null-terminated list by following prev links.
40
+ * @param {object|null} node - Any node in the list, or `null`.
41
+ * @param {object} [options] - Link property names.
42
+ * @param {string} [options.prevName='prev'] - Property name for the previous link.
43
+ * @returns {object|null} The head node, or `null` if empty or circular.
44
+ */
28
45
  export const getNTListHead = (node, {prevName = 'prev'} = {}) => getNTListTail(node, {nextName: prevName});
29
46
 
47
+ /**
48
+ * Count the number of nodes in a null-terminated list.
49
+ * @param {object|null} head - First node, or `null`.
50
+ * @param {object} [options] - Link property names.
51
+ * @param {string} [options.nextName='next'] - Property name for the next link.
52
+ * @returns {number} The node count.
53
+ */
30
54
  export const getNTListLength = (head, {nextName = 'next'} = {}) => {
31
55
  if (head === null) return 0;
32
56
  let current = head;
@@ -40,6 +64,14 @@ export const getNTListLength = (head, {nextName = 'next'} = {}) => {
40
64
  return length;
41
65
  };
42
66
 
67
+ /**
68
+ * Convert a null-terminated DLL into a circular DLL.
69
+ * @param {object|null} node - Any node in the null-terminated list, or `null`.
70
+ * @param {object} [options] - Link property names.
71
+ * @param {string} [options.nextName='next'] - Property name for the next link.
72
+ * @param {string} [options.prevName='prev'] - Property name for the previous link.
73
+ * @returns {{head: object, tail: object}|null} Head/tail pair, or `null` if empty.
74
+ */
43
75
  export const makeListFromNTList = (node, {nextName = 'next', prevName = 'prev'} = {}) => {
44
76
  if (node === null) return null;
45
77
  const head = getNTListHead(node, {prevName}),
@@ -49,6 +81,13 @@ export const makeListFromNTList = (node, {nextName = 'next', prevName = 'prev'}
49
81
  return {head, tail};
50
82
  };
51
83
 
84
+ /**
85
+ * Convert a null-terminated SLL into a circular SLL.
86
+ * @param {object|null} head - First node, or `null`.
87
+ * @param {object} [options] - Link property names.
88
+ * @param {string} [options.nextName='next'] - Property name for the next link.
89
+ * @returns {{head: object, tail: object}|null} Head/tail pair, or `null` if empty.
90
+ */
52
91
  export const makeSListFromNTList = (head, {nextName = 'next'} = {}) => {
53
92
  if (head === null) return null;
54
93
  const tail = getNTListTail(head, {nextName});
@@ -56,6 +95,14 @@ export const makeSListFromNTList = (head, {nextName = 'next'} = {}) => {
56
95
  return {head, tail};
57
96
  };
58
97
 
98
+ /**
99
+ * Convert a circular DLL into a null-terminated DLL.
100
+ * @param {object|null} head - Head of the circular list, or `null`.
101
+ * @param {object} [options] - Link property names.
102
+ * @param {string} [options.nextName='next'] - Property name for the next link.
103
+ * @param {string} [options.prevName='prev'] - Property name for the previous link.
104
+ * @returns {{head: object, tail: object}|null} Head/tail pair, or `null` if empty.
105
+ */
59
106
  export const makeNTListFromList = (head, {nextName = 'next', prevName = 'prev'} = {}) => {
60
107
  if (head === null) return null;
61
108
  const tail = head[prevName];
@@ -64,6 +111,13 @@ export const makeNTListFromList = (head, {nextName = 'next', prevName = 'prev'}
64
111
  return {head, tail};
65
112
  };
66
113
 
114
+ /**
115
+ * Convert a circular SLL into a null-terminated SLL (fast: head becomes second node).
116
+ * @param {object|null} head - Head of the circular list, or `null`.
117
+ * @param {object} [options] - Link property names.
118
+ * @param {string} [options.nextName='next'] - Property name for the next link.
119
+ * @returns {{head: object, tail: object}|null} Head/tail pair, or `null` if empty.
120
+ */
67
121
  export const makeNTListFromSListFast = (head, {nextName = 'next'} = {}) => {
68
122
  if (head === null) return null;
69
123
  const tail = head;
@@ -72,6 +126,13 @@ export const makeNTListFromSListFast = (head, {nextName = 'next'} = {}) => {
72
126
  return {head, tail};
73
127
  };
74
128
 
129
+ /**
130
+ * Convert a circular SLL into a null-terminated SLL (traverses to find the tail).
131
+ * @param {object|null} head - Head of the circular list, or `null`.
132
+ * @param {object} [options] - Link property names.
133
+ * @param {string} [options.nextName='next'] - Property name for the next link.
134
+ * @returns {{head: object, tail: object}|null} Head/tail pair, or `null` if empty.
135
+ */
75
136
  export const makeNTListFromSList = (head, {nextName = 'next'} = {}) => {
76
137
  if (head === null) return null;
77
138
  let tail = head;
package/src/queue.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ /** FIFO queue backed by a value list. */
2
+ export class Queue<V = unknown> {
3
+ /** Number of elements in the queue. */
4
+ size: number;
5
+
6
+ /**
7
+ * @param underlyingList - Optional pre-existing value list to use.
8
+ */
9
+ constructor(underlyingList?: object);
10
+
11
+ /** Whether the queue has no elements. */
12
+ get isEmpty(): boolean;
13
+
14
+ /** The front element without removing it, or `undefined` if empty. */
15
+ get top(): V | undefined;
16
+
17
+ /** Alias for {@link top}. */
18
+ peek(): V | undefined;
19
+
20
+ /**
21
+ * Add a value to the back of the queue.
22
+ * @param value - Value to enqueue.
23
+ * @returns `this` for chaining.
24
+ */
25
+ add(value: V): this;
26
+
27
+ /** Alias for {@link add}. */
28
+ push(value: V): this;
29
+
30
+ /** Alias for {@link add}. */
31
+ pushBack(value: V): this;
32
+
33
+ /** Alias for {@link add}. */
34
+ enqueue(value: V): this;
35
+
36
+ /**
37
+ * Remove and return the front value.
38
+ * @returns The front value, or `undefined` if empty.
39
+ */
40
+ remove(): V | undefined;
41
+
42
+ /** Alias for {@link remove}. */
43
+ pop(): V | undefined;
44
+
45
+ /** Alias for {@link remove}. */
46
+ popFront(): V | undefined;
47
+
48
+ /** Alias for {@link remove}. */
49
+ dequeue(): V | undefined;
50
+
51
+ /**
52
+ * Add multiple values to the back of the queue.
53
+ * @param values - Iterable of values.
54
+ * @returns `this` for chaining.
55
+ */
56
+ addValues(values: Iterable<V>): this;
57
+
58
+ /**
59
+ * Remove all elements.
60
+ * @returns `this` for chaining.
61
+ */
62
+ clear(): this;
63
+
64
+ /** Iterate over values from front to back. */
65
+ [Symbol.iterator](): IterableIterator<V>;
66
+
67
+ /**
68
+ * Iterate over values from back to front.
69
+ * @returns An iterable iterator.
70
+ */
71
+ getReverseIterator(): IterableIterator<V>;
72
+ }
73
+
74
+ export default Queue;
package/src/queue.js CHANGED
@@ -1,28 +1,40 @@
1
- 'use strict';
2
-
3
1
  import ValueList from './value-list.js';
4
2
  import {addAliases} from './meta-utils.js';
5
3
  import {pushValuesBack} from './list-utils.js';
6
4
 
5
+ /** FIFO queue backed by a value list. */
7
6
  export class Queue {
7
+ /** @param {object} [underlyingList] - Backing list instance (default: new ValueList). */
8
8
  constructor(underlyingList = new ValueList()) {
9
9
  this.list = underlyingList;
10
10
  this.size = this.list.getLength();
11
11
  }
12
+ /** Whether the queue has no elements. */
12
13
  get isEmpty() {
13
14
  return this.list.isEmpty;
14
15
  }
16
+ /** The front element without removing it, or `undefined` if empty. */
15
17
  get top() {
16
18
  return this.list.isEmpty ? undefined : this.list.front.value;
17
19
  }
20
+ /** Alias for {@link Queue#top|top}. */
18
21
  peek() {
19
22
  return this.list.isEmpty ? undefined : this.list.front.value;
20
23
  }
24
+ /**
25
+ * Add a value to the back of the queue.
26
+ * @param {*} value - Value to enqueue.
27
+ * @returns {Queue} `this` for chaining.
28
+ */
21
29
  add(value) {
22
30
  this.list.pushBack(value);
23
31
  ++this.size;
24
32
  return this;
25
33
  }
34
+ /**
35
+ * Remove and return the front value.
36
+ * @returns {*} The dequeued value, or `undefined` if empty.
37
+ */
26
38
  remove() {
27
39
  if (!this.list.isEmpty) {
28
40
  --this.size;
@@ -30,18 +42,32 @@ export class Queue {
30
42
  }
31
43
  // return undefined;
32
44
  }
45
+ /**
46
+ * Enqueue multiple values.
47
+ * @param {Iterable} values - Values to add.
48
+ * @returns {Queue} `this` for chaining.
49
+ */
33
50
  addValues(values) {
34
51
  pushValuesBack(this, values);
35
52
  return this;
36
53
  }
54
+ /**
55
+ * Remove all elements.
56
+ * @returns {Queue} `this` for chaining.
57
+ */
37
58
  clear() {
38
59
  this.list.clear();
39
60
  this.size = 0;
40
61
  return this;
41
62
  }
63
+ /** Iterate over values from front to back. */
42
64
  [Symbol.iterator]() {
43
65
  return this.list[Symbol.iterator]();
44
66
  }
67
+ /**
68
+ * Get an iterable over values in reverse order.
69
+ * @returns {Iterable} An iterable iterator of values.
70
+ */
45
71
  getReverseIterator() {
46
72
  return this.list.getReverseIterator?.();
47
73
  }
@@ -0,0 +1,47 @@
1
+ import {SllOptions} from './nodes.js';
2
+
3
+ /** Result of extracting or popping nodes from a circular SLL. */
4
+ export interface SllExtractResult<T extends object> {
5
+ /** The extracted sub-range descriptor. */
6
+ extracted: { prevFrom: T; to: T };
7
+ /** The remaining circular list head, or `null` if nothing remains. */
8
+ rest: T | null;
9
+ }
10
+
11
+ /** A splice range descriptor for SLL operations. */
12
+ export interface SllSpliceRange<T extends object> {
13
+ /** Node whose next link starts the range. */
14
+ prevFrom: T;
15
+ /** Last node of the range (defaults to `prevFrom[nextName]`). */
16
+ to?: T;
17
+ }
18
+
19
+ /**
20
+ * Extract a range of nodes from a circular SLL.
21
+ * @param options - Link property names.
22
+ * @param range - Range descriptor with `prevFrom` and optional `to`.
23
+ * @returns The extracted sub-list and the remaining list.
24
+ */
25
+ export function extract<T extends object>(options: SllOptions, range: SllSpliceRange<T>): SllExtractResult<T>;
26
+
27
+ /**
28
+ * Pop a single node out of its circular SLL.
29
+ * @param options - Link property names.
30
+ * @param prev - The node preceding the one to pop.
31
+ * @returns The popped node (now stand-alone) and the remaining list.
32
+ */
33
+ export function pop<T extends object>(options: SllOptions, prev: T): SllExtractResult<T>;
34
+
35
+ /**
36
+ * Splice a circular SLL into another list after a target node.
37
+ * @param options - Link property names.
38
+ * @param target - Node after which to insert.
39
+ * @param range - Range descriptor of the circular list to splice in.
40
+ * @returns The target node.
41
+ */
42
+ export function splice<T extends object>(options: SllOptions, target: T, range: SllSpliceRange<T>): T;
43
+
44
+ /**
45
+ * Alias for {@link splice}.
46
+ */
47
+ export { splice as append };