@rimbu/base 2.0.2 → 2.0.4

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 (42) hide show
  1. package/README.md +165 -35
  2. package/dist/bun/arr.mts +184 -19
  3. package/dist/bun/entry.mts +14 -2
  4. package/dist/bun/index.mts +10 -0
  5. package/dist/bun/rimbu-error.mts +25 -0
  6. package/dist/bun/token.mts +7 -0
  7. package/dist/cjs/arr.cjs +184 -19
  8. package/dist/cjs/arr.cjs.map +1 -1
  9. package/dist/cjs/arr.d.cts +184 -0
  10. package/dist/cjs/entry.cjs +14 -2
  11. package/dist/cjs/entry.cjs.map +1 -1
  12. package/dist/cjs/entry.d.cts +14 -0
  13. package/dist/cjs/index.cjs +10 -0
  14. package/dist/cjs/index.cjs.map +1 -1
  15. package/dist/cjs/index.d.cts +9 -0
  16. package/dist/cjs/rimbu-error.cjs +25 -0
  17. package/dist/cjs/rimbu-error.cjs.map +1 -1
  18. package/dist/cjs/rimbu-error.d.cts +25 -0
  19. package/dist/cjs/token.cjs +4 -0
  20. package/dist/cjs/token.cjs.map +1 -1
  21. package/dist/cjs/token.d.cts +7 -0
  22. package/dist/esm/arr.d.mts +184 -0
  23. package/dist/esm/arr.mjs +184 -19
  24. package/dist/esm/arr.mjs.map +1 -1
  25. package/dist/esm/entry.d.mts +14 -0
  26. package/dist/esm/entry.mjs +14 -2
  27. package/dist/esm/entry.mjs.map +1 -1
  28. package/dist/esm/index.d.mts +9 -0
  29. package/dist/esm/index.mjs +10 -0
  30. package/dist/esm/index.mjs.map +1 -1
  31. package/dist/esm/rimbu-error.d.mts +25 -0
  32. package/dist/esm/rimbu-error.mjs +25 -0
  33. package/dist/esm/rimbu-error.mjs.map +1 -1
  34. package/dist/esm/token.d.mts +7 -0
  35. package/dist/esm/token.mjs +4 -0
  36. package/dist/esm/token.mjs.map +1 -1
  37. package/package.json +4 -9
  38. package/src/arr.mts +184 -19
  39. package/src/entry.mts +14 -2
  40. package/src/index.mts +10 -0
  41. package/src/rimbu-error.mts +25 -0
  42. package/src/token.mts +7 -0
package/README.md CHANGED
@@ -2,24 +2,179 @@
2
2
  <img src="https://github.com/rimbu-org/rimbu/raw/main/assets/rimbu_logo.svg" />
3
3
  </p>
4
4
 
