@rimbu/base 2.0.4 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimbu/base",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Utilities to implement Rimbu collections",
5
5
  "keywords": [
6
6
  "array",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "repository": {
25
25
  "type": "git",
26
- "url": "https://github.com/rimbu-org/rimbu.git",
26
+ "url": "https://github.com/rimbu-org/rimbu",
27
27
  "directory": "packages/base"
28
28
  },
29
29
  "type": "module",
@@ -32,7 +32,6 @@
32
32
  "types": "./dist/cjs/index.d.cts",
33
33
  "exports": {
34
34
  ".": {
35
- "bun": "./dist/bun/index.mts",
36
35
  "import": {
37
36
  "types": "./dist/esm/index.d.mts",
38
37
  "default": "./dist/esm/index.mjs"
@@ -49,8 +48,7 @@
49
48
  ],
50
49
  "scripts": {
51
50
  "build": "yarn clean && yarn bundle",
52
- "bundle": "yarn bundle:cjs && yarn bundle:esm && yarn bundle:bun",
53
- "bundle:bun": "node ../../config/bunnify.mjs -mode bun",
51
+ "bundle": "yarn bundle:cjs && yarn bundle:esm",
54
52
  "bundle:cjs": "yarn bundle:cjs-prepare && yarn bundle:cjs-build && yarn bundle:cjs-clean",
55
53
  "bundle:cjs-prepare": "node ../../config/bunnify.mjs -mode cjs",
56
54
  "bundle:cjs-build": "tsc -p tsconfig.cjs.json",
@@ -68,10 +66,10 @@
68
66
  "typecheck": "tsc"
69
67
  },
70
68
  "dependencies": {
71
- "@rimbu/common": "^2.0.4"
69
+ "@rimbu/common": "^2.0.6"
72
70
  },
73
71
  "publishConfig": {
74
72
  "access": "public"
75
73
  },
76
- "gitHead": "bc6bc82af86461c423ba459d6d9809efdd5ffd61"
74
+ "gitHead": "0d946ea05fda8261f1c55c3bcd6527ed793b90b5"
77
75
  }
package/dist/bun/arr.mts DELETED
@@ -1,477 +0,0 @@
1
- import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
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
- */
11
- export function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
12
- return array.toSpliced(array.length, 0, value) as ArrayNonEmpty<T>;
13
- }
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
- */
23
- export function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
24
- const clone = array.slice();
25
- clone.push(value);
26
- return clone as ArrayNonEmpty<T>;
27
- }
28
-
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
- */
37
- export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
38
-
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
- */
46
- export function concat<T>(
47
- first: readonly T[],
48
- second: readonly T[]
49
- ): readonly T[] {
50
- if (first.length === 0) return second;
51
- if (second.length === 0) return first;
52
- return first.concat(second);
53
- }
54
-
55
- /**
56
- * Internal helper to create a reversed copy using modern `toReversed` with optional slicing.
57
- * @internal
58
- */
59
- export function _reverseNew<T>(
60
- array: readonly T[],
61
- start?: number,
62
- end?: number
63
- ): T[] {
64
- const source =
65
- undefined !== start || undefined !== end
66
- ? array.slice(start ?? 0, (end ?? array.length - 1) + 1)
67
- : array;
68
-
69
- return source.toReversed();
70
- }
71
-
72
- /**
73
- * Internal helper to create a reversed copy using manual iteration (legacy fallback).
74
- * @internal
75
- */
76
- export function _reverseOld<T>(
77
- array: readonly T[],
78
- start?: number,
79
- end?: number
80
- ): T[] {
81
- const _start = start ?? 0;
82
- const _end = end ?? array.length - 1;
83
- const length = _end - _start + 1;
84
- const res = [] as T[];
85
-
86
- let arrayIndex = _start - 1;
87
- let resIndex = length - 1;
88
-
89
- while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex];
90
-
91
- return res;
92
- }
93
-
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
- */
101
- export const reverse =
102
- 'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
103
-
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
- */
113
- export function forEach<T>(
114
- array: readonly T[],
115
- f: (value: T, index: number, halt: () => void) => void,
116
- state: TraverseState = TraverseState(),
117
- reversed = false
118
- ): void {
119
- if (state.halted) return;
120
-
121
- const { halt } = state;
122
-
123
- if (reversed) {
124
- let i = array.length;
125
-
126
- while (!state.halted && --i >= 0) {
127
- f(array[i], state.nextIndex(), halt);
128
- }
129
- } else {
130
- const length = array.length;
131
- let i = -1;
132
-
133
- while (!state.halted && ++i < length) {
134
- f(array[i], state.nextIndex(), halt);
135
- }
136
- }
137
- }
138
-
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
- */
148
- export function map<T, R>(
149
- array: readonly T[],
150
- f: (value: T, index: number) => R,
151
- indexOffset = 0
152
- ): R[] {
153
- if (indexOffset === 0) {
154
- // without offset, can use standard array map
155
- return array.map(f);
156
- }
157
-
158
- const result: R[] = [];
159
-
160
- let index = indexOffset;
161
- let i = -1;
162
- const length = array.length;
163
- while (++i < length) {
164
- result[i] = f(array[i], index++);
165
- }
166
- return result;
167
- }
168
-
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
- */
177
- export function reverseMap<T, R>(
178
- array: readonly T[],
179
- f: (value: T, index: number) => R,
180
- indexOffset = 0
181
- ): R[] {
182
- const result: R[] = [];
183
-
184
- let index = indexOffset;
185
- let arrayIndex = array.length;
186
- let resultIndex = 0;
187
- while (--arrayIndex >= 0)
188
- result[resultIndex++] = f(array[arrayIndex], index++);
189
-
190
- return result;
191
- }
192
-
193
- /**
194
- * Internal helper to prepend a value using `toSpliced`.
195
- * @internal
196
- */
197
- export function _prependNew<T>(
198
- array: readonly T[],
199
- value: T
200
- ): ArrayNonEmpty<T> {
201
- return array.toSpliced(0, 0, value) as ArrayNonEmpty<T>;
202
- }
203
-
204
- /**
205
- * Internal helper to prepend a value using legacy cloning.
206
- * @internal
207
- */
208
- export function _prependOld<T>(
209
- array: readonly T[],
210
- value: T
211
- ): ArrayNonEmpty<T> {
212
- const clone = array.slice();
213
- clone.unshift(value);
214
- return clone as ArrayNonEmpty<T>;
215
- }
216
-
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
- */
223
- export const prepend =
224
- `toSpliced` in Array.prototype ? _prependNew : _prependOld;
225
-
226
- /**
227
- * Internal helper to obtain the last element using modern `at`.
228
- * @internal
229
- */
230
- export function _lastNew<T>(arr: readonly T[]): T {
231
- return arr.at(-1)!;
232
- }
233
-
234
- /**
235
- * Internal helper to obtain the last element using index arithmetic.
236
- * @internal
237
- */
238
- export function _lastOld<T>(arr: readonly T[]): T {
239
- return arr[arr.length - 1];
240
- }
241
-
242
- /**
243
- * Returns the last element of the array.
244
- * @typeparam T - element type
245
- * @param arr - the array
246
- */
247
- export const last = `at` in Array.prototype ? _lastNew : _lastOld;
248
-
249
- /**
250
- * Internal helper implementing an immutable index update via `with`.
251
- * @internal
252
- */
253
- export function _updateNew<T>(
254
- arr: readonly T[],
255
- index: number,
256
- updater: Update<T>
257
- ): readonly T[] {
258
- if (index < 0 || index >= arr.length) {
259
- return arr;
260
- }
261
- const curValue = arr[index];
262
-
263
- const newValue = Update(curValue, updater);
264
- if (Object.is(newValue, curValue)) {
265
- return arr;
266
- }
267
-
268
- return arr.with(index, newValue);
269
- }
270
-
271
- /**
272
- * Internal helper implementing an immutable index update via cloning.
273
- * @internal
274
- */
275
- export function _updateOld<T>(
276
- arr: readonly T[],
277
- index: number,
278
- updater: Update<T>
279
- ): readonly T[] {
280
- if (index < 0 || index >= arr.length) {
281
- return arr;
282
- }
283
- const curValue = arr[index];
284
-
285
- const newValue = Update(curValue, updater);
286
- if (Object.is(newValue, curValue)) {
287
- return arr;
288
- }
289
-
290
- const newArr = arr.slice();
291
- newArr[index] = newValue;
292
- return newArr;
293
- }
294
-
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
- */
303
- export const update = `with` in Array.prototype ? _updateNew : _updateOld;
304
-
305
- /**
306
- * Internal helper applying a modifier function via `with`.
307
- * @internal
308
- */
309
- export function _modNew<T>(
310
- arr: readonly T[],
311
- index: number,
312
- f: (value: T) => T
313
- ): readonly T[] {
314
- if (index < 0 || index >= arr.length) {
315
- return arr;
316
- }
317
-
318
- const curValue = arr[index];
319
- const newValue = f(curValue);
320
-
321
- if (Object.is(newValue, curValue)) {
322
- return arr;
323
- }
324
-
325
- return arr.with(index, newValue);
326
- }
327
-
328
- /**
329
- * Internal helper applying a modifier function via cloning.
330
- * @internal
331
- */
332
- export function _modOld<T>(
333
- arr: readonly T[],
334
- index: number,
335
- f: (value: T) => T
336
- ): readonly T[] {
337
- if (index < 0 || index >= arr.length) {
338
- return arr;
339
- }
340
-
341
- const curValue = arr[index];
342
- const newValue = f(curValue);
343
-
344
- if (Object.is(newValue, curValue)) {
345
- return arr;
346
- }
347
-
348
- const newArr = arr.slice();
349
- newArr[index] = newValue;
350
- return newArr;
351
- }
352
-
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
- */
361
- export const mod = `with` in Array.prototype ? _modNew : _modOld;
362
-
363
- /**
364
- * Internal helper for inserting a value using `toSpliced`.
365
- * @internal
366
- */
367
- export function _insertNew<T>(arr: readonly T[], index: number, value: T): T[] {
368
- return arr.toSpliced(index, 0, value);
369
- }
370
-
371
- /**
372
- * Internal helper for inserting a value using legacy `splice` on a clone.
373
- * @internal
374
- */
375
- export function _insertOld<T>(arr: readonly T[], index: number, value: T): T[] {
376
- const clone = arr.slice();
377
- clone.splice(index, 0, value);
378
- return clone;
379
- }
380
-
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
- */
388
- export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
389
-
390
- /**
391
- * Returns a copy of the array without its first element.
392
- * @typeparam T - element type
393
- * @param arr - the source array
394
- */
395
- export function tail<T>(arr: readonly T[]): T[] {
396
- return arr.slice(1);
397
- }
398
-
399
- /**
400
- * Returns a copy of the array without its last element.
401
- * @typeparam T - element type
402
- * @param arr - the source array
403
- */
404
- export function init<T>(arr: readonly T[]): T[] {
405
- return arr.slice(0, arr.length - 1);
406
- }
407
-
408
- /**
409
- * Internal helper providing an immutable `splice` using `toSpliced`.
410
- * @internal
411
- */
412
- export function _spliceNew<T>(
413
- arr: readonly T[],
414
- start: number,
415
- deleteCount: number,
416
- ...items: T[]
417
- ): T[] {
418
- return arr.toSpliced(start, deleteCount, ...items);
419
- }
420
-
421
- /**
422
- * Internal helper providing an immutable `splice` via cloning.
423
- * @internal
424
- */
425
- export function _spliceOld<T>(
426
- arr: readonly T[],
427
- start: number,
428
- deleteCount: number,
429
- ...items: T[]
430
- ): T[] {
431
- const clone = arr.slice();
432
- clone.splice(start, deleteCount, ...items);
433
- return clone;
434
- }
435
-
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
- */
444
- export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
445
-
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
- */
451
- export function copySparse<T>(arr: readonly T[]): T[] {
452
- const clone: T[] = [];
453
- for (const key in arr) {
454
- clone[key] = arr[key];
455
- }
456
- return clone;
457
- }
458
-
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
- */
466
- export function mapSparse<T, T2>(
467
- arr: readonly T[],
468
- f: (value: T, index: number) => T2
469
- ): T2[] {
470
- const result: T2[] = Array(arr.length);
471
-
472
- for (const key in arr) {
473
- result[key] = f(arr[key], key as any);
474
- }
475
-
476
- return result;
477
- }
@@ -1,21 +0,0 @@
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
- */
8
- export function first<K, V>(entry: readonly [K, V]): K {
9
- return entry[0];
10
- }
11
-
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
- */
19
- export function second<K, V>(entry: readonly [K, V]): V {
20
- return entry[1];
21
- }
@@ -1,16 +0,0 @@
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
- */
10
- export * as Arr from './arr.mts';
11
- export * as Entry from './entry.mts';
12
- export * as RimbuError from './rimbu-error.mts';
13
- export * from './plain-object.mts';
14
-
15
- // Internal exports (may change without notice)
16
- export * from './internal.mts';
@@ -1 +0,0 @@
1
- export * from './token.mts';
@@ -1,95 +0,0 @@
1
- /**
2
- * Matches any type of function
3
- */
4
- export type AnyFunc = (...args: any[]) => any;
5
-
6
- /**
7
- * Gives true if the given type T is a function, false otherwise.
8
- * @typeparam T - the input type
9
- */
10
- export type IsAnyFunc<T> = AnyFunc extends T ? true : false;
11
-
12
- /**
13
- * A predicate type for any record that resolves to true if any of the record
14
- * properties is a function, false otherwise.
15
- * This is useful to have a coarse discrimination between pure data objects and class instances.
16
- * @typeparam T - the input type
17
- */
18
- export type IsObjWithoutFunctions<T> = AnyFunc extends T[keyof T]
19
- ? false
20
- : true;
21
-
22
- /**
23
- * A predicate type that resolves to true if the given type satisfies:
24
- * - it is an object type (not a primitive)
25
- * - it is not a function
26
- * - it is not iterable
27
- * - it does not have any properties that are functions
28
- * Otherwise, it resolves to false
29
- * @typeparam T - the input type
30
- */
31
- export type IsPlainObj<T> = T extends
32
- | null
33
- | undefined
34
- | number
35
- | string
36
- | boolean
37
- | bigint
38
- | symbol
39
- | AnyFunc
40
- | Iterable<any>
41
- | AsyncIterable<any>
42
- ? false
43
- : IsObjWithoutFunctions<T>;
44
-
45
- /**
46
- * Utility type that will only accept objects that are considered 'plain objects' according
47
- * to the `IsPlainObj` predicate type.
48
- * @typeparam T - the value type to test
49
- */
50
- export type PlainObj<T> = IsPlainObj<T> extends true ? T : never;
51
-
52
- /**
53
- * Utility type that will only return true if the input type T is equal to `any`.
54
- * @typeparam T - the value type to test
55
- */
56
- export type IsAny<T> = 0 extends 1 & T ? true : false;
57
-
58
- /**
59
- * Utility type that will only return true if the input type T is a (readonly) array.
60
- * @typeparm T - the value type to test
61
- */
62
- export type IsArray<T> = T extends readonly any[] ? true : false;
63
-
64
- /**
65
- * Utility type to exclude any types that are iterable. Useful in cases where
66
- * plain objects are required as inputs but not arrays.
67
- */
68
- export type NotIterable = {
69
- [Symbol.iterator]?: never;
70
- };
71
-
72
- /**
73
- * Companion function to the `IsRecord<T>` type that checks whether the given object is a pure
74
- * data object.
75
- * @param obj - the object to check
76
- * @returns true if the given object is a pure data object
77
- * @note does not check whether a record's properties are not functions
78
- */
79
- export function isPlainObj(obj: any): obj is object {
80
- return (
81
- typeof obj === 'object' &&
82
- null !== obj &&
83
- (obj.constructor === Object || !(obj.constructor instanceof Function)) &&
84
- !(Symbol.iterator in obj) &&
85
- !(Symbol.asyncIterator in obj)
86
- );
87
- }
88
-
89
- /**
90
- * Returns true if the given object is Iterable
91
- * @param obj - the object to check
92
- */
93
- export function isIterable(obj: any): obj is Iterable<unknown> {
94
- return obj !== null && typeof obj === 'object' && Symbol.iterator in obj;
95
- }
@@ -1,64 +0,0 @@
1
- import { ErrBase } from '@rimbu/common';
2
-
3
- /**
4
- * Error thrown when an operation assumes a collection is non-empty but it is empty.
5
- */
6
- export class EmptyCollectionAssumedNonEmptyError extends ErrBase.CustomError {
7
- constructor() {
8
- super('empty collection was assumbed to be non-empty');
9
- }
10
- }
11
-
12
- /**
13
- * Error thrown when a builder is modified while it is being iterated.
14
- */
15
- export class ModifiedBuilderWhileLoopingOverItError extends ErrBase.CustomError {
16
- constructor() {
17
- super('an attempt was made to modify a builder while looping over it');
18
- }
19
- }
20
-
21
- /**
22
- * Error indicating an unexpected internal state. Users are encouraged to file an issue.
23
- */
24
- export class InvalidStateError extends ErrBase.CustomError {
25
- constructor() {
26
- super(
27
- "something happend that shouldn't happen, please consider creating an issue"
28
- );
29
- }
30
- }
31
-
32
- /**
33
- * Error indicating incorrect usage of the API.
34
- */
35
- export class InvalidUsageError extends ErrBase.CustomError {}
36
-
37
- /**
38
- * Throws an `EmptyCollectionAssumedNonEmptyError`.
39
- */
40
- export function throwEmptyCollectionAssumedNonEmptyError(): never {
41
- throw new EmptyCollectionAssumedNonEmptyError();
42
- }
43
-
44
- /**
45
- * Throws a `ModifiedBuilderWhileLoopingOverItError`.
46
- */
47
- export function throwModifiedBuilderWhileLoopingOverItError(): never {
48
- throw new ModifiedBuilderWhileLoopingOverItError();
49
- }
50
-
51
- /**
52
- * Throws an `InvalidStateError`.
53
- */
54
- export function throwInvalidStateError(): never {
55
- throw new InvalidStateError();
56
- }
57
-
58
- /**
59
- * Throws an `InvalidUsageError` with the provided message.
60
- * @param msg - context message describing the invalid usage
61
- */
62
- export function throwInvalidUsageError(msg: string): never {
63
- throw new InvalidUsageError(msg);
64
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Unique symbol used as a nominal token within the base package.
3
- * Can be employed for branding or sentinel values.
4
- */
5
- export const Token = Symbol('Token');
6
- /**
7
- * Type alias representing the Token symbol.
8
- */
9
- export type Token = typeof Token;