list-toolkit 2.2.6 → 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 -37
- package/llms-full.txt +743 -0
- package/llms.txt +100 -0
- package/package.json +34 -29
- 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/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(
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 };
|