@hyperfrontend/list-utils 0.0.5 → 0.1.1

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.
@@ -4,143 +4,29 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.HyperfrontendListUtils = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- /**
8
- * Safe copies of Array built-in static methods.
9
- *
10
- * These references are captured at module initialization time to protect against
11
- * prototype pollution attacks. Import only what you need for tree-shaking.
12
- *
13
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/array
14
- */
15
7
  const _Array = globalThis.Array;
16
- /**
17
- * (Safe copy) Determines whether the passed value is an Array.
18
- */
19
- const isArray = _Array.isArray;
20
- /**
21
- * (Safe copy) Creates an array from an array-like or iterable object.
22
- */
23
8
  const from = _Array.from;
24
9
 
25
- /**
26
- * Safe copies of Error built-ins via factory functions.
27
- *
28
- * Since constructors cannot be safely captured via Object.assign, this module
29
- * provides factory functions that use Reflect.construct internally.
30
- *
31
- * These references are captured at module initialization time to protect against
32
- * prototype pollution attacks. Import only what you need for tree-shaking.
33
- *
34
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/error
35
- */
36
10
  const _Error = globalThis.Error;
37
11
  const _Reflect$1 = globalThis.Reflect;
38
- /**
39
- * (Safe copy) Creates a new Error using the captured Error constructor.
40
- * Use this instead of `new Error()`.
41
- *
42
- * @param message - Optional error message.
43
- * @param options - Optional error options.
44
- * @returns A new Error instance.
45
- *
46
- * @example Creating Error instances
47
- * ```typescript
48
- * const error = createError('Operation failed')
49
- * // With cause for error chaining
50
- * const wrapped = createError('Request failed', { cause: originalError })
51
- * ```
52
- */
53
12
  const createError = (message, options) => _Reflect$1.construct(_Error, [message, options]);
54
13
 
55
- /**
56
- * Safe copies of Object built-in methods.
57
- *
58
- * These references are captured at module initialization time to protect against
59
- * prototype pollution attacks. Import only what you need for tree-shaking.
60
- *
61
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/object
62
- */
63
14
  const _Object = globalThis.Object;
64
- /**
65
- * (Safe copy) Prevents modification of existing property attributes and values,
66
- * and prevents the addition of new properties.
67
- */
68
15
  const freeze = _Object.freeze;
69
16
 
70
- const registeredClasses = [];
71
-
72
- /**
73
- * Returns the data type of the target.
74
- * Uses native `typeof` operator, however, makes distinction between `null`, `array`, and `object`.
75
- * Also, when classes are registered via `registerClass`, it checks if objects are instance of any known registered class.
76
- *
77
- * @param target - The target to get the data type of.
78
- * @returns The data type of the target.
79
- *
80
- * @example Determining data types
81
- * ```typescript
82
- * getType([1, 2]) // 'array'
83
- * getType({ a: 1 }) // 'object'
84
- * getType(null) // 'null'
85
- * ```
86
- */
87
- const getType = (target) => {
88
- if (target === null)
89
- return 'null';
90
- const nativeDataType = typeof target;
91
- if (nativeDataType === 'object') {
92
- if (isArray(target))
93
- return 'array';
94
- for (const registeredClass of registeredClasses) {
95
- if (target instanceof registeredClass)
96
- return registeredClass.name;
97
- }
98
- }
99
- return nativeDataType;
100
- };
101
-
102
- /**
103
- * Safe Set factory for protected set construction.
104
- *
105
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/set
106
- */
107
- /* eslint-disable workspace/lib-require-jsdoc-example */
108
17
  const _Set = globalThis.Set;
109
18
  const _Reflect = globalThis.Reflect;
110
- /**
111
- * (Safe copy) Creates a new Set using the captured Set constructor.
112
- * Use this instead of `new Set()`.
113
- *
114
- * @param iterable - Optional iterable of values.
115
- * @returns A new Set instance.
116
- */
117
19
  const createSet = (iterable) => _Reflect.construct(_Set, iterable ? [iterable] : []);
