@hyperfrontend/list-utils 0.1.0 → 0.1.2

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 (25) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +37 -33
  3. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/{index.cjs.js → index.cjs} +0 -2
  4. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/{index.esm.js → index.mjs} +1 -2
  5. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/{index.cjs.js → index.cjs} +0 -2
  6. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/{index.esm.js → index.mjs} +1 -2
  7. package/bundle/index.iife.js +4 -20
  8. package/bundle/index.iife.min.js +1 -1
  9. package/bundle/index.umd.js +4 -20
  10. package/bundle/index.umd.min.js +1 -1
  11. package/{index.cjs.js → index.cjs} +33 -20
  12. package/{index.esm.js → index.mjs} +21 -8
  13. package/package.json +8 -6
  14. package/_dependencies/@hyperfrontend/data-utils/index.cjs.js +0 -214
  15. package/_dependencies/@hyperfrontend/data-utils/index.esm.js +0 -202
  16. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.cjs.js +0 -8
  17. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.esm.js +0 -7
  18. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js +0 -6
  19. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js +0 -5
  20. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js +0 -7
  21. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js +0 -5
  22. /package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/{index.cjs.js → index.cjs} +0 -0
  23. /package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/{index.esm.js → index.mjs} +0 -0
  24. /package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/{index.cjs.js → index.cjs} +0 -0
  25. /package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/{index.esm.js → index.mjs} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,75 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.1.2](https://github.com/AndrewRedican/hyperfrontend/compare/41325ecf9b3f15f597cddadd5fbe6ab68f59eab7...e1fedeaec2e4a890fb7767750298f48de3434cbe) - 2026-11-05
6
+
7
+ ### Breaking Changes
8
+
9
+ - **BREAKING** **lib-builder:** stop loading the rollup worker from the bundle/rollup entry
10
+ - **BREAKING** **lib-builder:** emit index.mjs and index.cjs for module outputs
11
+ - **BREAKING** **lib-builder:** fail the build on a declared export it cannot publish
12
+
13
+ ### Dependency Updates
14
+
15
+ - **tool-package:** let the version batch inherit the commit window
16
+ - **tool-package:** release a library the graph rebuilds
17
+ - **tool-package:** declare operating systems in make-publishable output
18
+ - **tool-package:** quote the e2e and publish executors' npm spawns for cmd.exe
19
+ - **tool-package:** run the nx e2e suites one at a time on windows
20
+ - **lib-builder:** keep platform-restricted packages external
21
+ - **lib-builder:** keep chunks a bare side-effect import reaches
22
+ - **lib-builder:** fail the build on a declaration alias cycle between entries
23
+ - **lib-builder:** list every third-party package the output inlines in THIRD_PARTY_LICENSES.md
24
+ - **lib-builder:** reproduce dependency license texts in THIRD_PARTY_LICENSES.md
25
+ - **tool-package:** drop npm's silent flag from the version remedies
26
+ - **tool-package:** locate generator templates from the tree root
27
+ - **tool-package:** add a provenance option to the publish executor
28
+ - **tool-package:** locate the test runner from the workspace root
29
+ - **tool-package:** scaffold e2e specs on the packed consumer
30
+ - **tool-package:** hand e2e suites the packed tarball path
31
+ - **lib-builder:** skip type checking in workers that drop diagnostics
32
+ - **lib-builder:** build browser bundles from one entry, refuse several
33
+ - **lib-builder:** inline dynamic imports into each library entry bundle
34
+ - **tool-package:** drop the e2e template's unknown rule directive
35
+ - **tool-package:** keep existing config when make-publishable re-runs
36
+ - **tool-package:** import make-publishable statically
37
+ - **tool-package:** scaffold libraries with the workspace lint config
38
+ - **lib-builder:** strip lint pragmas from bundled dependency code
39
+ - **tool-package:** typecheck each project's spec config alongside its library config
40
+ - **tool-package:** scaffold e2e projects with an audit target and assertive spec names
41
+ - **tool-package:** scaffold libraries at 0.0.0 with a bare test target and runner config types
42
+ - **tool-package:** register a publishable library in ci, the root readme and the docs site
43
+ - **lib-builder:** build the bin descriptor's output dir natively
44
+ - **lib-builder:** keep resolved workspace dependency paths native
45
+ - **tool-package:** quote the tarball path when npm runs through the windows shell
46
+ - **lib-builder:** drop type diagnostics computed without path mappings
47
+ - **lib-builder:** retry report directory removal on transient windows locks
48
+ - **lib-builder:** keep core modules external without module.isBuiltin
49
+ - **BREAKING** **lib-builder:** stop loading the rollup worker from the bundle/rollup entry
50
+ - **lib-builder:** expose the crypto global to the rollup worker on node 18
51
+ - **BREAKING** **lib-builder:** emit index.mjs and index.cjs for module outputs
52
+ - **tool-package:** run the tsc entry script on node for typecheck
53
+ - **lib-builder:** run the tsc entry script on node for declaration emit
54
+ - **tool-package:** pass the e2e executor preloads as file urls
55
+ - **tool-package:** pass the test executor preload as a file url
56
+ - **tool-package:** report workspace-relative paths with posix separators
57
+ - **tool-package:** split text on crlf line endings
58
+ - **tool-package:** spawn npm through a shell on windows
59
+ - **lib-builder:** split worker stderr on crlf line endings
60
+ - **lib-builder:** rewrite only native separators to forward slashes
61
+ - **lib-builder:** walk up to package.json from native windows paths
62
+ - **lib-builder:** guard bundled deps against native windows paths
63
+ - **BREAKING** **lib-builder:** fail the build on a declared export it cannot publish
64
+ - **tool-package:** fold the compatibility matrix into the version commit
65
+ - **tool-package:** expose the builder clean option to projects
66
+ - **lib-builder:** clean only an owned output and add the clean option
67
+
68
+ ## [0.1.1](https://github.com/AndrewRedican/hyperfrontend/compare/29dc54d58c2b3c8b8dd35f7c546ebc6cd9191f6e...adf0a4f77dece2be855e7ab88185a4fe84e7b16b) - 2026-09-14
69
+
70
+ ### Bug Fixes
71
+
72
+ - accept arrays, functions and class instances in fifo and lifo lists
73
+
5
74
  ## [0.1.0](https://github.com/AndrewRedican/hyperfrontend/compare/5f116abb8ba6355dfb283fa03b7481e5eb029480...cc16961a470190848f71a7cce41f7377bc4511a4) - 2026-08-25
6
75
 
7
76
  ### Breaking Changes
package/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # @hyperfrontend/list-utils
1
+ <p align="center">
2
+ <a href="https://www.hyperfrontend.dev/docs/libraries/utils/list/">
3
+ <img width="640" height="180" src="https://www.hyperfrontend.dev/media/banner-list-utils/banner.gif" alt="@hyperfrontend/list-utils">
4
+ </a>
5
+ </p>
2
6
 
3
7
  <p align="center">
4
8
  <a href="https://github.com/AndrewRedican/hyperfrontend/actions/workflows/ci-lib-list-utils.yml">
@@ -33,6 +37,12 @@
33
37
  <img src="https://img.shields.io/badge/tree%20shakeable-%E2%9C%93-success?style=flat-square" alt="Tree Shakeable">
34
38
  </p>
35
39
 
40
+ <p align="center">
41
+ <a href="https://www.hyperfrontend.dev/docs/libraries/utils/list/">
42
+ <img width="640" height="360" src="https://www.hyperfrontend.dev/media/list-utils-order/hero.gif" alt="A tube open at both ends and a cup open only at the top, with the same three numbered discs dropped into each; three pulls take the discs out, the tube from its bottom and the cup from its top, and the exit rows read 1 2 3 under the tube and 3 2 1 beside the cup">
43
+ </a>
44
+ </p>
45
+
36
46
  Purpose-built collection utilities for queue management, filtering, and iteration patterns.
37
47
 
38
48
  • 👉 See [**documentation**](https://www.hyperfrontend.dev/docs/libraries/utils/list/)
@@ -46,16 +56,16 @@ The library enforces immutability through frozen interfaces while maintaining hi
46
56
 
47
57
  ### Key Features
48
58
 
49
- - **FIFO and LIFO queues** with type-safe object tracking
50
- - **Value picker** for cyclical iteration (ideal for round-robin patterns)
51
- - **String sanitization** utilities (dedupe, trim, filter empty)
52
- - **Range generation** for loop-free number sequences
53
- - **Map utilities** for common Map operations
59
+ - **[FIFO and LIFO queues](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createFifoList)** with type-safe object tracking
60
+ - **[Value picker](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createValuePicker)** for cyclical iteration (ideal for round-robin patterns)
61
+ - **[String sanitization](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-uniqueStrings)** utilities (dedupe, trim, filter empty)
62
+ - **[Range generation](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createRange)** for loop-free number sequences
63
+ - **[Map utilities](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-getLastKeyInMap)** for common Map operations
54
64
  - **Zero dependencies** - Self-contained implementation with no third-party runtime dependencies
55
65
 
56
66
  ### Architecture Highlights
57
67
 
58
- Queue implementations return frozen objects to prevent external mutation while using native `Set` internally for optimal performance. Object-only restriction on queues prevents reference comparison issues with primitives.
68
+ Both queue kinds hold object references only: pushing a primitive throws at runtime, not just at compile time. Membership is reference identity, so two structurally identical objects are two separate entries, and `has()` and `remove()` need the same reference you pushed.
59
69
 
60
70
  ## Why Use @hyperfrontend/list-utils?
61
71
 
@@ -99,47 +109,41 @@ colorPicker.next() // 'blue'
99
109
  colorPicker.next() // 'green'
100
110
  colorPicker.next() // 'red' (cycles back)
101
111
 
102
- // String sanitization
112
+ // String sanitization: blanks are dropped, survivors keep their original padding
103
113
  const userInputs = [' hello ', '', 'world', null, 'hello', ' ', 'world']
104
- const cleaned = uniqueStrings(nonEmptyStrings(userInputs)) // ['hello', 'world']
114
+ const cleaned = uniqueStrings(nonEmptyStrings(userInputs)) // [' hello ', 'world', 'hello']
105
115
  ```
106
116
 
107
117
  ## API Overview
108
118
 
109
- ### Queue Management
110
-
111
- - **`createFifoList<T>()`** - First-in-first-out queue with reference uniqueness
112
- - **`createLifoList<T>()`** - Last-in-first-out stack with reference uniqueness
119
+ Two ordered collections plus a few standalone helpers; the collections are the place to start. [`createFifoList`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createFifoList) and [`createLifoList`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createLifoList) each take no arguments, are generic over an object type, and return a frozen instance with the same fixed method surface: [`push`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`pull`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`map`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`forEach`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`remove`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`has`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList), [`size`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList) and [`clear`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-FifoList). Choosing one factory over the other decides which end `pull()` reads from and nothing else about the surrounding code. They diverge on one point, deliberately: pushing an item a FIFO list already holds throws, surfacing a queue that would otherwise take the same job twice, whereas a LIFO list ignores the duplicate and leaves the item where it already was.
113
120
 
114
- ### Iteration Utilities
121
+ Both are backed by a `Set` of the references you pushed, which has two consequences to know before reaching for either. A primitive is rejected at runtime, not only by the type parameter. And membership is reference identity, so two structurally identical objects are two entries, and `has()` and `remove()` want back the exact reference you handed over.
115
122
 
116
- - **`createValuePicker(values)`** - Cyclical iterator for round-robin patterns
117
- - **`createRange(start, end)`** - Generate number arrays without loops
123
+ The helpers are independent of the lists and of each other. [`createValuePicker`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createValuePicker) wraps a non-empty string array in a `current()` and `next()` pair that cycles forever, while [`createRange`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-createRange) returns an inclusive run of numbers. For string arrays, [`nonEmptyStrings`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-nonEmptyStrings) drops null, undefined, empty and whitespace-only entries but returns the survivors exactly as they arrived: it tests `value.trim()`, it does not trim, so padded values come through padded and [`uniqueStrings`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-uniqueStrings) then dedupes on exact string equality, which leaves `' hello '` and `'hello'` as two distinct results. The last helper, [`getLastKeyInMap`](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-getLastKeyInMap), reads the most recently inserted key of a `Map`.
118
124
 
119
- ### String Utilities
120
-
121
- - **`nonEmptyStrings(values)`** - Filter null/undefined/empty/whitespace strings
122
- - **`uniqueStrings(values)`** - Remove duplicates while preserving order
123
-
124
- ### Map Helpers
125
-
126
- - **`getLastKeyInMap(map)`** - Retrieve the last inserted key from a Map
125
+ Every signature, type parameter and thrown error is in the [API reference](https://www.hyperfrontend.dev/docs/libraries/utils/list/#api-reference).
127
126
 
128
127
  ## Compatibility
129
128
 
130
- | Platform | Support |
131
- | ----------------------------- | :-----: |
132
- | Browser | ✅ |
133
- | Node.js | ✅ |
134
- | Web Workers | ✅ |
135
- | Deno, Bun, Cloudflare Workers | ✅ |
129
+ <p align="center">
130
+ <a href="https://www.hyperfrontend.dev/docs/libraries/utils/list/#compatibility">
131
+ <img width="640" height="150" src="https://www.hyperfrontend.dev/media/runtimes-list-utils/runtimes.png" alt="Runs in Node.js 18 or later, evergreen browsers and web workers">
132
+ </a>
133
+ </p>
134
+
135
+ | Operating System | Supported |
136
+ | ---------------- | :-------: |
137
+ | Linux | ✅ |
138
+ | macOS | ✅ |
139
+ | Windows | ✅ |
136
140
 
137
141
  ### Output Formats
138
142
 
139
143
  | Format | File | Tree-Shakeable |
140
144
  | ------ | -------------------------- | :------------: |
141
- | ESM | `index.esm.js` | ✅ |
142
- | CJS | `index.cjs.js` | ❌ |
145
+ | ESM | `index.mjs` | ✅ |
146
+ | CJS | `index.cjs` | ❌ |
143
147
  | IIFE | `bundle/index.iife.min.js` | ❌ |
144
148
  | UMD | `bundle/index.umd.min.js` | ❌ |
145
149
 
@@ -157,7 +161,7 @@ const cleaned = uniqueStrings(nonEmptyStrings(userInputs)) // ['hello', 'world']
157
161
  </script>
158
162
  ```
159
163
 
160
- **Global variable:** `HyperfrontendListUtils`
164
+ **Global variable:** [`HyperfrontendListUtils`](https://www.hyperfrontend.dev/docs/libraries/utils/list/)
161
165
 
162
166
  ## Part of hyperfrontend
163
167
 
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
3
  const _Array = globalThis.Array;
4
- const isArray = _Array.isArray;
5
4
  const from = _Array.from;
6
5
  exports.from = from;
7
- exports.isArray = isArray;
@@ -1,5 +1,4 @@
1
1
  const _Array = globalThis.Array;
2
- const isArray = _Array.isArray;
3
2
  const from = _Array.from;
4
3
 
5
- export { from, isArray };
4
+ export { from };
@@ -2,6 +2,4 @@
2
2
 
3
3
  const _Object = globalThis.Object;
4
4
  const freeze = _Object.freeze;
5
- const keys = _Object.keys;
6
5
  exports.freeze = freeze;
7
- exports.keys = keys;
@@ -1,5 +1,4 @@
1
1
  const _Object = globalThis.Object;
2
2
  const freeze = _Object.freeze;
3
- const keys = _Object.keys;
4
3
 
5
- export { freeze, keys };
4
+ export { freeze };
@@ -2,7 +2,6 @@ var HyperfrontendListUtils = (function (exports) {
2
2
  'use strict';
3
3
 
4
4
  const _Array = globalThis.Array;
5
- const isArray = _Array.isArray;
6
5
  const from = _Array.from;
7
6
 
8
7
  const _Error = globalThis.Error;
@@ -12,31 +11,15 @@ var HyperfrontendListUtils = (function (exports) {
12
11
  const _Object = globalThis.Object;
13
12
  const freeze = _Object.freeze;
14
13
 
15
- const registeredClasses = [];
16
-
17
- const getType = (target) => {
18
- if (target === null)
19
- return 'null';
20
- const nativeDataType = typeof target;
21
- if (nativeDataType === 'object') {
22
- if (isArray(target))
23
- return 'array';
24
- for (const registeredClass of registeredClasses) {
25
- if (target instanceof registeredClass)
26
- return registeredClass.name;
27
- }
28
- }
29
- return nativeDataType;
30
- };
31
-
32
14
  const _Set = globalThis.Set;
33
15
  const _Reflect = globalThis.Reflect;
34
16
  const createSet = (iterable) => _Reflect.construct(_Set, iterable ? [iterable] : []);
35
17
 
18
+ const isNonPrimitive$1 = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
36
19
  function createFifoList() {
37
20
  const list = createSet();
38
21
  const push = (item) => {
39
- if (getType(item) !== 'object') {
22
+ if (!isNonPrimitive$1(item)) {
40
23
  throw createError('A fifo list only supports non-primitive values');
41
24
  }
42
25
  if (list.has(item)) {
@@ -72,10 +55,11 @@ var HyperfrontendListUtils = (function (exports) {
72
55
  return freeze(result);
73
56
  }
74
57
 
58
+ const isNonPrimitive = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
75
59
  function createLifoList() {
76
60
  const list = createSet();
77
61
  const push = (item) => {
78
- if (getType(item) !== 'object') {
62
+ if (!isNonPrimitive(item)) {
79
63
  throw createError('A lifo list only supports non-primitive values');
80
64
  }
81
65
  list.add(item);
@@ -1 +1 @@
1
- var HyperfrontendListUtils=function(e){"use strict";const t=globalThis.Array,r=t.isArray,n=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(r(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]:[]);return e.createFifoList=function(){const e=h();return l({push:t=>{if("object"!==u(t))throw s("A fifo list only supports non-primitive values");if(e.has(t))throw s("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:t=>n(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=n(e).pop();return t&&e.delete(t),t},map:t=>n(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 r=[];for(let n=e;n<=t;n+=1)r.push(n);return r},e.createValuePicker=function(e){if(!e||!e.length)throw s("Expected values not to be an empty list.");let t=-1;function r(){return t<0&&(t=0),e[t]}return{current:r,next:function(){return t<0?r():(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 n(h(e))},e}({});
1
+ var HyperfrontendListUtils=function(t){"use strict";const e=globalThis.Array.from,n=globalThis.Error,r=globalThis.Reflect,o=(t,e)=>r.construct(n,[t,e]),i=globalThis.Object.freeze,l=globalThis.Set,s=globalThis.Reflect,a=t=>s.construct(l,t?[t]:[]);return t.createFifoList=function(){const t=a();return i({push:e=>{if(("object"!=typeof(n=e)||null===n)&&"function"!=typeof n)throw o("A fifo list only supports non-primitive values");var n;if(t.has(e))throw o("Cannot push an item that already exists in the list");t.add(e)},pull:()=>{const e=t.values().next().value;return t.delete(e),e},map:n=>e(t.values()).map(n),forEach:e=>{t.forEach(e)},remove:e=>t.delete(e),has:e=>t.has(e),size:()=>t.size,clear:()=>t.clear()})},t.createLifoList=function(){const t=a();return i({push:e=>{if(("object"!=typeof(n=e)||null===n)&&"function"!=typeof n)throw o("A lifo list only supports non-primitive values");var n;t.add(e)},pull:()=>{const n=e(t).pop();return n&&t.delete(n),n},map:n=>e(t).map(n),forEach:e=>{t.forEach(e)},remove:e=>t.delete(e),has:e=>t.has(e),size:()=>t.size,clear:()=>{t.clear()}})},t.createRange=function(t,e){const n=[];for(let r=t;r<=e;r+=1)n.push(r);return n},t.createValuePicker=function(t){if(!t||!t.length)throw o("Expected values not to be an empty list.");let e=-1;function n(){return e<0&&(e=0),t[e]}return{current:n,next:function(){return e<0?n():(e=++e<t.length?e:0,t[e])}}},t.getLastKeyInMap=t=>{const e=[...t.keys()];return e[e.length-1]},t.nonEmptyStrings=function(t){return t.filter(t=>![void 0,null,""].includes(t)&&""!==t.trim())},t.uniqueStrings=function(t){return e(a(t))},t}({});
@@ -5,7 +5,6 @@
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
7
  const _Array = globalThis.Array;
8
- const isArray = _Array.isArray;
9
8
  const from = _Array.from;
10
9
 
11
10
  const _Error = globalThis.Error;
@@ -15,31 +14,15 @@
15
14
  const _Object = globalThis.Object;
16
15
  const freeze = _Object.freeze;
17
16
 
18
- const registeredClasses = [];
19
-
20
- const getType = (target) => {
21
- if (target === null)
22
- return 'null';
23
- const nativeDataType = typeof target;
24
- if (nativeDataType === 'object') {
25
- if (isArray(target))
26
- return 'array';
27
- for (const registeredClass of registeredClasses) {
28
- if (target instanceof registeredClass)
29
- return registeredClass.name;
30
- }
31
- }
32
- return nativeDataType;
33
- };
34
-
35
17
  const _Set = globalThis.Set;
36
18
  const _Reflect = globalThis.Reflect;
37
19
  const createSet = (iterable) => _Reflect.construct(_Set, iterable ? [iterable] : []);
38
20
 
21
+ const isNonPrimitive$1 = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
39
22
  function createFifoList() {
40
23
  const list = createSet();
41
24
  const push = (item) => {
42
- if (getType(item) !== 'object') {
25
+ if (!isNonPrimitive$1(item)) {
43
26
  throw createError('A fifo list only supports non-primitive values');
44
27
  }
45
28
  if (list.has(item)) {
@@ -75,10 +58,11 @@
75
58
  return freeze(result);
76
59
  }
77
60
 
61
+ const isNonPrimitive = (value) => (typeof value === 'object' && value !== null) || typeof value === 'function';
78
62
  function createLifoList() {
79
63
  const list = createSet();
80
64
  const push = (item) => {
81
- if (getType(item) !== 'object') {
65
+ if (!isNonPrimitive(item)) {
82
66
  throw createError('A lifo list only supports non-primitive values');
83
67
  }
84
68
  list.add(item);
@@ -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 supports non-primitive values");if(e.has(t))throw s("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: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))}});
@@ -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');
6
- const index_cjs_js$1 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js');
7
- const index_cjs_js = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
3
+ const index_cjs$3 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs');
4
+ const index_cjs$2 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs');
5
+ const index_cjs$1 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs');
6
+ const index_cjs = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs');
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
  *
@@ -27,13 +33,13 @@ const index_cjs_js = require('./_dependencies/@hyperfrontend/immutable-api-utils
27
33
  * @throws {Error} When the pushed item is already in the list. Use has() to check first if a duplicate is expected.
28
34
  */
29
35
  function createFifoList() {
30
- const list = index_cjs_js.createSet();
36
+ const list = index_cjs.createSet();
31
37
  const push = (item) => {
32
- if (index_cjs_js$2.getType(item) !== 'object') {
33
- throw index_cjs_js$3.createError('A fifo list only supports non-primitive values');
38
+ if (!isNonPrimitive$1(item)) {
39
+ throw index_cjs$2.createError('A fifo list only supports non-primitive values');
34
40
  }
35
41
  if (list.has(item)) {
36
- throw index_cjs_js$3.createError('Cannot push an item that already exists in the list');
42
+ throw index_cjs$2.createError('Cannot push an item that already exists in the list');
37
43
  }
38
44
  list.add(item);
39
45
  };
@@ -43,7 +49,7 @@ function createFifoList() {
43
49
  return value;
44
50
  };
45
51
  const map = (callback) => {
46
- return index_cjs_js$4.from(list.values()).map(callback);
52
+ return index_cjs$3.from(list.values()).map(callback);
47
53
  };
48
54
  const forEach = (callback) => {
49
55
  list.forEach(callback);
@@ -62,9 +68,16 @@ function createFifoList() {
62
68
  size,
63
69
  clear,
64
70
  };
65
- return index_cjs_js$1.freeze(result);
71
+ return index_cjs$1.freeze(result);
66
72
  }
67
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';
68
81
  /**
69
82
  * Creates a LIFO (Last-In-First-Out) list.
70
83
  *
@@ -83,22 +96,22 @@ function createFifoList() {
83
96
  * ```
84
97
  */
85
98
  function createLifoList() {
86
- const list = index_cjs_js.createSet();
99
+ const list = index_cjs.createSet();
87
100
  const push = (item) => {
88
- if (index_cjs_js$2.getType(item) !== 'object') {
89
- throw index_cjs_js$3.createError('A lifo list only supports non-primitive values');
101
+ if (!isNonPrimitive(item)) {
102
+ throw index_cjs$2.createError('A lifo list only supports non-primitive values');
90
103
  }
91
104
  list.add(item);
92
105
  };
93
106
  const pull = () => {
94
- const lastItem = index_cjs_js$4.from(list).pop();
107
+ const lastItem = index_cjs$3.from(list).pop();
95
108
  if (lastItem) {
96
109
  list.delete(lastItem);
97
110
  }
98
111
  return lastItem;
99
112
  };
100
113
  const map = (callback) => {
101
- return index_cjs_js$4.from(list).map(callback);
114
+ return index_cjs$3.from(list).map(callback);
102
115
  };
103
116
  const forEach = (callback) => {
104
117
  list.forEach(callback);
@@ -119,7 +132,7 @@ function createLifoList() {
119
132
  size,
120
133
  clear,
121
134
  };
122
- return index_cjs_js$1.freeze(result);
135
+ return index_cjs$1.freeze(result);
123
136
  }
124
137
 
125
138
  /**
@@ -163,7 +176,7 @@ function createRange(start, end) {
163
176
  */
164
177
  function createValuePicker(values) {
165
178
  if (!values || !values.length) {
166
- throw index_cjs_js$3.createError('Expected values not to be an empty list.');
179
+ throw index_cjs$2.createError('Expected values not to be an empty list.');
167
180
  }
168
181
  let index = -1;
169
182
  /**
@@ -193,7 +206,7 @@ function createValuePicker(values) {
193
206
  };
194
207
  }
195
208
 
196
- /* eslint-disable @typescript-eslint/no-explicit-any */
209
+ /* lint-disable typescript/no-explicit-any */
197
210
  /**
198
211
  * Retrieves the final key from a Map by converting keys to an array.
199
212
  *
@@ -241,7 +254,7 @@ function nonEmptyStrings(values) {
241
254
  * ```
242
255
  */
243
256
  function uniqueStrings(values) {
244
- return index_cjs_js$4.from(index_cjs_js.createSet(values));
257
+ return index_cjs$3.from(index_cjs.createSet(values));
245
258
  }
246
259
 
247
260
  exports.createFifoList = createFifoList;
@@ -1,9 +1,15 @@
1
- import { getType } from './_dependencies/@hyperfrontend/data-utils/index.esm.js';
2
- import { from } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
3
- import { createError } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
4
- import { freeze } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js';
5
- import { createSet } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
1
+ import { from } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.mjs';
2
+ import { createError } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.mjs';
3
+ import { freeze } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.mjs';
4
+ import { createSet } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.mjs';
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
  *
@@ -27,7 +33,7 @@ import { createSet } from './_dependencies/@hyperfrontend/immutable-api-utils/bu
27
33
  function createFifoList() {
28
34
  const list = createSet();
29
35
  const push = (item) => {
30
- if (getType(item) !== 'object') {
36
+ if (!isNonPrimitive$1(item)) {
31
37
  throw createError('A fifo list only supports non-primitive values');
32
38
  }
33
39
  if (list.has(item)) {
@@ -63,6 +69,13 @@ function createFifoList() {
63
69
  return freeze(result);
64
70
  }
65
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';
66
79
  /**
67
80
  * Creates a LIFO (Last-In-First-Out) list.
68
81
  *
@@ -83,7 +96,7 @@ function createFifoList() {
83
96
  function createLifoList() {
84
97
  const list = createSet();
85
98
  const push = (item) => {
86
- if (getType(item) !== 'object') {
99
+ if (!isNonPrimitive(item)) {
87
100
  throw createError('A lifo list only supports non-primitive values');
88
101
  }
89
102
  list.add(item);
@@ -191,7 +204,7 @@ function createValuePicker(values) {
191
204
  };
192
205
  }
193
206
 
194
- /* eslint-disable @typescript-eslint/no-explicit-any */
207
+ /* lint-disable typescript/no-explicit-any */
195
208
  /**
196
209
  * Retrieves the final key from a Map by converting keys to an array.
197
210
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperfrontend/list-utils",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Purpose-built collection utilities for queue management, filtering, and iteration patterns.",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -29,8 +29,8 @@
29
29
  "./package.json": "./package.json",
30
30
  ".": {
31
31
  "types": "./index.d.ts",
32
- "import": "./index.esm.js",
33
- "require": "./index.cjs.js"
32
+ "import": "./index.mjs",
33
+ "require": "./index.cjs"
34
34
  }
35
35
  },
36
36
  "repository": {
@@ -45,8 +45,8 @@
45
45
  "name": "andrew.redican.mejia@gmail.com",
46
46
  "url": "https://hyperfrontend.dev"
47
47
  },
48
- "main": "./index.cjs.js",
49
- "module": "./index.esm.js",
48
+ "main": "./index.cjs",
49
+ "module": "./index.mjs",
50
50
  "types": "./index.d.ts",
51
51
  "unpkg": "./bundle/index.umd.min.js",
52
52
  "jsdelivr": "./bundle/index.umd.min.js",
@@ -57,6 +57,8 @@
57
57
  "LICENSE.md",
58
58
  "README.md",
59
59
  "SECURITY.md",
60
- "!**/*.js.map"
60
+ "!**/*.js.map",
61
+ "!**/*.mjs.map",
62
+ "!**/*.cjs.map"
61
63
  ]
62
64
  }
@@ -1,214 +0,0 @@
1
- 'use strict';
2
-
3
- const { isArray } = require('../immutable-api-utils/built-in-copy/array/index.cjs.js');
4
- const { createError } = require('../immutable-api-utils/built-in-copy/error/index.cjs.js');
5
- const { freeze, keys: keys$1 } = require('../immutable-api-utils/built-in-copy/object/index.cjs.js');
6
- const { createMap } = require('../immutable-api-utils/built-in-copy/map/index.cjs.js');
7
- const { createDate } = require('../immutable-api-utils/built-in-copy/date/index.cjs.js');
8
- const { random, round } = require('../immutable-api-utils/built-in-copy/math/index.cjs.js');
9
-
10
- const isMarker = (text) => {
11
- if (typeof text !== 'string' || !text.startsWith('__$'))
12
- return false;
13
- return /^__\$[0-9]+$/.test(text);
14
- };
15
-
16
- const registeredClasses = [];
17
- const registeredIterableClasses = [
18
- {
19
- classRef: Array,
20
- instantiate: () => [],
21
- getKeys: (target) => {
22
- const keysArray = keys$1(target);
23
- if (getConfig().detectCircularReferences) {
24
- return keysArray.filter((key) => !isMarker(key));
25
- }
26
- return keysArray;
27
- },
28
- read: (target, key) => target[key],
29
- write: (target, value, key) => (target[key] = value),
30
- remove: (target, value) => target.splice(value, 1),
31
- },
32
- {
33
- classRef: Object,
34
- instantiate: () => ({}),
35
- getKeys: (target) => {
36
- const keysArray = keys$1(target);
37
- if (getConfig().detectCircularReferences) {
38
- return keysArray.filter((key) => !isMarker(key));
39
- }
40
- return keysArray;
41
- },
42
- read: (target, key) => target[key],
43
- write: (target, value, key) => (target[key] = value),
44
- remove: (target, value) => delete target[value],
45
- },
46
- ];
47
- let samePositionOfOwnProperties = false;
48
- let detectCircularReferences = false;
49
- const getConfig = () => ({
50
- samePositionOfOwnProperties,
51
- detectCircularReferences,
52
- });
53
-
54
- const getKeysFromIterable = (target, dataType) => {
55
- if (dataType === 'array')
56
- dataType = Array.name;
57
- if (dataType === 'object')
58
- dataType = Object.name;
59
- const iterableClass = registeredIterableClasses.find(({ classRef }) => dataType === classRef.name);
60
- if (iterableClass === undefined)
61
- return [];
62
- return iterableClass.getKeys(target);
63
- };
64
-
65
- const getType = (target) => {
66
- if (target === null)
67
- return 'null';
68
- const nativeDataType = typeof target;
69
- if (nativeDataType === 'object') {
70
- if (isArray(target))
71
- return 'array';
72
- for (const registeredClass of registeredClasses) {
73
- if (target instanceof registeredClass)
74
- return registeredClass.name;
75
- }
76
- }
77
- return nativeDataType;
78
- };
79
-
80
- const getIterableTypes = () => registeredIterableClasses.map(({ classRef }) => {
81
- const name = classRef.name;
82
- if (name === Object.name)
83
- return 'object';
84
- if (name === Array.name)
85
- return 'array';
86
- return name;
87
- });
88
-
89
- const isIterableType = (dataType) => getIterableTypes().includes(dataType);
90
-
91
- const isIterable = (target) => isIterableType(getType(target));
92
-
93
- const marker = () => {
94
- const randomValue = round(random() * 10000000000000);
95
- const sequential = createDate().getTime();
96
- const unique = `${randomValue}${sequential}`;
97
- const prefix = `__$`;
98
- return `${prefix}${unique}`;
99
- };
100
-
101
- const referenceStack = () => {
102
- const records = createMap();
103
- const flag = marker();
104
- const exists = (ref) => (isIterable(ref) ? flag in ref && records.has(ref[flag]) : false);
105
- const add = (ref) => {
106
- if (!isIterable(ref) || exists(ref))
107
- return;
108
- ref[flag] = Symbol();
109
- records.set(ref[flag], [flag, ref, records.size]);
110
- };
111
- const lastSeen = (ref) => {
112
- if (!isIterable(ref))
113
- return null;
114
- const record = records.get(ref[flag]);
115
- return record ? record[2] - records.size : null;
116
- };
117
- const clear = () => (records.forEach(([key, ref]) => {
118
- delete ref[key];
119
- }),
120
- records.clear());
121
- return {
122
- add: (ref) => add(ref),
123
- exists: (ref) => exists(ref),
124
- lastSeen: (ref) => lastSeen(ref),
125
- clear: () => clear(),
126
- get size() {
127
- return records.size;
128
- },
129
- };
130
- };
131
-
132
- const errorMessage = (thing, type) => `Expected ${thing} to be ${type}.`;
133
- const nextIterationDetails = (path, key, value) => ({
134
- nextPath: [...path, key],
135
- nextValue: value[key],
136
- });
137
- const circularDependencyTraversal = (condition, callback, config, key, path, value, parent, state, stack, root = false) => {
138
- if (stack.exists(value))
139
- return state;
140
- const ok = condition(config, key, value, path, parent);
141
- if (config.exitEarly)
142
- return state;
143
- if (ok)
144
- callback(key, value, path, state, parent);
145
- stack.add(value);
146
- const type = getType(value);
147
- if (!isIterableType(type))
148
- return state;
149
- const keys = getKeysFromIterable(value, type);
150
- keys.forEach((key) => {
151
- const { nextPath, nextValue } = nextIterationDetails(path, key, value);
152
- circularDependencyTraversal(condition, callback, config, key, nextPath, nextValue, value, state, stack);
153
- });
154
- if (root)
155
- stack.clear();
156
- return state;
157
- };
158
- const nonCircularDependencyTraversal = (condition, callback, config, key, path, value, parent, state) => {
159
- const ok = condition(config, key, value, path, parent);
160
- if (config.exitEarly)
161
- return state;
162
- if (ok)
163
- callback(key, value, path, state, parent);
164
- const type = getType(value);
165
- if (!isIterableType(type))
166
- return state;
167
- const keys = getKeysFromIterable(value, type);
168
- keys.forEach((key) => {
169
- const { nextPath, nextValue } = nextIterationDetails(path, key, value);
170
- nonCircularDependencyTraversal(condition, callback, config, key, nextPath, nextValue, value, state);
171
- });
172
- return state;
173
- };
174
- const traversal = (target, condition, callback, options, state) => {
175
- if (typeof callback !== 'function')
176
- throw createError(errorMessage('callback', 'a function'));
177
- if (!(typeof options === 'object' && !isArray(options)))
178
- throw createError(errorMessage('options', 'an object'));
179
- if (!isArray(options.depth))
180
- throw createError(errorMessage('options.depth', 'an array'));
181
- const [startDepth, maxDepth] = options.depth;
182
- if (startDepth !== void 0 && typeof startDepth !== 'number')
183
- throw createError(errorMessage('options.depth.0', 'a number'));
184
- if (maxDepth !== void 0) {
185
- const maxDepthType = typeof maxDepth;
186
- if (!['number', 'string'].includes(maxDepthType))
187
- throw createError(errorMessage('options.depth.1', 'a number or a string'));
188
- if (maxDepthType === 'string' && maxDepth !== '*')
189
- throw createError("Only valid string value in options.depth.1 is '*'.");
190
- }
191
- const config = {
192
- depth: freeze([options.depth[0] ?? 0, options.depth[1] ?? '*']),
193
- exitEarly: false,
194
- };
195
- const initialArgs = [condition, callback, config, '', [], target, void 0, state];
196
- if (getConfig().detectCircularReferences)
197
- return circularDependencyTraversal(...initialArgs, referenceStack(), true);
198
- return nonCircularDependencyTraversal(...initialArgs);
199
- };
200
- const createTraversal = (condition) => (target, callback, options, state) => traversal(target, condition, callback, options ?? { depth: [0, '*'] }, state ?? {});
201
- const condition = (config, key, value, path) => !(path.length < config.depth[0] || config.depth[1] < path.length);
202
- const traverseBetweenDepthRange = createTraversal(condition);
203
- exports.createTraversal = createTraversal;
204
- exports.getConfig = getConfig;
205
- exports.getIterableTypes = getIterableTypes;
206
- exports.getKeysFromIterable = getKeysFromIterable;
207
- exports.getType = getType;
208
- exports.isIterable = isIterable;
209
- exports.isIterableType = isIterableType;
210
- exports.isMarker = isMarker;
211
- exports.marker = marker;
212
- exports.referenceStack = referenceStack;
213
- exports.registeredClasses = registeredClasses;
214
- exports.registeredIterableClasses = registeredIterableClasses;
@@ -1,202 +0,0 @@
1
- import { isArray } from '../immutable-api-utils/built-in-copy/array/index.esm.js';
2
- import { createError } from '../immutable-api-utils/built-in-copy/error/index.esm.js';
3
- import { keys, freeze } from '../immutable-api-utils/built-in-copy/object/index.esm.js';
4
- import { createMap } from '../immutable-api-utils/built-in-copy/map/index.esm.js';
5
- import { createDate } from '../immutable-api-utils/built-in-copy/date/index.esm.js';
6
- import { round, random } from '../immutable-api-utils/built-in-copy/math/index.esm.js';
7
-
8
- const isMarker = (text) => {
9
- if (typeof text !== 'string' || !text.startsWith('__$'))
10
- return false;
11
- return /^__\$[0-9]+$/.test(text);
12
- };
13
-
14
- const registeredClasses = [];
15
- const registeredIterableClasses = [
16
- {
17
- classRef: Array,
18
- instantiate: () => [],
19
- getKeys: (target) => {
20
- const keysArray = keys(target);
21
- if (getConfig().detectCircularReferences) {
22
- return keysArray.filter((key) => !isMarker(key));
23
- }
24
- return keysArray;
25
- },
26
- read: (target, key) => target[key],
27
- write: (target, value, key) => (target[key] = value),
28
- remove: (target, value) => target.splice(value, 1),
29
- },
30
- {
31
- classRef: Object,
32
- instantiate: () => ({}),
33
- getKeys: (target) => {
34
- const keysArray = keys(target);
35
- if (getConfig().detectCircularReferences) {
36
- return keysArray.filter((key) => !isMarker(key));
37
- }
38
- return keysArray;
39
- },
40
- read: (target, key) => target[key],
41
- write: (target, value, key) => (target[key] = value),
42
- remove: (target, value) => delete target[value],
43
- },
44
- ];
45
- let samePositionOfOwnProperties = false;
46
- let detectCircularReferences = false;
47
- const getConfig = () => ({
48
- samePositionOfOwnProperties,
49
- detectCircularReferences,
50
- });
51
-
52
- const getKeysFromIterable = (target, dataType) => {
53
- if (dataType === 'array')
54
- dataType = Array.name;
55
- if (dataType === 'object')
56
- dataType = Object.name;
57
- const iterableClass = registeredIterableClasses.find(({ classRef }) => dataType === classRef.name);
58
- if (iterableClass === undefined)
59
- return [];
60
- return iterableClass.getKeys(target);
61
- };
62
-
63
- const getType = (target) => {
64
- if (target === null)
65
- return 'null';
66
- const nativeDataType = typeof target;
67
- if (nativeDataType === 'object') {
68
- if (isArray(target))
69
- return 'array';
70
- for (const registeredClass of registeredClasses) {
71
- if (target instanceof registeredClass)
72
- return registeredClass.name;
73
- }
74
- }
75
- return nativeDataType;
76
- };
77
-
78
- const getIterableTypes = () => registeredIterableClasses.map(({ classRef }) => {
79
- const name = classRef.name;
80
- if (name === Object.name)
81
- return 'object';
82
- if (name === Array.name)
83
- return 'array';
84
- return name;
85
- });
86
-
87
- const isIterableType = (dataType) => getIterableTypes().includes(dataType);
88
-
89
- const isIterable = (target) => isIterableType(getType(target));
90
-
91
- const marker = () => {
92
- const randomValue = round(random() * 10000000000000);
93
- const sequential = createDate().getTime();
94
- const unique = `${randomValue}${sequential}`;
95
- const prefix = `__$`;
96
- return `${prefix}${unique}`;
97
- };
98
-
99
- const referenceStack = () => {
100
- const records = createMap();
101
- const flag = marker();
102
- const exists = (ref) => (isIterable(ref) ? flag in ref && records.has(ref[flag]) : false);
103
- const add = (ref) => {
104
- if (!isIterable(ref) || exists(ref))
105
- return;
106
- ref[flag] = Symbol();
107
- records.set(ref[flag], [flag, ref, records.size]);
108
- };
109
- const lastSeen = (ref) => {
110
- if (!isIterable(ref))
111
- return null;
112
- const record = records.get(ref[flag]);
113
- return record ? record[2] - records.size : null;
114
- };
115
- const clear = () => (records.forEach(([key, ref]) => {
116
- delete ref[key];
117
- }),
118
- records.clear());
119
- return {
120
- add: (ref) => add(ref),
121
- exists: (ref) => exists(ref),
122
- lastSeen: (ref) => lastSeen(ref),
123
- clear: () => clear(),
124
- get size() {
125
- return records.size;
126
- },
127
- };
128
- };
129
-
130
- const errorMessage = (thing, type) => `Expected ${thing} to be ${type}.`;
131
- const nextIterationDetails = (path, key, value) => ({
132
- nextPath: [...path, key],
133
- nextValue: value[key],
134
- });
135
- const circularDependencyTraversal = (condition, callback, config, key, path, value, parent, state, stack, root = false) => {
136
- if (stack.exists(value))
137
- return state;
138
- const ok = condition(config, key, value, path, parent);
139
- if (config.exitEarly)
140
- return state;
141
- if (ok)
142
- callback(key, value, path, state, parent);
143
- stack.add(value);
144
- const type = getType(value);
145
- if (!isIterableType(type))
146
- return state;
147
- const keys = getKeysFromIterable(value, type);
148
- keys.forEach((key) => {
149
- const { nextPath, nextValue } = nextIterationDetails(path, key, value);
150
- circularDependencyTraversal(condition, callback, config, key, nextPath, nextValue, value, state, stack);
151
- });
152
- if (root)
153
- stack.clear();
154
- return state;
155
- };
156
- const nonCircularDependencyTraversal = (condition, callback, config, key, path, value, parent, state) => {
157
- const ok = condition(config, key, value, path, parent);
158
- if (config.exitEarly)
159
- return state;
160
- if (ok)
161
- callback(key, value, path, state, parent);
162
- const type = getType(value);
163
- if (!isIterableType(type))
164
- return state;
165
- const keys = getKeysFromIterable(value, type);
166
- keys.forEach((key) => {
167
- const { nextPath, nextValue } = nextIterationDetails(path, key, value);
168
- nonCircularDependencyTraversal(condition, callback, config, key, nextPath, nextValue, value, state);
169
- });
170
- return state;
171
- };
172
- const traversal = (target, condition, callback, options, state) => {
173
- if (typeof callback !== 'function')
174
- throw createError(errorMessage('callback', 'a function'));
175
- if (!(typeof options === 'object' && !isArray(options)))
176
- throw createError(errorMessage('options', 'an object'));
177
- if (!isArray(options.depth))
178
- throw createError(errorMessage('options.depth', 'an array'));
179
- const [startDepth, maxDepth] = options.depth;
180
- if (startDepth !== void 0 && typeof startDepth !== 'number')
181
- throw createError(errorMessage('options.depth.0', 'a number'));
182
- if (maxDepth !== void 0) {
183
- const maxDepthType = typeof maxDepth;
184
- if (!['number', 'string'].includes(maxDepthType))
185
- throw createError(errorMessage('options.depth.1', 'a number or a string'));
186
- if (maxDepthType === 'string' && maxDepth !== '*')
187
- throw createError("Only valid string value in options.depth.1 is '*'.");
188
- }
189
- const config = {
190
- depth: freeze([options.depth[0] ?? 0, options.depth[1] ?? '*']),
191
- exitEarly: false,
192
- };
193
- const initialArgs = [condition, callback, config, '', [], target, void 0, state];
194
- if (getConfig().detectCircularReferences)
195
- return circularDependencyTraversal(...initialArgs, referenceStack(), true);
196
- return nonCircularDependencyTraversal(...initialArgs);
197
- };
198
- const createTraversal = (condition) => (target, callback, options, state) => traversal(target, condition, callback, options ?? { depth: [0, '*'] }, state ?? {});
199
- const condition = (config, key, value, path) => !(path.length < config.depth[0] || config.depth[1] < path.length);
200
- const traverseBetweenDepthRange = createTraversal(condition);
201
-
202
- export { createTraversal, getConfig, getIterableTypes, getKeysFromIterable, getType, isIterable, isIterableType, isMarker, marker, referenceStack, registeredClasses, registeredIterableClasses };
@@ -1,8 +0,0 @@
1
- 'use strict';
2
-
3
- const _Date = globalThis.Date;
4
- const _Reflect = globalThis.Reflect;
5
- function createDate(...args) {
6
- return _Reflect.construct(_Date, args);
7
- }
8
- exports.createDate = createDate;
@@ -1,7 +0,0 @@
1
- const _Date = globalThis.Date;
2
- const _Reflect = globalThis.Reflect;
3
- function createDate(...args) {
4
- return _Reflect.construct(_Date, args);
5
- }
6
-
7
- export { createDate };
@@ -1,6 +0,0 @@
1
- 'use strict';
2
-
3
- const _Map = globalThis.Map;
4
- const _Reflect = globalThis.Reflect;
5
- const createMap = (iterable) => _Reflect.construct(_Map, iterable ? [iterable] : []);
6
- exports.createMap = createMap;
@@ -1,5 +0,0 @@
1
- const _Map = globalThis.Map;
2
- const _Reflect = globalThis.Reflect;
3
- const createMap = (iterable) => _Reflect.construct(_Map, iterable ? [iterable] : []);
4
-
5
- export { createMap };
@@ -1,7 +0,0 @@
1
- 'use strict';
2
-
3
- const _Math = globalThis.Math;
4
- const round = _Math.round;
5
- const random = _Math.random;
6
- exports.random = random;
7
- exports.round = round;
@@ -1,5 +0,0 @@
1
- const _Math = globalThis.Math;
2
- const round = _Math.round;
3
- const random = _Math.random;
4
-
5
- export { random, round };