5
- [![npm version](https://badge.fury.io/js/@rimbu%2Fbase.svg)](https://www.npmjs.com/package/@rimbu/base) [![Deno](https://shield.deno.dev/x/rimbu)](http://deno.land/x/rimbu)
5
+ [![npm version](https://badge.fury.io/js/@rimbu%2Fbase.svg)](https://www.npmjs.com/package/@rimbu/base)
6
+ ![License](https://img.shields.io/github/license/rimbu-org/rimbu)
7
+ ![Types Included](https://img.shields.io/badge/TypeScript-ready-blue)
8
+ ![Node](https://img.shields.io/badge/Node-18+-6DA55F?logo=node.js&logoColor=white)
9
+ ![Bun](https://img.shields.io/badge/Bun-%23000000.svg)
10
+ ![ESM + CJS](https://img.shields.io/badge/modules-ESM%20%2B%20CJS-informational)
6
11
 
7
- ![Licence](https://img.shields.io/github/license/rimbu-org/rimbu)
12
+ </div>
8
13
 
9
- # @rimbu/base
14
+ # `@rimbu/base`
10
15
 
11
- This package contains mostly utilities to implement the other Rimbu collections. The types are not exported by any of the other packages, but are internally used by most of them.
16
+ **Foundational immutable array and utility primitives powering all other Rimbu collections.**
12
17
 
13
- Most important are the exported `Arr` methods that are used at the basis of all the block-based data structures. These methods should be as correct and efficient as possible.
18
+ `@rimbu/base` exposes a small, efficient set of low-level utilities (array operations, tuple helpers, type predicates, error types) used internally across Rimbu’s high-level data structures. While primarily an implementation substrate, you can use these helpers directly for performance‑aware immutable array manipulation and advanced type constraints.
14
19
 
15
- For complete documentation please visit the _[Rimbu Docs](https://rimbu.org)_ or the _[Rimbu API Docs](https://rimbu.org/api)_
20
+ > Think: ultra-focused building blocks for persistent & type‑rich collections.
21
+
22
+ Full documentation: **[Rimbu Docs](https://rimbu.org)** · **[Rimbu API](https://rimbu.org/api)**
23
+
24
+ ---
25
+
26
+ ## Table of Contents
27
+
28
+ 1. [Why Rimbu Base?](#why-rimbu-base)
29
+ 2. [Feature Highlights](#feature-highlights)
30
+ 3. [Quick Start](#quick-start)
31
+ 4. [Immutable Array Operations (`Arr`)](#immutable-array-operations-arr)
32
+ 5. [Tuple & Token Utilities](#tuple--token-utilities)
33
+ 6. [Type Utilities (`plain-object`)](#type-utilities-plain-object)
34
+ 7. [Error Types (`RimbuError`)](#error-types-rimbuerror)
35
+ 8. [Installation](#installation)
36
+ 9. [FAQ](#faq)
37
+ 10. [Contributing](#contributing)
38
+ 11. [License](#license)
39
+ 12. [Attributions](#attributions)
40
+ 13. [Quick Reference](#quick-reference-api-surface)
41
+
42
+ ---
43
+
44
+ ## Why Rimbu Base?
45
+
46
+ High‑level persistent collections depend on fast, predictable low‑level primitives. Instead of rewriting array cloning, sparse copying, index‑safe mutation, and structured error handling in every package, `@rimbu/base` centralizes these operations:
47
+
48
+ - **Consistency** – shared implementations eliminate subtle divergence.
49
+ - **Performance** – leverages modern `Array` prototype methods (`toSpliced`, `toReversed`, `with`, `at`) when available; falls back gracefully.
50
+ - **Immutability by default** – every operation returns a new array only when changes occur (structural sharing where possible).
51
+ - **Sparse array awareness** – preserves sparsity for specialized internal block layouts.
52
+ - **Type guards & predicates** – compile‑time discrimination for plain objects vs. functions/iterables.
53
+ - **Focused surface** – zero external runtime dependencies (aside from internal Rimbu type modules).
54
+
55
+ Use it directly if you need ergonomic immutable array helpers without pulling in full collection abstractions.
56
+
57
+ ---
58
+
59
+ ## Feature Highlights
60
+
61
+ - **`Arr` Immutable Ops** – `append`, `prepend`, `concat`, `reverse`, `update`, `mod`, `insert`, `splice`, `tail`, `init`, `last`, `mapSparse`, `copySparse`.
62
+ - **Conditional Optimization** – automatically chooses modern O(1) helpers when your runtime supports them.
63
+ - **Tuple Helpers** – `Entry.first`, `Entry.second` for lightweight entry handling in map-like structures.
64
+ - **Type Predicates** – `IsPlainObj`, `IsArray`, `IsAny`, plus runtime `isPlainObj`, `isIterable`.
65
+ - **Structured Errors** – clear error signaling via custom error classes (e.g. `InvalidStateError`).
66
+ - **Sentinel Token** – a shared `Token` symbol for internal identity and tagging.
67
+ - **Tree-shakable** – import only what you use: `import { Arr } from '@rimbu/base';`.
68
+
69
+ ---
70
+
71
+ ## Quick Start
72
+
73
+ ```ts
74
+ import { Arr } from '@rimbu/base';
75
+
76
+ const base = [1, 2, 3];
77
+
78
+ // Pure modification: only clones when the value actually changes
79
+ const incremented = Arr.mod(base, 1, (v) => v + 1); // [1, 3, 3]
80
+
81
+ // Structural no-op returns original reference for efficiency
82
+ const same = Arr.mod(base, 5, (v) => v); // index out of range → original
83
+
84
+ // Append without mutating
85
+ const appended = Arr.append(incremented, 4); // [1, 3, 3, 4]
86
+
87
+ // Reverse slice
88
+ const reversed = Arr.reverse(appended); // [4, 3, 3, 1]
89
+
90
+ console.log(base); // [1, 2, 3]
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Immutable Array Operations (`Arr`)
96
+
97
+ All functions accept a `readonly T[]` input and return either the original array (when unchanged) or an optimized clone.
98
+
99
+ | Function | Purpose |
100
+ | -------------------- | --------------------------------------------------------- |
101
+ | `append` | Add element at end (non-empty array optimization). |
102
+ | `prepend` | Add element at start efficiently. |
103
+ | `concat` | Smart concat – reuses original when one side empty. |
104
+ | `reverse` | Fast reversed copy (range slice optional). |
105
+ | `forEach` | Controlled traversal with optional reverse + halt state. |
106
+ | `map` / `reverseMap` | Indexed transformation forward or backward. |
107
+ | `last` | O(1) last element access (uses `.at(-1)` when available). |
108
+ | `update` | Apply `Update<T>` logic at index (no-op preserved). |
109
+ | `mod` | Lightweight element modification via `(value)=>value'`. |
110
+ | `insert` | Insert at index. |
111
+ | `tail` / `init` | Drop first / last element. |
112
+ | `splice` | Immutable variant of native splice. |
113
+ | `copySparse` | Preserve holes in sparse arrays. |
114
+ | `mapSparse` | Transform only present indices, keeping sparsity. |
115
+
116
+ Design details:
117
+
118
+ - Uses native **copy-on-write** style helpers when available for speed.
119
+ - Avoids unnecessary cloning when an update is identity.
120
+ - Preserves array holes for internal block structures requiring sparse layout semantics.
121
+
122
+ ---
123
+
124
+ ## Tuple & Token Utilities
125
+
126
+ ```ts
127
+ import { Entry, Token } from '@rimbu/base';
128
+
129
+ const pair: readonly [string, number] = ['age', 42];
130
+ Entry.first(pair); // 'age'
131
+ Entry.second(pair); // 42
132
+
133
+ // Shared sentinel for internal tagging / identity
134
+ if (someValue === Token) {
135
+ /* special branch */
136
+ }
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Type Utilities (`plain-object`)
142
+
143
+ Compile-time predicates for discriminating plain data objects from complex / functional structures:
144
+
145
+ | Type | Description |
146
+ | ----------------- | ---------------------------------------------------------------------------------- |
147
+ | `IsPlainObj<T>` | True only for non-iterable, non-function object types without function properties. |
148
+ | `PlainObj<T>` | Narrows to T if `IsPlainObj<T>`; otherwise `never`. |
149
+ | `IsArray<T>` | Resolves to `true` if T is a (readonly) array type. |
150
+ | `IsAny<T>` | Detects `any`. |
151
+ | `isPlainObj(obj)` | Runtime guard for plain data objects. |
152
+ | `isIterable(obj)` | Runtime guard for `Iterable`. |
153
+
154
+ Use these when building APIs that must reject iterables or functions while retaining strong type discrimination.
155
+
156
+ ---
157
+
158
+ ## Error Types (`RimbuError`)
159
+
160
+ Structured error classes provide meaningful failure contexts internally and externally:
161
+
162
+ | Error Class | Trigger Scenario |
163
+ | ---------------------------------------- | ---------------------------------------------- |
164
+ | `EmptyCollectionAssumedNonEmptyError` | An operation expected a non-empty collection. |
165
+ | `ModifiedBuilderWhileLoopingOverItError` | Mutating a builder mid-iteration. |
166
+ | `InvalidStateError` | Internal invariant breach (should not happen). |
167
+ | `InvalidUsageError` | Consumer used an API incorrectly. |
168
+
169
+ Helper throw functions exist for concise signaling (`throwInvalidStateError()`, etc.). Prefer them for consistency.
170
+
171
+ ---
16
172
 
17
173
  ## Installation
18
174
 
19
175
  ### Compabitity
20
176
 
21
177
  - [`Node` ![NodeJS](https://img.shields.io/badge/node.js-6DA55F?logo=node.js&logoColor=white)](https://nodejs.org)
22
- - [`Deno` ![Deno JS](https://img.shields.io/badge/deno%20js-000000?logo=deno&logoColor=white)](https://deno.com/runtime)
23
178
  - [`Bun` ![Bun](https://img.shields.io/badge/Bun-%23000000.svg?logoColor=white)](https://bun.sh/)
24
179
  - `Web` ![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?logoColor=white)
25
180
 
@@ -43,37 +198,12 @@ npm install @rimbu/base
43
198
  bun add @rimbu/base
44
199
  ```
45
200
 
46
- ### Deno Setup
47
-
48
- Create or edit `import_map.json` in your project root:
49
-
50
- ```json
51
- {
52
- "imports": {
53
- "@rimbu/": "https://deno.land/x/rimbu@x.y.z/"
54
- }
55
- }
56
- ```
57
-
58
- _Replace `x.y.z` with the desired version._
201
+ **Deno:**
59
202
 
60
- In this way you can use relative imports from Rimbu in your code, like so:
61
-
62
- ```ts
63
- import { List } from '@rimbu/core/mod.ts';
64
- import { HashMap } from '@rimbu/hashed/mod.ts';
65
- ```
66
-
67
- Note that for sub-packages, due to conversion limitations it is needed to import the `index.ts` instead of `mod.ts`, like so:
68
-
69
- ```ts
70
- import { HashMap } from '@rimbu/hashed/map/index.ts';
203
+ ```sh
204
+ deno add npm:@rimbu/base
71
205
  ```
72
206
 
73
- To run your script (let's assume the entry point is in `src/main.ts`):
74
-
75
- `deno run --import-map import_map.json src/main.ts`
76
-
77
207
  ## Usage
78
208
 
79
209
  ```ts
package/dist/bun/arr.mts CHANGED
@@ -1,19 +1,48 @@
1
1
  import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
2
2
 
3
+ /**
4
+ * Internal helper that appends a value using the modern immutable `toSpliced` API.
5
+ * @internal
6
+ * @typeparam T - the array element type
7
+ * @param array - the source array (not mutated)
8
+ * @param value - the value to append
9
+ * @returns a new non-empty array with the value at the end
10
+ */
3
11
  export function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
4
12
  return array.toSpliced(array.length, 0, value) as ArrayNonEmpty<T>;
5
13
  }
6
14
 
15
+ /**
16
+ * Internal helper that appends a value by cloning and pushing (legacy fallback).
17
+ * @internal
18
+ * @typeparam T - the array element type
19
+ * @param array - the source array (not mutated)
20
+ * @param value - the value to append
21
+ * @returns a new non-empty array with the value at the end
22
+ */
7
23
  export function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
8
24
  const clone = array.slice();
9
25
  clone.push(value);
10
26
  return clone as ArrayNonEmpty<T>;
11
27
  }
12
28
 
13
- // Returns a copy of the array with the given value appended
29
+ /**
30
+ * Returns a copy of the array with the given value appended.
31
+ * Chooses an implementation depending on environment capabilities.
32
+ * @typeparam T - the array element type
33
+ * @param array - the source array (not mutated)
34
+ * @param value - the value to append
35
+ * @returns a new array with the value at the end
36
+ */
14
37
  export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
15
38
 
16
- // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty
39
+ /**
40
+ * Returns the concatenation of two arrays, reusing an input array when the other is empty.
41
+ * @typeparam T - the array element type
42
+ * @param first - the first array
43
+ * @param second - the second array
44
+ * @returns a new array containing all elements of both arrays (or one of the originals if the other is empty)
45
+ */
17
46
  export function concat<T>(
18
47
  first: readonly T[],
19
48
  second: readonly T[]
@@ -23,6 +52,10 @@ export function concat<T>(
23
52
  return first.concat(second);
24
53
  }
25
54
 
55
+ /**
56
+ * Internal helper to create a reversed copy using modern `toReversed` with optional slicing.
57
+ * @internal
58
+ */
26
59
  export function _reverseNew<T>(
27
60
  array: readonly T[],
28
61
  start?: number,
@@ -36,6 +69,10 @@ export function _reverseNew<T>(
36
69
  return source.toReversed();
37
70
  }
38
71
 
72
+ /**
73
+ * Internal helper to create a reversed copy using manual iteration (legacy fallback).
74
+ * @internal
75
+ */
39
76
  export function _reverseOld<T>(
40
77
  array: readonly T[],
41
78
  start?: number,
@@ -54,11 +91,25 @@ export function _reverseOld<T>(
54
91
  return res;
55
92
  }
56
93
 
57
- // Returns an copy of the array between the start and end indices, with the elements in reversed order.
94
+ /**
95
+ * Returns a copy of the array (or a slice) with elements in reversed order.
96
+ * @typeparam T - array element type
97
+ * @param array - the source array
98
+ * @param start - optional start index (inclusive)
99
+ * @param end - optional end index (inclusive)
100
+ */
58
101
  export const reverse =
59
102
  'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
60
103
 
61
- // Performs given function on each element of the array, in reverse order if 'reversed' is true.
104
+ /**
105
+ * Performs the given function for each element of the array, optionally in reverse order.
106
+ * Halting is supported through the provided `TraverseState`.
107
+ * @typeparam T - element type
108
+ * @param array - the source array
109
+ * @param f - callback receiving (value, sequential index, halt)
110
+ * @param state - traversal state (created if omitted)
111
+ * @param reversed - whether to traverse in reverse order
112
+ */
62
113
  export function forEach<T>(
63
114
  array: readonly T[],
64
115
  f: (value: T, index: number, halt: () => void) => void,
@@ -85,7 +136,15 @@ export function forEach<T>(
85
136
  }
86
137
  }
87
138
 
88
- // Returns a copy of the array where given function is applied to each element
139
+ /**
140
+ * Returns a copy of the array where the given function is applied to each element.
141
+ * Supports an index offset useful for composed traversals.
142
+ * @typeparam T - source element type
143
+ * @typeparam R - result element type
144
+ * @param array - the source array
145
+ * @param f - the mapping function
146
+ * @param indexOffset - optional start index value passed to `f`
147
+ */
89
148
  export function map<T, R>(
90
149
  array: readonly T[],
91
150
  f: (value: T, index: number) => R,
@@ -107,7 +166,14 @@ export function map<T, R>(
107
166
  return result;
108
167
  }
109
168
 
110
- // Returns a copy of the array where given functio is applied to each element in reverse order
169
+ /**
170
+ * Returns a copy of the array where the given function is applied to each element in reverse order.
171
+ * @typeparam T - source element type
172
+ * @typeparam R - result element type
173
+ * @param array - the source array
174
+ * @param f - the mapping function
175
+ * @param indexOffset - optional index offset passed to `f`
176
+ */
111
177
  export function reverseMap<T, R>(
112
178
  array: readonly T[],
113
179
  f: (value: T, index: number) => R,
@@ -124,6 +190,10 @@ export function reverseMap<T, R>(
124
190
  return result;
125
191
  }
126
192
 
193
+ /**
194
+ * Internal helper to prepend a value using `toSpliced`.
195
+ * @internal
196
+ */
127
197
  export function _prependNew<T>(
128
198
  array: readonly T[],
129
199
  value: T
@@ -131,6 +201,10 @@ export function _prependNew<T>(
131
201
  return array.toSpliced(0, 0, value) as ArrayNonEmpty<T>;
132
202
  }
133
203
 
204
+ /**
205
+ * Internal helper to prepend a value using legacy cloning.
206
+ * @internal
207
+ */
134
208
  export function _prependOld<T>(
135
209
  array: readonly T[],
136
210
  value: T
@@ -140,21 +214,42 @@ export function _prependOld<T>(
140
214
  return clone as ArrayNonEmpty<T>;
141
215
  }
142
216
 
143
- // Returns a copy of the given array with the given value added at the start
217
+ /**
218
+ * Returns a copy of the array with the given value inserted at the start.
219
+ * @typeparam T - element type
220
+ * @param array - the source array
221
+ * @param value - value to insert at index 0
222
+ */
144
223
  export const prepend =
145
224
  `toSpliced` in Array.prototype ? _prependNew : _prependOld;
146
225
 
226
+ /**
227
+ * Internal helper to obtain the last element using modern `at`.
228
+ * @internal
229
+ */
147
230
  export function _lastNew<T>(arr: readonly T[]): T {
148
231
  return arr.at(-1)!;
149
232
  }
150
233
 
234
+ /**
235
+ * Internal helper to obtain the last element using index arithmetic.
236
+ * @internal
237
+ */
151
238
  export function _lastOld<T>(arr: readonly T[]): T {
152
239
  return arr[arr.length - 1];
153
240
  }
154
241
 
155
- // Returns the last element of the array
242
+ /**
243
+ * Returns the last element of the array.
244
+ * @typeparam T - element type
245
+ * @param arr - the array
246
+ */
156
247
  export const last = `at` in Array.prototype ? _lastNew : _lastOld;
157
248
 
249
+ /**
250
+ * Internal helper implementing an immutable index update via `with`.
251
+ * @internal
252
+ */
158
253
  export function _updateNew<T>(
159
254
  arr: readonly T[],
160
255
  index: number,
@@ -173,6 +268,10 @@ export function _updateNew<T>(
173
268
  return arr.with(index, newValue);
174
269
  }
175
270
 
271
+ /**
272
+ * Internal helper implementing an immutable index update via cloning.
273
+ * @internal
274
+ */
176
275
  export function _updateOld<T>(
177
276
  arr: readonly T[],
178
277
  index: number,
@@ -193,10 +292,20 @@ export function _updateOld<T>(
193
292
  return newArr;
194
293
  }
195
294
 
196
- // Returns a copy of the array where the element at given index is replaced by the given updater.
197
- // If the new element is the same as the old element, the original array is returned
295
+ /**
296
+ * Returns a copy of the array where the element at the given index is replaced using the provided updater.
297
+ * If the result value is identical (by `Object.is`) the original array is returned.
298
+ * @typeparam T - element type
299
+ * @param arr - the source array
300
+ * @param index - the index to update
301
+ * @param updater - value or function update description
302
+ */
198
303
  export const update = `with` in Array.prototype ? _updateNew : _updateOld;
199
304
 
305
+ /**
306
+ * Internal helper applying a modifier function via `with`.
307
+ * @internal
308
+ */
200
309
  export function _modNew<T>(
201
310
  arr: readonly T[],
202
311
  index: number,
@@ -216,6 +325,10 @@ export function _modNew<T>(
216
325
  return arr.with(index, newValue);
217
326
  }
218
327
 
328
+ /**
329
+ * Internal helper applying a modifier function via cloning.
330
+ * @internal
331
+ */
219
332
  export function _modOld<T>(
220
333
  arr: readonly T[],
221
334
  index: number,
@@ -237,33 +350,65 @@ export function _modOld<T>(
237
350
  return newArr;
238
351
  }
239
352
 
240
- // Returns a copy of the array where the element at given index is replaced by applying given function.
241
- // If the new element is the same as the old element, the original array is returned
353
+ /**
354
+ * Returns a copy of the array where the element at the given index is transformed by a modifier function.
355
+ * If the result value is identical (by `Object.is`) the original array is returned.
356
+ * @typeparam T - element type
357
+ * @param arr - the source array
358
+ * @param index - the index to modify
359
+ * @param f - modifier function receiving the current value
360
+ */
242
361
  export const mod = `with` in Array.prototype ? _modNew : _modOld;
243
362
 
363
+ /**
364
+ * Internal helper for inserting a value using `toSpliced`.
365
+ * @internal
366
+ */
244
367
  export function _insertNew<T>(arr: readonly T[], index: number, value: T): T[] {
245
368
  return arr.toSpliced(index, 0, value);
246
369
  }
247
370
 
371
+ /**
372
+ * Internal helper for inserting a value using legacy `splice` on a clone.
373
+ * @internal
374
+ */
248
375
  export function _insertOld<T>(arr: readonly T[], index: number, value: T): T[] {
249
376
  const clone = arr.slice();
250
377
  clone.splice(index, 0, value);
251
378
  return clone;
252
379
  }
253
380
 
254
- // Returns a copy of the array where at given index the given value is inserted
381
+ /**
382
+ * Returns a copy of the array where at the given index the provided value is inserted.
383
+ * @typeparam T - element type
384
+ * @param arr - the source array
385
+ * @param index - insertion index
386
+ * @param value - value to insert
387
+ */
255
388
  export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
256
389
 
257
- // Returns a copy of the array, without its first element
390
+ /**
391
+ * Returns a copy of the array without its first element.
392
+ * @typeparam T - element type
393
+ * @param arr - the source array
394
+ */
258
395
  export function tail<T>(arr: readonly T[]): T[] {
259
396
  return arr.slice(1);
260
397
  }
261
398
 
262
- // Returns a copy of the array, without its last element
399
+ /**
400
+ * Returns a copy of the array without its last element.
401
+ * @typeparam T - element type
402
+ * @param arr - the source array
403
+ */
263
404
  export function init<T>(arr: readonly T[]): T[] {
264
405
  return arr.slice(0, arr.length - 1);
265
406
  }
266
407
 
408
+ /**
409
+ * Internal helper providing an immutable `splice` using `toSpliced`.
410
+ * @internal
411
+ */
267
412
  export function _spliceNew<T>(
268
413
  arr: readonly T[],
269
414
  start: number,
@@ -273,6 +418,10 @@ export function _spliceNew<T>(
273
418
  return arr.toSpliced(start, deleteCount, ...items);
274
419
  }
275
420
 
421
+ /**
422
+ * Internal helper providing an immutable `splice` via cloning.
423
+ * @internal
424
+ */
276
425
  export function _spliceOld<T>(
277
426
  arr: readonly T[],
278
427
  start: number,
@@ -284,10 +433,21 @@ export function _spliceOld<T>(
284
433
  return clone;
285
434
  }
286
435
 
287
- // Immutable version of the array .splice command, always returns a new array
436
+ /**
437
+ * Immutable version of the array `.splice` command, always returning a new array.
438
+ * @typeparam T - element type
439
+ * @param arr - the source array
440
+ * @param start - start index
441
+ * @param deleteCount - number of elements to delete
442
+ * @param items - optional items to insert
443
+ */
288
444
  export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
289
445
 
290
- // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value)
446
+ /**
447
+ * Returns a copy of a (potentially) sparse array preserving sparsity (skips holes).
448
+ * @typeparam T - element type
449
+ * @param arr - the source sparse array
450
+ */
291
451
  export function copySparse<T>(arr: readonly T[]): T[] {
292
452
  const clone: T[] = [];
293
453
  for (const key in arr) {
@@ -296,8 +456,13 @@ export function copySparse<T>(arr: readonly T[]): T[] {
296
456
  return clone;
297
457
  }
298
458
 
299
- // Returns a copy of the array with given function applied to each element, where its 'sparse' property is kept
300
- // (sparse = not all indices have a value)
459
+ /**
460
+ * Returns a copy of a sparse array applying the given function to each present element, preserving holes.
461
+ * @typeparam T - source element type
462
+ * @typeparam T2 - result element type
463
+ * @param arr - the source sparse array
464
+ * @param f - mapping function
465
+ */
301
466
  export function mapSparse<T, T2>(
302
467
  arr: readonly T[],
303
468
  f: (value: T, index: number) => T2
@@ -1,9 +1,21 @@
1
- // Returns the first element of a 2-Tuple
1
+ /**
2
+ * Returns the first element of a 2-tuple.
3
+ * @typeparam K - the first element type
4
+ * @typeparam V - the second element type
5
+ * @param entry - the tuple
6
+ * @returns the first element
7
+ */
2
8
  export function first<K, V>(entry: readonly [K, V]): K {
3
9
  return entry[0];
4
10
  }
5
11
 
6
- // Returns the second element of a 2-Tuple
12
+ /**
13
+ * Returns the second element of a 2-tuple.
14
+ * @typeparam K - the first element type
15
+ * @typeparam V - the second element type
16
+ * @param entry - the tuple
17
+ * @returns the second element
18
+ */
7
19
  export function second<K, V>(entry: readonly [K, V]): V {
8
20
  return entry[1];
9
21
  }
@@ -1,6 +1,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * The `@rimbu/base` package provides foundational immutable array utilities, tuple helpers,
5
+ * plain‑object type predicates and structured error types that power all other Rimbu collections.<br/>
6
+ * Use it directly when you need low‑level, performance‑aware primitives for persistent data
7
+ * structures without pulling in the higher‑level collection packages.<br/>
8
+ * See the Rimbu docs and API reference for more information.
9
+ */
1
10
  export * as Arr from './arr.mts';
2
11
  export * as Entry from './entry.mts';
3
12
  export * as RimbuError from './rimbu-error.mts';
4
13
  export * from './plain-object.mts';
5
14
 
15
+ // Internal exports (may change without notice)
6
16
  export * from './internal.mts';