118
20
 
119
- /**
120
- * Creates a FIFO (First-In-First-Out) list.
121
- *
122
- * @template T The type of elements in the list, must be an object.
123
- * @returns {FifoList<T>} A FIFO list with methods to manipulate and query the list.
124
- * @example Creating and using FIFO queue
125
- * ```typescript
126
- * interface Task { id: number; name: string }
127
- * const queue = createFifoList<Task>()
128
- *
129
- * queue.push({ id: 1, name: 'first' })
130
- * queue.push({ id: 2, name: 'second' })
131
- *
132
- * queue.pull() // => { id: 1, name: 'first' }
133
- * queue.pull() // => { id: 2, name: 'second' }
134
- * ```
135
- */
21
+ const isNonPrimitive$1 = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
136
22
  function createFifoList() {
137
23
  const list = createSet();
138
24
  const push = (item) => {
139
- if (getType(item) !== 'object') {
140
- throw createError('A fifo list only non-primitive values');
25
+ if (!isNonPrimitive$1(item)) {
26
+ throw createError('A fifo list only supports non-primitive values');
141
27
  }
142
28
  if (list.has(item)) {
143
- throw createError('Cannot a item that already exists');
29
+ throw createError('Cannot push an item that already exists in the list');
144
30
  }
145
31
  list.add(item);
146
32
  };
@@ -172,27 +58,11 @@
172
58
  return freeze(result);
173
59
  }
174
60
 
175
- /**
176
- * Creates a LIFO (Last-In-First-Out) list.
177
- *
178
- * @template T The type of elements in the list, must be an object.
179
- * @returns {LifoList<T>} A LIFO list with methods to manipulate and query the list.
180
- * @example Creating and using LIFO stack
181
- * ```typescript
182
- * interface HistoryEntry { url: string; timestamp: number }
183
- * const history = createLifoList<HistoryEntry>()
184
- *
185
- * history.push({ url: '/home', timestamp: 1 })
186
- * history.push({ url: '/about', timestamp: 2 })
187
- *
188
- * history.pull() // => { url: '/about', timestamp: 2 }
189
- * history.pull() // => { url: '/home', timestamp: 1 }
190
- * ```
191
- */
61
+ const isNonPrimitive = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
192
62
  function createLifoList() {
193
63
  const list = createSet();
194
64
  const push = (item) => {
195
- if (getType(item) !== 'object') {
65
+ if (!isNonPrimitive(item)) {
196
66
  throw createError('A lifo list only supports non-primitive values');
197
67
  }
198
68
  list.add(item);
@@ -229,21 +99,6 @@
229
99
  return freeze(result);
230
100
  }
231
101
 
232
- /**
233
- * Creates an array of numbers within a specified range (inclusive).
234
- *
235
- * @param start - The starting number of the range
236
- * @param end - The ending number of the range (inclusive)
237
- * @returns An array containing all numbers from start to end
238
- * @example Generating number ranges
239
- * ```typescript
240
- * createRange(1, 5)
241
- * // => [1, 2, 3, 4, 5]
242
- *
243
- * createRange(3, 3)
244
- * // => [3]
245
- * ```
246
- */
247
102
  function createRange(start, end) {
248
103
  const range = [];
249
104
  for (let i = start; i <= end; i += 1) {
@@ -252,42 +107,16 @@
252
107
  return range;
253
108
  }
254
109
 
255
- /**
256
- * Creates a value picker that cycles through a list of string values.
257
- *
258
- * @param values - The array of string values to cycle through
259
- * @returns A ValuePicker instance with current and next methods
260
- * @example Cycling through values
261
- * ```typescript
262
- * const colorPicker = createValuePicker(['red', 'green', 'blue'])
263
- *
264
- * colorPicker.current() // => 'red'
265
- * colorPicker.next() // => 'red' (first call initializes)
266
- * colorPicker.next() // => 'green'
267
- * colorPicker.next() // => 'blue'
268
- * colorPicker.next() // => 'red' (cycles back)
269
- * ```
270
- */
271
110
  function createValuePicker(values) {
272
111
  if (!values || !values.length) {
273
112
  throw createError('Expected values not to be an empty list.');
274
113
  }
275
114
  let index = -1;
276
- /**
277
- * Returns the current value without advancing the picker.
278
- *
279
- * @returns The current value in the list
280
- */
281
115
  function current() {
282
116
  if (index < 0)
283
117
  index = 0;
284
118
  return values[index];
285
119
  }
286
- /**
287
- * Advances to and returns the next value, cycling back to the start when reaching the end.
288
- *
289
- * @returns The next value in the list
290
- */
291
120
  function next() {
292
121
  if (index < 0)
293
122
  return current();
@@ -300,53 +129,15 @@
300
129
  };
301
130
  }
302
131
 
303
- /* eslint-disable @typescript-eslint/no-explicit-any */
304
- /**
305
- * Retrieves the final key from a Map by converting keys to an array.
306
- *
307
- * @param map - The Map to extract the last key from
308
- * @returns The key that was inserted last, or undefined if map is empty
309
- * @example Getting last key from Map
310
- * ```typescript
311
- * const userRoles = new Map<string, string>()
312
- * userRoles.set('alice', 'admin')
313
- * userRoles.set('bob', 'editor')
314
- * userRoles.set('charlie', 'viewer')
315
- *
316
- * getLastKeyInMap(userRoles) // => 'charlie'
317
- * ```
318
- */
319
132
  const getLastKeyInMap = (map) => {
320
133
  const items = [...map.keys()];
321
134
  return items[items.length - 1];
322
135
  };
323
136
 
324
- /**
325
- * Filters out empty, null, undefined, and whitespace-only strings from an array.
326
- *
327
- * @param values - The array of strings to filter
328
- * @returns A new array containing only non-empty strings with content
329
- * @example Filtering empty strings
330
- * ```typescript
331
- * nonEmptyStrings(['hello', '', ' ', 'world', null as unknown as string])
332
- * // => ['hello', 'world']
333
- * ```
334
- */
335
137
  function nonEmptyStrings(values) {
336
138
  return values.filter((value) => ![undefined, null, ''].includes(value) && value.trim() !== '');
337
139
  }
338
140
 
339
- /**
340
- * Removes duplicate strings from an array, preserving insertion order.
341
- *
342
- * @param values - The array of strings to deduplicate
343
- * @returns A new array containing only unique strings
344
- * @example Deduplicating strings
345
- * ```typescript
346
- * uniqueStrings(['apple', 'banana', 'apple', 'cherry', 'banana'])
347
- * // => ['apple', 'banana', 'cherry']
348
- * ```
349
- */
350
141
  function uniqueStrings(values) {
351
142
  return from(createSet(values));
352
143
  }
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).HyperfrontendListUtils={})}(this,function(e){"use strict";const t=globalThis.Array,n=t.isArray,r=t.from,o=globalThis.Error,i=globalThis.Reflect,s=(e,t)=>i.construct(o,[e,t]),l=globalThis.Object.freeze,a=[],u=e=>{if(null===e)return"null";const t=typeof e;if("object"===t){if(n(e))return"array";for(const t of a)if(e instanceof t)return t.name}return t},c=globalThis.Set,f=globalThis.Reflect,h=e=>f.construct(c,e?[e]:[]);e.createFifoList=function(){const e=h();return l({push:t=>{if("object"!==u(t))throw s("A fifo list only non-primitive values");if(e.has(t))throw s("Cannot a item that already exists");e.add(t)},pull:()=>{const t=e.values().next().value;return e.delete(t),t},map:t=>r(e.values()).map(t),forEach:t=>{e.forEach(t)},remove:t=>e.delete(t),has:t=>e.has(t),size:()=>e.size,clear:()=>e.clear()})},e.createLifoList=function(){const e=h();return l({push:t=>{if("object"!==u(t))throw s("A lifo list only supports non-primitive values");e.add(t)},pull:()=>{const t=r(e).pop();return t&&e.delete(t),t},map:t=>r(e).map(t),forEach:t=>{e.forEach(t)},remove:t=>e.delete(t),has:t=>e.has(t),size:()=>e.size,clear:()=>{e.clear()}})},e.createRange=function(e,t){const n=[];for(let r=e;r<=t;r+=1)n.push(r);return n},e.createValuePicker=function(e){if(!e||!e.length)throw s("Expected values not to be an empty list.");let t=-1;function n(){return t<0&&(t=0),e[t]}return{current:n,next:function(){return t<0?n():(t=++t<e.length?t:0,e[t])}}},e.getLastKeyInMap=e=>{const t=[...e.keys()];return t[t.length-1]},e.nonEmptyStrings=function(e){return e.filter(e=>![void 0,null,""].includes(e)&&""!==e.trim())},e.uniqueStrings=function(e){return r(h(e))}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).HyperfrontendListUtils={})}(this,function(e){"use strict";const t=globalThis.Array.from,n=globalThis.Error,o=globalThis.Reflect,r=(e,t)=>o.construct(n,[e,t]),i=globalThis.Object.freeze,l=globalThis.Set,s=globalThis.Reflect,u=e=>s.construct(l,e?[e]:[]);e.createFifoList=function(){const e=u();return i({push:t=>{if(("object"!=typeof(n=t)||null===n)&&"function"!=typeof n)throw r("A fifo list only supports non-primitive values");var n;if(e.has(t))throw r("Cannot push an item that already exists in the list");e.add(t)},pull:()=>{const t=e.values().next().value;return e.delete(t),t},map:n=>t(e.values()).map(n),forEach:t=>{e.forEach(t)},remove:t=>e.delete(t),has:t=>e.has(t),size:()=>e.size,clear:()=>e.clear()})},e.createLifoList=function(){const e=u();return i({push:t=>{if(("object"!=typeof(n=t)||null===n)&&"function"!=typeof n)throw r("A lifo list only supports non-primitive values");var n;e.add(t)},pull:()=>{const n=t(e).pop();return n&&e.delete(n),n},map:n=>t(e).map(n),forEach:t=>{e.forEach(t)},remove:t=>e.delete(t),has:t=>e.has(t),size:()=>e.size,clear:()=>{e.clear()}})},e.createRange=function(e,t){const n=[];for(let o=e;o<=t;o+=1)n.push(o);return n},e.createValuePicker=function(e){if(!e||!e.length)throw r("Expected values not to be an empty list.");let t=-1;function n(){return t<0&&(t=0),e[t]}return{current:n,next:function(){return t<0?n():(t=++t<e.length?t:0,e[t])}}},e.getLastKeyInMap=e=>{const t=[...e.keys()];return t[t.length-1]},e.nonEmptyStrings=function(e){return e.filter(e=>![void 0,null,""].includes(e)&&""!==e.trim())},e.uniqueStrings=function(e){return t(u(e))}});
package/index.cjs.js CHANGED
@@ -1,11 +1,17 @@
1
1
  'use strict';
2
2
 
3
- const index_cjs_js$2 = require('./_dependencies/@hyperfrontend/data-utils/index.cjs.js');
4
- const index_cjs_js$4 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js');
5
- const index_cjs_js$3 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
3
+ const index_cjs_js$3 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js');
4
+ const index_cjs_js$2 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
6
5
  const index_cjs_js$1 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js');
7
6
  const index_cjs_js = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
8
7
 
8
+ /**
9
+ * Reports whether a value is a non-primitive, the only kind of value these lists accept.
10
+ *
11
+ * @param value - The value a caller tried to push.
12
+ * @returns True when the value is a non-null object or a function.
13
+ */
14
+ const isNonPrimitive$1 = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
9
15
  /**
10
16
  * Creates a FIFO (First-In-First-Out) list.
11
17
  *
@@ -21,16 +27,19 @@ const index_cjs_js = require('./_dependencies/@hyperfrontend/immutable-api-utils
21
27
  *
22
28
  * queue.pull() // => { id: 1, name: 'first' }
23
29
  * queue.pull() // => { id: 2, name: 'second' }
30
+ * queue.pull() // => undefined (the list is empty)
24
31
  * ```
32
+ * @throws {Error} When the pushed item is a primitive rather than an object.
33
+ * @throws {Error} When the pushed item is already in the list. Use has() to check first if a duplicate is expected.
25
34
  */
26
35
  function createFifoList() {
27
36
  const list = index_cjs_js.createSet();
28
37
  const push = (item) => {
29
- if (index_cjs_js$2.getType(item) !== 'object') {
30
- throw index_cjs_js$3.createError('A fifo list only non-primitive values');
38
+ if (!isNonPrimitive$1(item)) {
39
+ throw index_cjs_js$2.createError('A fifo list only supports non-primitive values');
31
40
  }
32
41
  if (list.has(item)) {
33
- throw index_cjs_js$3.createError('Cannot a item that already exists');
42
+ throw index_cjs_js$2.createError('Cannot push an item that already exists in the list');
34
43
  }
35
44
  list.add(item);
36
45
  };
@@ -40,7 +49,7 @@ function createFifoList() {
40
49
  return value;
41
50
  };
42
51
  const map = (callback) => {
43
- return index_cjs_js$4.from(list.values()).map(callback);
52
+ return index_cjs_js$3.from(list.values()).map(callback);
44
53
  };
45
54
  const forEach = (callback) => {
46
55
  list.forEach(callback);
@@ -62,6 +71,13 @@ function createFifoList() {
62
71
  return index_cjs_js$1.freeze(result);
63
72
  }
64
73
 
74
+ /**
75
+ * Reports whether a value is a non-primitive, the only kind of value these lists accept.
76
+ *
77
+ * @param value - The value a caller tried to push.
78
+ * @returns True when the value is a non-null object or a function.
79
+ */
80
+ const isNonPrimitive = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
65
81
  /**
66
82
  * Creates a LIFO (Last-In-First-Out) list.
67
83
  *
@@ -82,20 +98,20 @@ function createFifoList() {
82
98
  function createLifoList() {
83
99
  const list = index_cjs_js.createSet();
84
100
  const push = (item) => {
85
- if (index_cjs_js$2.getType(item) !== 'object') {
86
- throw index_cjs_js$3.createError('A lifo list only supports non-primitive values');
101
+ if (!isNonPrimitive(item)) {
102
+ throw index_cjs_js$2.createError('A lifo list only supports non-primitive values');
87
103
  }
88
104
  list.add(item);
89
105
  };
90
106
  const pull = () => {
91
- const lastItem = index_cjs_js$4.from(list).pop();
107
+ const lastItem = index_cjs_js$3.from(list).pop();
92
108
  if (lastItem) {
93
109
  list.delete(lastItem);
94
110
  }
95
111
  return lastItem;
96
112
  };
97
113
  const map = (callback) => {
98
- return index_cjs_js$4.from(list).map(callback);
114
+ return index_cjs_js$3.from(list).map(callback);
99
115
  };
100
116
  const forEach = (callback) => {
101
117
  list.forEach(callback);
@@ -160,7 +176,7 @@ function createRange(start, end) {
160
176
  */
161
177
  function createValuePicker(values) {
162
178
  if (!values || !values.length) {
163
- throw index_cjs_js$3.createError('Expected values not to be an empty list.');
179
+ throw index_cjs_js$2.createError('Expected values not to be an empty list.');
164
180
  }
165
181
  let index = -1;
166
182
  /**
@@ -238,7 +254,7 @@ function nonEmptyStrings(values) {
238
254
  * ```
239
255
  */
240
256
  function uniqueStrings(values) {
241
- return index_cjs_js$4.from(index_cjs_js.createSet(values));
257
+ return index_cjs_js$3.from(index_cjs_js.createSet(values));
242
258
  }
243
259
 
244
260
  exports.createFifoList = createFifoList;
package/index.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  interface FifoList<T extends object> {
5
5
  /** Adds an item to the end of the list */
6
6
  push(item: T): void;
7
- /** Removes and returns the first item in the list */
8
- pull(): T;
7
+ /** Removes and returns the first item in the list, or undefined when the list is empty */
8
+ pull(): T | undefined;
9
9
  /** Maps each item using the provided callback */
10
10
  map<U>(callback: (item: T) => U): U[];
11
11
  /** Iterates over each item in the list */
@@ -34,7 +34,10 @@ interface FifoList<T extends object> {
34
34
  *
35
35
  * queue.pull() // => { id: 1, name: 'first' }
36
36
  * queue.pull() // => { id: 2, name: 'second' }
37
+ * queue.pull() // => undefined (the list is empty)
37
38
  * ```
39
+ * @throws {Error} When the pushed item is a primitive rather than an object.
40
+ * @throws {Error} When the pushed item is already in the list. Use has() to check first if a duplicate is expected.
38
41
  */
39
42
  declare function createFifoList<T extends object>(): FifoList<T>;
40
43
 
package/index.esm.js CHANGED
@@ -1,9 +1,15 @@
1
- import { getType } from './_dependencies/@hyperfrontend/data-utils/index.esm.js';
2
1
  import { from } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
3
2
  import { createError } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
4
3
  import { freeze } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js';
5
4
  import { createSet } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
6
5
 
6
+ /**
7
+ * Reports whether a value is a non-primitive, the only kind of value these lists accept.
8
+ *
9
+ * @param value - The value a caller tried to push.
10
+ * @returns True when the value is a non-null object or a function.
11
+ */
12
+ const isNonPrimitive$1 = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
7
13
  /**
8
14
  * Creates a FIFO (First-In-First-Out) list.
9
15
  *
@@ -19,16 +25,19 @@ import { createSet } from './_dependencies/@hyperfrontend/immutable-api-utils/bu
19
25
  *
20
26
  * queue.pull() // => { id: 1, name: 'first' }
21
27
  * queue.pull() // => { id: 2, name: 'second' }
28
+ * queue.pull() // => undefined (the list is empty)
22
29
  * ```
30
+ * @throws {Error} When the pushed item is a primitive rather than an object.
31
+ * @throws {Error} When the pushed item is already in the list. Use has() to check first if a duplicate is expected.
23
32
  */
24
33
  function createFifoList() {
25
34
  const list = createSet();
26
35
  const push = (item) => {
27
- if (getType(item) !== 'object') {
28
- throw createError('A fifo list only non-primitive values');
36
+ if (!isNonPrimitive$1(item)) {
37
+ throw createError('A fifo list only supports non-primitive values');
29
38
  }
30
39
  if (list.has(item)) {
31
- throw createError('Cannot a item that already exists');
40
+ throw createError('Cannot push an item that already exists in the list');
32
41
  }
33
42
  list.add(item);
34
43
  };
@@ -60,6 +69,13 @@ function createFifoList() {
60
69
  return freeze(result);
61
70
  }
62
71
 
72
+ /**
73
+ * Reports whether a value is a non-primitive, the only kind of value these lists accept.
74
+ *
75
+ * @param value - The value a caller tried to push.
76
+ * @returns True when the value is a non-null object or a function.
77
+ */
78
+ const isNonPrimitive = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
63
79
  /**
64
80
  * Creates a LIFO (Last-In-First-Out) list.
65
81
  *
@@ -80,7 +96,7 @@ function createFifoList() {
80
96
  function createLifoList() {
81
97
  const list = createSet();
82
98
  const push = (item) => {
83
- if (getType(item) !== 'object') {
99
+ if (!isNonPrimitive(item)) {
84
100
  throw createError('A lifo list only supports non-primitive values');
85
101
  }
86
102
  list.add(item);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperfrontend/list-utils",
3
- "version": "0.0.5",
3
+ "version": "0.1.1",
4
4
  "description": "Purpose-built collection utilities for queue management, filtering, and iteration patterns.",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,