@rimbu/base 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bun/arr.mts CHANGED
@@ -1,12 +1,18 @@
1
- import { Update, TraverseState, type ArrayNonEmpty } from '@rimbu/common';
1
+ import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
2
2
 
3
- // Returns a copy of the array with the given value appended
4
- export function append<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
3
+ export function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
4
+ return array.toSpliced(array.length, 0, value) as ArrayNonEmpty<T>;
5
+ }
6
+
7
+ export function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
5
8
  const clone = array.slice();
6
9
  clone.push(value);
7
10
  return clone as ArrayNonEmpty<T>;
8
11
  }
9
12
 
13
+ // Returns a copy of the array with the given value appended
14
+ export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
15
+
10
16
  // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty
11
17
  export function concat<T>(
12
18
  first: readonly T[],
@@ -17,23 +23,41 @@ export function concat<T>(
17
23
  return first.concat(second);
18
24
  }
19
25
 
20
- // Returns an copy of the array between the start and end indices, with the elements in reversed order.
21
- export function reverse<T>(
26
+ export function _reverseNew<T>(
27
+ array: readonly T[],
28
+ start?: number,
29
+ end?: number
30
+ ): T[] {
31
+ const source =
32
+ undefined !== start || undefined !== end
33
+ ? array.slice(start ?? 0, (end ?? array.length - 1) + 1)
34
+ : array;
35
+
36
+ return source.toReversed();
37
+ }
38
+
39
+ export function _reverseOld<T>(
22
40
  array: readonly T[],
23
- start = 0,
24
- end = array.length - 1
41
+ start?: number,
42
+ end?: number
25
43
  ): T[] {
26
- const length = end - start + 1;
44
+ const _start = start ?? 0;
45
+ const _end = end ?? array.length - 1;
46
+ const length = _end - _start + 1;
27
47
  const res = [] as T[];
28
48
 
29
- let arrayIndex = start - 1;
49
+ let arrayIndex = _start - 1;
30
50
  let resIndex = length - 1;
31
51
 
32
- while (++arrayIndex <= end) res[resIndex--] = array[arrayIndex];
52
+ while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex];
33
53
 
34
54
  return res;
35
55
  }
36
56
 
57
+ // Returns an copy of the array between the start and end indices, with the elements in reversed order.
58
+ export const reverse =
59
+ 'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
60
+
37
61
  // Performs given function on each element of the array, in reverse order if 'reversed' is true.
38
62
  export function forEach<T>(
39
63
  array: readonly T[],
@@ -67,6 +91,11 @@ export function map<T, R>(
67
91
  f: (value: T, index: number) => R,
68
92
  indexOffset = 0
69
93
  ): R[] {
94
+ if (indexOffset === 0) {
95
+ // without offset, can use standard array map
96
+ return array.map(f);
97
+ }
98
+
70
99
  const result: R[] = [];
71
100
 
72
101
  let index = indexOffset;
@@ -95,59 +124,136 @@ export function reverseMap<T, R>(
95
124
  return result;
96
125
  }
97
126
 
98
- // Returns a copy of the given array with the given value added at the start
99
- export function prepend<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
127
+ export function _prependNew<T>(
128
+ array: readonly T[],
129
+ value: T
130
+ ): ArrayNonEmpty<T> {
131
+ return array.toSpliced(0, 0, value) as ArrayNonEmpty<T>;
132
+ }
133
+
134
+ export function _prependOld<T>(
135
+ array: readonly T[],
136
+ value: T
137
+ ): ArrayNonEmpty<T> {
100
138
  const clone = array.slice();
101
139
  clone.unshift(value);
102
140
  return clone as ArrayNonEmpty<T>;
103
141
  }
104
142
 
105
- // Returns the last element of the array
106
- export function last<T>(arr: readonly T[]): T {
143
+ // Returns a copy of the given array with the given value added at the start
144
+ export const prepend =
145
+ `toSpliced` in Array.prototype ? _prependNew : _prependOld;
146
+
147
+ export function _lastNew<T>(arr: readonly T[]): T {
148
+ return arr.at(-1)!;
149
+ }
150
+
151
+ export function _lastOld<T>(arr: readonly T[]): T {
107
152
  return arr[arr.length - 1];
108
153
  }
109
154
 
110
- // Returns a copy of the array where the element at given index is replaced by the given updater.
111
- // If the new element is the same as the old element, the original array is returned
112
- export function update<T>(
155
+ // Returns the last element of the array
156
+ export const last = `at` in Array.prototype ? _lastNew : _lastOld;
157
+
158
+ export function _updateNew<T>(
159
+ arr: readonly T[],
160
+ index: number,
161
+ updater: Update<T>
162
+ ): readonly T[] {
163
+ if (index < 0 || index >= arr.length) {
164
+ return arr;
165
+ }
166
+ const curValue = arr[index];
167
+
168
+ const newValue = Update(curValue, updater);
169
+ if (Object.is(newValue, curValue)) {
170
+ return arr;
171
+ }
172
+
173
+ return arr.with(index, newValue);
174
+ }
175
+
176
+ export function _updateOld<T>(
113
177
  arr: readonly T[],
114
178
  index: number,
115
179
  updater: Update<T>
116
180
  ): readonly T[] {
117
- if (index < 0 || index >= arr.length) return arr;
181
+ if (index < 0 || index >= arr.length) {
182
+ return arr;
183
+ }
118
184
  const curValue = arr[index];
119
185
 
120
186
  const newValue = Update(curValue, updater);
121
- if (Object.is(newValue, curValue)) return arr;
187
+ if (Object.is(newValue, curValue)) {
188
+ return arr;
189
+ }
190
+
122
191
  const newArr = arr.slice();
123
192
  newArr[index] = newValue;
124
193
  return newArr;
125
194
  }
126
195
 
127
- // Returns a copy of the array where the element at given index is replaced by applying given function.
196
+ // Returns a copy of the array where the element at given index is replaced by the given updater.
128
197
  // If the new element is the same as the old element, the original array is returned
129
- export function mod<T>(
198
+ export const update = `with` in Array.prototype ? _updateNew : _updateOld;
199
+
200
+ export function _modNew<T>(
130
201
  arr: readonly T[],
131
202
  index: number,
132
203
  f: (value: T) => T
133
204
  ): readonly T[] {
134
- if (index < 0 || index >= arr.length) return arr;
205
+ if (index < 0 || index >= arr.length) {
206
+ return arr;
207
+ }
135
208
 
136
209
  const curValue = arr[index];
137
210
  const newValue = f(curValue);
138
- if (Object.is(newValue, curValue)) return arr;
211
+
212
+ if (Object.is(newValue, curValue)) {
213
+ return arr;
214
+ }
215
+
216
+ return arr.with(index, newValue);
217
+ }
218
+
219
+ export function _modOld<T>(
220
+ arr: readonly T[],
221
+ index: number,
222
+ f: (value: T) => T
223
+ ): readonly T[] {
224
+ if (index < 0 || index >= arr.length) {
225
+ return arr;
226
+ }
227
+
228
+ const curValue = arr[index];
229
+ const newValue = f(curValue);
230
+
231
+ if (Object.is(newValue, curValue)) {
232
+ return arr;
233
+ }
234
+
139
235
  const newArr = arr.slice();
140
236
  newArr[index] = newValue;
141
237
  return newArr;
142
238
  }
143
239
 
144
- // Returns a copy of the array where at given index the given value is inserted
145
- export function insert<T>(arr: readonly T[], index: number, value: T): T[] {
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
242
+ export const mod = `with` in Array.prototype ? _modNew : _modOld;
243
+
244
+ export function _insertNew<T>(arr: readonly T[], index: number, value: T): T[] {
245
+ return arr.toSpliced(index, 0, value);
246
+ }
247
+
248
+ export function _insertOld<T>(arr: readonly T[], index: number, value: T): T[] {
146
249
  const clone = arr.slice();
147
250
  clone.splice(index, 0, value);
148
251
  return clone;
149
252
  }
150
253
 
254
+ // Returns a copy of the array where at given index the given value is inserted
255
+ export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
256
+
151
257
  // Returns a copy of the array, without its first element
152
258
  export function tail<T>(arr: readonly T[]): T[] {
153
259
  return arr.slice(1);
@@ -158,8 +264,16 @@ export function init<T>(arr: readonly T[]): T[] {
158
264
  return arr.slice(0, arr.length - 1);
159
265
  }
160
266
 
161
- // Immutable version of the array .splice command, always returns a new array
162
- export function splice<T>(
267
+ export function _spliceNew<T>(
268
+ arr: readonly T[],
269
+ start: number,
270
+ deleteCount: number,
271
+ ...items: T[]
272
+ ): T[] {
273
+ return arr.toSpliced(start, deleteCount, ...items);
274
+ }
275
+
276
+ export function _spliceOld<T>(
163
277
  arr: readonly T[],
164
278
  start: number,
165
279
  deleteCount: number,
@@ -170,6 +284,9 @@ export function splice<T>(
170
284
  return clone;
171
285
  }
172
286
 
287
+ // Immutable version of the array .splice command, always returns a new array
288
+ export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
289
+
173
290
  // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value)
174
291
  export function copySparse<T>(arr: readonly T[]): T[] {
175
292
  const clone: T[] = [];
package/dist/cjs/arr.cjs CHANGED
@@ -20,6 +20,22 @@ var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: tr
20
20
  // src/arr.mts
21
21
  var arr_exports = {};
22
22
  __export(arr_exports, {
23
+ _appendNew: () => _appendNew,
24
+ _appendOld: () => _appendOld,
25
+ _insertNew: () => _insertNew,
26
+ _insertOld: () => _insertOld,
27
+ _lastNew: () => _lastNew,
28
+ _lastOld: () => _lastOld,
29
+ _modNew: () => _modNew,
30
+ _modOld: () => _modOld,
31
+ _prependNew: () => _prependNew,
32
+ _prependOld: () => _prependOld,
33
+ _reverseNew: () => _reverseNew,
34
+ _reverseOld: () => _reverseOld,
35
+ _spliceNew: () => _spliceNew,
36
+ _spliceOld: () => _spliceOld,
37
+ _updateNew: () => _updateNew,
38
+ _updateOld: () => _updateOld,
23
39
  append: () => append,
24
40
  concat: () => concat,
25
41
  copySparse: () => copySparse,
@@ -39,11 +55,15 @@ __export(arr_exports, {
39
55
  });
40
56
  module.exports = __toCommonJS(arr_exports);
41
57
  var import_common = require("@rimbu/common");
42
- function append(array, value) {
58
+ function _appendNew(array, value) {
59
+ return array.toSpliced(array.length, 0, value);
60
+ }
61
+ function _appendOld(array, value) {
43
62
  const clone = array.slice();
44
63
  clone.push(value);
45
64
  return clone;
46
65
  }
66
+ var append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
47
67
  function concat(first, second) {
48
68
  if (first.length === 0)
49
69
  return second;
@@ -51,15 +71,22 @@ function concat(first, second) {
51
71
  return first;
52
72
  return first.concat(second);
53
73
  }
54
- function reverse(array, start = 0, end = array.length - 1) {
55
- const length = end - start + 1;
74
+ function _reverseNew(array, start, end) {
75
+ const source = void 0 !== start || void 0 !== end ? array.slice(start ?? 0, (end ?? array.length - 1) + 1) : array;
76
+ return source.toReversed();
77
+ }
78
+ function _reverseOld(array, start, end) {
79
+ const _start = start ?? 0;
80
+ const _end = end ?? array.length - 1;
81
+ const length = _end - _start + 1;
56
82
  const res = [];
57
- let arrayIndex = start - 1;
83
+ let arrayIndex = _start - 1;
58
84
  let resIndex = length - 1;
59
- while (++arrayIndex <= end)
85
+ while (++arrayIndex <= _end)
60
86
  res[resIndex--] = array[arrayIndex];
61
87
  return res;
62
88
  }
89
+ var reverse = "toReversed" in Array.prototype ? _reverseNew : _reverseOld;
63
90
  function forEach(array, f, state = (0, import_common.TraverseState)(), reversed = false) {
64
91
  if (state.halted)
65
92
  return;
@@ -78,6 +105,9 @@ function forEach(array, f, state = (0, import_common.TraverseState)(), reversed
78
105
  }
79
106
  }
80
107
  function map(array, f, indexOffset = 0) {
108
+ if (indexOffset === 0) {
109
+ return array.map(f);
110
+ }
81
111
  const result = [];
82
112
  let index = indexOffset;
83
113
  let i = -1;
@@ -96,52 +126,96 @@ function reverseMap(array, f, indexOffset = 0) {
96
126
  result[resultIndex++] = f(array[arrayIndex], index++);
97
127
  return result;
98
128
  }
99
- function prepend(array, value) {
129
+ function _prependNew(array, value) {
130
+ return array.toSpliced(0, 0, value);
131
+ }
132
+ function _prependOld(array, value) {
100
133
  const clone = array.slice();
101
134
  clone.unshift(value);
102
135
  return clone;
103
136
  }
104
- function last(arr) {
137
+ var prepend = `toSpliced` in Array.prototype ? _prependNew : _prependOld;
138
+ function _lastNew(arr) {
139
+ return arr.at(-1);
140
+ }
141
+ function _lastOld(arr) {
105
142
  return arr[arr.length - 1];
106
143
  }
107
- function update(arr, index, updater) {
108
- if (index < 0 || index >= arr.length)
144
+ var last = `at` in Array.prototype ? _lastNew : _lastOld;
145
+ function _updateNew(arr, index, updater) {
146
+ if (index < 0 || index >= arr.length) {
109
147
  return arr;
148
+ }
149
+ const curValue = arr[index];
150
+ const newValue = (0, import_common.Update)(curValue, updater);
151
+ if (Object.is(newValue, curValue)) {
152
+ return arr;
153
+ }
154
+ return arr.with(index, newValue);
155
+ }
156
+ function _updateOld(arr, index, updater) {
157
+ if (index < 0 || index >= arr.length) {
158
+ return arr;
159
+ }
110
160
  const curValue = arr[index];
111
161
  const newValue = (0, import_common.Update)(curValue, updater);
112
- if (Object.is(newValue, curValue))
162
+ if (Object.is(newValue, curValue)) {
113
163
  return arr;
164
+ }
114
165
  const newArr = arr.slice();
115
166
  newArr[index] = newValue;
116
167
  return newArr;
117
168
  }
118
- function mod(arr, index, f) {
119
- if (index < 0 || index >= arr.length)
169
+ var update = `with` in Array.prototype ? _updateNew : _updateOld;
170
+ function _modNew(arr, index, f) {
171
+ if (index < 0 || index >= arr.length) {
172
+ return arr;
173
+ }
174
+ const curValue = arr[index];
175
+ const newValue = f(curValue);
176
+ if (Object.is(newValue, curValue)) {
177
+ return arr;
178
+ }
179
+ return arr.with(index, newValue);
180
+ }
181
+ function _modOld(arr, index, f) {
182
+ if (index < 0 || index >= arr.length) {
120
183
  return arr;
184
+ }
121
185
  const curValue = arr[index];
122
186
  const newValue = f(curValue);
123
- if (Object.is(newValue, curValue))
187
+ if (Object.is(newValue, curValue)) {
124
188
  return arr;
189
+ }
125
190
  const newArr = arr.slice();
126
191
  newArr[index] = newValue;
127
192
  return newArr;
128
193
  }
129
- function insert(arr, index, value) {
194
+ var mod = `with` in Array.prototype ? _modNew : _modOld;
195
+ function _insertNew(arr, index, value) {
196
+ return arr.toSpliced(index, 0, value);
197
+ }
198
+ function _insertOld(arr, index, value) {
130
199
  const clone = arr.slice();
131
200
  clone.splice(index, 0, value);
132
201
  return clone;
133
202
  }
203
+ var insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
134
204
  function tail(arr) {
135
205
  return arr.slice(1);
136
206
  }
137
207
  function init(arr) {
138
208
  return arr.slice(0, arr.length - 1);
139
209
  }
140
- function splice(arr, start, deleteCount, ...items) {
210
+ function _spliceNew(arr, start, deleteCount, ...items) {
211
+ return arr.toSpliced(start, deleteCount, ...items);
212
+ }
213
+ function _spliceOld(arr, start, deleteCount, ...items) {
141
214
  const clone = arr.slice();
142
215
  clone.splice(start, deleteCount, ...items);
143
216
  return clone;
144
217
  }
218
+ var splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
145
219
  function copySparse(arr) {
146
220
  const clone = [];
147
221
  for (const key in arr) {
@@ -158,6 +232,22 @@ function mapSparse(arr, f) {
158
232
  }
159
233
  // Annotate the CommonJS export names for ESM import in node:
160
234
  0 && (module.exports = {
235
+ _appendNew,
236
+ _appendOld,
237
+ _insertNew,
238
+ _insertOld,
239
+ _lastNew,
240
+ _lastOld,
241
+ _modNew,
242
+ _modOld,
243
+ _prependNew,
244
+ _prependOld,
245
+ _reverseNew,
246
+ _reverseOld,
247
+ _spliceNew,
248
+ _spliceOld,
249
+ _updateNew,
250
+ _updateOld,
161
251
  append,
162
252
  concat,
163
253
  copySparse,
@@ -32,6 +32,22 @@ module.exports = __toCommonJS(src_exports);
32
32
  // src/arr.mts
33
33
  var arr_exports = {};
34
34
  __export(arr_exports, {
35
+ _appendNew: () => _appendNew,
36
+ _appendOld: () => _appendOld,
37
+ _insertNew: () => _insertNew,
38
+ _insertOld: () => _insertOld,
39
+ _lastNew: () => _lastNew,
40
+ _lastOld: () => _lastOld,
41
+ _modNew: () => _modNew,
42
+ _modOld: () => _modOld,
43
+ _prependNew: () => _prependNew,
44
+ _prependOld: () => _prependOld,
45
+ _reverseNew: () => _reverseNew,
46
+ _reverseOld: () => _reverseOld,
47
+ _spliceNew: () => _spliceNew,
48
+ _spliceOld: () => _spliceOld,
49
+ _updateNew: () => _updateNew,
50
+ _updateOld: () => _updateOld,
35
51
  append: () => append,
36
52
  concat: () => concat,
37
53
  copySparse: () => copySparse,
@@ -50,11 +66,15 @@ __export(arr_exports, {
50
66
  update: () => update
51
67
  });
52
68
  var import_common = require("@rimbu/common");
53
- function append(array, value) {
69
+ function _appendNew(array, value) {
70
+ return array.toSpliced(array.length, 0, value);
71
+ }
72
+ function _appendOld(array, value) {
54
73
  const clone = array.slice();
55
74
  clone.push(value);
56
75
  return clone;
57
76
  }
77
+ var append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
58
78
  function concat(first2, second2) {
59
79
  if (first2.length === 0)
60
80
  return second2;
@@ -62,15 +82,22 @@ function concat(first2, second2) {
62
82
  return first2;
63
83
  return first2.concat(second2);
64
84
  }
65
- function reverse(array, start = 0, end = array.length - 1) {
66
- const length = end - start + 1;
85
+ function _reverseNew(array, start, end) {
86
+ const source = void 0 !== start || void 0 !== end ? array.slice(start ?? 0, (end ?? array.length - 1) + 1) : array;
87
+ return source.toReversed();
88
+ }
89
+ function _reverseOld(array, start, end) {
90
+ const _start = start ?? 0;
91
+ const _end = end ?? array.length - 1;
92
+ const length = _end - _start + 1;
67
93
  const res = [];
68
- let arrayIndex = start - 1;
94
+ let arrayIndex = _start - 1;
69
95
  let resIndex = length - 1;
70
- while (++arrayIndex <= end)
96
+ while (++arrayIndex <= _end)
71
97
  res[resIndex--] = array[arrayIndex];
72
98
  return res;
73
99
  }
100
+ var reverse = "toReversed" in Array.prototype ? _reverseNew : _reverseOld;
74
101
  function forEach(array, f, state = (0, import_common.TraverseState)(), reversed = false) {
75
102
  if (state.halted)
76
103
  return;
@@ -89,6 +116,9 @@ function forEach(array, f, state = (0, import_common.TraverseState)(), reversed
89
116
  }
90
117
  }
91
118
  function map(array, f, indexOffset = 0) {
119
+ if (indexOffset === 0) {
120
+ return array.map(f);
121
+ }
92
122
  const result = [];
93
123
  let index = indexOffset;
94
124
  let i = -1;
@@ -107,52 +137,96 @@ function reverseMap(array, f, indexOffset = 0) {
107
137
  result[resultIndex++] = f(array[arrayIndex], index++);
108
138
  return result;
109
139
  }
110
- function prepend(array, value) {
140
+ function _prependNew(array, value) {
141
+ return array.toSpliced(0, 0, value);
142
+ }
143
+ function _prependOld(array, value) {
111
144
  const clone = array.slice();
112
145
  clone.unshift(value);
113
146
  return clone;
114
147
  }
115
- function last(arr) {
148
+ var prepend = `toSpliced` in Array.prototype ? _prependNew : _prependOld;
149
+ function _lastNew(arr) {
150
+ return arr.at(-1);
151
+ }
152
+ function _lastOld(arr) {
116
153
  return arr[arr.length - 1];
117
154
  }
118
- function update(arr, index, updater) {
119
- if (index < 0 || index >= arr.length)
155
+ var last = `at` in Array.prototype ? _lastNew : _lastOld;
156
+ function _updateNew(arr, index, updater) {
157
+ if (index < 0 || index >= arr.length) {
120
158
  return arr;
159
+ }
160
+ const curValue = arr[index];
161
+ const newValue = (0, import_common.Update)(curValue, updater);
162
+ if (Object.is(newValue, curValue)) {
163
+ return arr;
164
+ }
165
+ return arr.with(index, newValue);
166
+ }
167
+ function _updateOld(arr, index, updater) {
168
+ if (index < 0 || index >= arr.length) {
169
+ return arr;
170
+ }
121
171
  const curValue = arr[index];
122
172
  const newValue = (0, import_common.Update)(curValue, updater);
123
- if (Object.is(newValue, curValue))
173
+ if (Object.is(newValue, curValue)) {
124
174
  return arr;
175
+ }
125
176
  const newArr = arr.slice();
126
177
  newArr[index] = newValue;
127
178
  return newArr;
128
179
  }
129
- function mod(arr, index, f) {
130
- if (index < 0 || index >= arr.length)
180
+ var update = `with` in Array.prototype ? _updateNew : _updateOld;
181
+ function _modNew(arr, index, f) {
182
+ if (index < 0 || index >= arr.length) {
183
+ return arr;
184
+ }
185
+ const curValue = arr[index];
186
+ const newValue = f(curValue);
187
+ if (Object.is(newValue, curValue)) {
188
+ return arr;
189
+ }
190
+ return arr.with(index, newValue);
191
+ }
192
+ function _modOld(arr, index, f) {
193
+ if (index < 0 || index >= arr.length) {
131
194
  return arr;
195
+ }
132
196
  const curValue = arr[index];
133
197
  const newValue = f(curValue);
134
- if (Object.is(newValue, curValue))
198
+ if (Object.is(newValue, curValue)) {
135
199
  return arr;
200
+ }
136
201
  const newArr = arr.slice();
137
202
  newArr[index] = newValue;
138
203
  return newArr;
139
204
  }
140
- function insert(arr, index, value) {
205
+ var mod = `with` in Array.prototype ? _modNew : _modOld;
206
+ function _insertNew(arr, index, value) {
207
+ return arr.toSpliced(index, 0, value);
208
+ }
209
+ function _insertOld(arr, index, value) {
141
210
  const clone = arr.slice();
142
211
  clone.splice(index, 0, value);
143
212
  return clone;
144
213
  }
214
+ var insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
145
215
  function tail(arr) {
146
216
  return arr.slice(1);
147
217
  }
148
218
  function init(arr) {
149
219
  return arr.slice(0, arr.length - 1);
150
220
  }
151
- function splice(arr, start, deleteCount, ...items) {
221
+ function _spliceNew(arr, start, deleteCount, ...items) {
222
+ return arr.toSpliced(start, deleteCount, ...items);
223
+ }
224
+ function _spliceOld(arr, start, deleteCount, ...items) {
152
225
  const clone = arr.slice();
153
226
  clone.splice(start, deleteCount, ...items);
154
227
  return clone;
155
228
  }
229
+ var splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
156
230
  function copySparse(arr) {
157
231
  const clone = [];
158
232
  for (const key in arr) {
package/dist/esm/arr.mjs CHANGED
@@ -1,10 +1,14 @@
1
- import { Update, TraverseState } from '@rimbu/common';
2
- // Returns a copy of the array with the given value appended
3
- export function append(array, value) {
1
+ import { TraverseState, Update } from '@rimbu/common';
2
+ export function _appendNew(array, value) {
3
+ return array.toSpliced(array.length, 0, value);
4
+ }
5
+ export function _appendOld(array, value) {
4
6
  const clone = array.slice();
5
7
  clone.push(value);
6
8
  return clone;
7
9
  }
10
+ // Returns a copy of the array with the given value appended
11
+ export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
8
12
  // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty
9
13
  export function concat(first, second) {
10
14
  if (first.length === 0)
@@ -13,16 +17,25 @@ export function concat(first, second) {
13
17
  return first;
14
18
  return first.concat(second);
15
19
  }
16
- // Returns an copy of the array between the start and end indices, with the elements in reversed order.
17
- export function reverse(array, start = 0, end = array.length - 1) {
18
- const length = end - start + 1;
20
+ export function _reverseNew(array, start, end) {
21
+ const source = undefined !== start || undefined !== end
22
+ ? array.slice(start ?? 0, (end ?? array.length - 1) + 1)
23
+ : array;
24
+ return source.toReversed();
25
+ }
26
+ export function _reverseOld(array, start, end) {
27
+ const _start = start ?? 0;
28
+ const _end = end ?? array.length - 1;
29
+ const length = _end - _start + 1;
19
30
  const res = [];
20
- let arrayIndex = start - 1;
31
+ let arrayIndex = _start - 1;
21
32
  let resIndex = length - 1;
22
- while (++arrayIndex <= end)
33
+ while (++arrayIndex <= _end)
23
34
  res[resIndex--] = array[arrayIndex];
24
35
  return res;
25
36
  }
37
+ // Returns an copy of the array between the start and end indices, with the elements in reversed order.
38
+ export const reverse = 'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
26
39
  // Performs given function on each element of the array, in reverse order if 'reversed' is true.
27
40
  export function forEach(array, f, state = TraverseState(), reversed = false) {
28
41
  if (state.halted)
@@ -44,6 +57,10 @@ export function forEach(array, f, state = TraverseState(), reversed = false) {
44
57
  }
45
58
  // Returns a copy of the array where given function is applied to each element
46
59
  export function map(array, f, indexOffset = 0) {
60
+ if (indexOffset === 0) {
61
+ // without offset, can use standard array map
62
+ return array.map(f);
63
+ }
47
64
  const result = [];
48
65
  let index = indexOffset;
49
66
  let i = -1;
@@ -63,48 +80,88 @@ export function reverseMap(array, f, indexOffset = 0) {
63
80
  result[resultIndex++] = f(array[arrayIndex], index++);
64
81
  return result;
65
82
  }
66
- // Returns a copy of the given array with the given value added at the start
67
- export function prepend(array, value) {
83
+ export function _prependNew(array, value) {
84
+ return array.toSpliced(0, 0, value);
85
+ }
86
+ export function _prependOld(array, value) {
68
87
  const clone = array.slice();
69
88
  clone.unshift(value);
70
89
  return clone;
71
90
  }
72
- // Returns the last element of the array
73
- export function last(arr) {
91
+ // Returns a copy of the given array with the given value added at the start
92
+ export const prepend = `toSpliced` in Array.prototype ? _prependNew : _prependOld;
93
+ export function _lastNew(arr) {
94
+ return arr.at(-1);
95
+ }
96
+ export function _lastOld(arr) {
74
97
  return arr[arr.length - 1];
75
98
  }
76
- // Returns a copy of the array where the element at given index is replaced by the given updater.
77
- // If the new element is the same as the old element, the original array is returned
78
- export function update(arr, index, updater) {
79
- if (index < 0 || index >= arr.length)
99
+ // Returns the last element of the array
100
+ export const last = `at` in Array.prototype ? _lastNew : _lastOld;
101
+ export function _updateNew(arr, index, updater) {
102
+ if (index < 0 || index >= arr.length) {
80
103
  return arr;
104
+ }
81
105
  const curValue = arr[index];
82
106
  const newValue = Update(curValue, updater);
83
- if (Object.is(newValue, curValue))
107
+ if (Object.is(newValue, curValue)) {
84
108
  return arr;
109
+ }
110
+ return arr.with(index, newValue);
111
+ }
112
+ export function _updateOld(arr, index, updater) {
113
+ if (index < 0 || index >= arr.length) {
114
+ return arr;
115
+ }
116
+ const curValue = arr[index];
117
+ const newValue = Update(curValue, updater);
118
+ if (Object.is(newValue, curValue)) {
119
+ return arr;
120
+ }
85
121
  const newArr = arr.slice();
86
122
  newArr[index] = newValue;
87
123
  return newArr;
88
124
  }
89
- // Returns a copy of the array where the element at given index is replaced by applying given function.
125
+ // Returns a copy of the array where the element at given index is replaced by the given updater.
90
126
  // If the new element is the same as the old element, the original array is returned
91
- export function mod(arr, index, f) {
92
- if (index < 0 || index >= arr.length)
127
+ export const update = `with` in Array.prototype ? _updateNew : _updateOld;
128
+ export function _modNew(arr, index, f) {
129
+ if (index < 0 || index >= arr.length) {
93
130
  return arr;
131
+ }
94
132
  const curValue = arr[index];
95
133
  const newValue = f(curValue);
96
- if (Object.is(newValue, curValue))
134
+ if (Object.is(newValue, curValue)) {
97
135
  return arr;
136
+ }
137
+ return arr.with(index, newValue);
138
+ }
139
+ export function _modOld(arr, index, f) {
140
+ if (index < 0 || index >= arr.length) {
141
+ return arr;
142
+ }
143
+ const curValue = arr[index];
144
+ const newValue = f(curValue);
145
+ if (Object.is(newValue, curValue)) {
146
+ return arr;
147
+ }
98
148
  const newArr = arr.slice();
99
149
  newArr[index] = newValue;
100
150
  return newArr;
101
151
  }
102
- // Returns a copy of the array where at given index the given value is inserted
103
- export function insert(arr, index, value) {
152
+ // Returns a copy of the array where the element at given index is replaced by applying given function.
153
+ // If the new element is the same as the old element, the original array is returned
154
+ export const mod = `with` in Array.prototype ? _modNew : _modOld;
155
+ export function _insertNew(arr, index, value) {
156
+ return arr.toSpliced(index, 0, value);
157
+ }
158
+ export function _insertOld(arr, index, value) {
104
159
  const clone = arr.slice();
105
160
  clone.splice(index, 0, value);
106
161
  return clone;
107
162
  }
163
+ // Returns a copy of the array where at given index the given value is inserted
164
+ export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
108
165
  // Returns a copy of the array, without its first element
109
166
  export function tail(arr) {
110
167
  return arr.slice(1);
@@ -113,12 +170,16 @@ export function tail(arr) {
113
170
  export function init(arr) {
114
171
  return arr.slice(0, arr.length - 1);
115
172
  }
116
- // Immutable version of the array .splice command, always returns a new array
117
- export function splice(arr, start, deleteCount, ...items) {
173
+ export function _spliceNew(arr, start, deleteCount, ...items) {
174
+ return arr.toSpliced(start, deleteCount, ...items);
175
+ }
176
+ export function _spliceOld(arr, start, deleteCount, ...items) {
118
177
  const clone = arr.slice();
119
178
  clone.splice(start, deleteCount, ...items);
120
179
  return clone;
121
180
  }
181
+ // Immutable version of the array .splice command, always returns a new array
182
+ export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
122
183
  // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value)
123
184
  export function copySparse(arr) {
124
185
  const clone = [];
@@ -1 +1 @@
1
- {"version":3,"file":"arr.mjs","sourceRoot":"","sources":["../../src/arr.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arr.mjs","sourceRoot":"","sources":["../../src/arr.mts"],"names":[],"mappings":"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"}
@@ -1,17 +1,33 @@
1
- import { Update, TraverseState, type ArrayNonEmpty } from '@rimbu/common';
2
- export declare function append<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
1
+ import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
2
+ export declare function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
3
+ export declare function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
4
+ export declare const append: typeof _appendNew;
3
5
  export declare function concat<T>(first: readonly T[], second: readonly T[]): readonly T[];
4
- export declare function reverse<T>(array: readonly T[], start?: number, end?: number): T[];
6
+ export declare function _reverseNew<T>(array: readonly T[], start?: number, end?: number): T[];
7
+ export declare function _reverseOld<T>(array: readonly T[], start?: number, end?: number): T[];
8
+ export declare const reverse: typeof _reverseNew;
5
9
  export declare function forEach<T>(array: readonly T[], f: (value: T, index: number, halt: () => void) => void, state?: TraverseState, reversed?: boolean): void;
6
10
  export declare function map<T, R>(array: readonly T[], f: (value: T, index: number) => R, indexOffset?: number): R[];
7
11
  export declare function reverseMap<T, R>(array: readonly T[], f: (value: T, index: number) => R, indexOffset?: number): R[];
8
- export declare function prepend<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
9
- export declare function last<T>(arr: readonly T[]): T;
10
- export declare function update<T>(arr: readonly T[], index: number, updater: Update<T>): readonly T[];
11
- export declare function mod<T>(arr: readonly T[], index: number, f: (value: T) => T): readonly T[];
12
- export declare function insert<T>(arr: readonly T[], index: number, value: T): T[];
12
+ export declare function _prependNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
13
+ export declare function _prependOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
14
+ export declare const prepend: typeof _prependNew;
15
+ export declare function _lastNew<T>(arr: readonly T[]): T;
16
+ export declare function _lastOld<T>(arr: readonly T[]): T;
17
+ export declare const last: typeof _lastNew;
18
+ export declare function _updateNew<T>(arr: readonly T[], index: number, updater: Update<T>): readonly T[];
19
+ export declare function _updateOld<T>(arr: readonly T[], index: number, updater: Update<T>): readonly T[];
20
+ export declare const update: typeof _updateNew;
21
+ export declare function _modNew<T>(arr: readonly T[], index: number, f: (value: T) => T): readonly T[];
22
+ export declare function _modOld<T>(arr: readonly T[], index: number, f: (value: T) => T): readonly T[];
23
+ export declare const mod: typeof _modNew;
24
+ export declare function _insertNew<T>(arr: readonly T[], index: number, value: T): T[];
25
+ export declare function _insertOld<T>(arr: readonly T[], index: number, value: T): T[];
26
+ export declare const insert: typeof _insertNew;
13
27
  export declare function tail<T>(arr: readonly T[]): T[];
14
28
  export declare function init<T>(arr: readonly T[]): T[];
15
- export declare function splice<T>(arr: readonly T[], start: number, deleteCount: number, ...items: T[]): T[];
29
+ export declare function _spliceNew<T>(arr: readonly T[], start: number, deleteCount: number, ...items: T[]): T[];
30
+ export declare function _spliceOld<T>(arr: readonly T[], start: number, deleteCount: number, ...items: T[]): T[];
31
+ export declare const splice: typeof _spliceNew;
16
32
  export declare function copySparse<T>(arr: readonly T[]): T[];
17
33
  export declare function mapSparse<T, T2>(arr: readonly T[], f: (value: T, index: number) => T2): T2[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimbu/base",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Utilities to implement Rimbu collections",
5
5
  "keywords": [
6
6
  "array",
@@ -67,11 +67,10 @@
67
67
  "typecheck": "tsc"
68
68
  },
69
69
  "dependencies": {
70
- "@rimbu/common": "^1.1.0",
71
- "tslib": "^2.6.1"
70
+ "@rimbu/common": "^2.0.0"
72
71
  },
73
72
  "publishConfig": {
74
73
  "access": "public"
75
74
  },
76
- "gitHead": "f0a61c7e2ba7ecc76dd56a57a9fe7e6ae059eb59"
75
+ "gitHead": "d107c858cf84cb27544685cef981067f2fe1612d"
77
76
  }
package/src/arr.mts CHANGED
@@ -1,12 +1,18 @@
1
- import { Update, TraverseState, type ArrayNonEmpty } from '@rimbu/common';
1
+ import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
2
2
 
3
- // Returns a copy of the array with the given value appended
4
- export function append<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
3
+ export function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
4
+ return array.toSpliced(array.length, 0, value) as ArrayNonEmpty<T>;
5
+ }
6
+
7
+ export function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
5
8
  const clone = array.slice();
6
9
  clone.push(value);
7
10
  return clone as ArrayNonEmpty<T>;
8
11
  }
9
12
 
13
+ // Returns a copy of the array with the given value appended
14
+ export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
15
+
10
16
  // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty
11
17
  export function concat<T>(
12
18
  first: readonly T[],
@@ -17,23 +23,41 @@ export function concat<T>(
17
23
  return first.concat(second);
18
24
  }
19
25
 
20
- // Returns an copy of the array between the start and end indices, with the elements in reversed order.
21
- export function reverse<T>(
26
+ export function _reverseNew<T>(
27
+ array: readonly T[],
28
+ start?: number,
29
+ end?: number
30
+ ): T[] {
31
+ const source =
32
+ undefined !== start || undefined !== end
33
+ ? array.slice(start ?? 0, (end ?? array.length - 1) + 1)
34
+ : array;
35
+
36
+ return source.toReversed();
37
+ }
38
+
39
+ export function _reverseOld<T>(
22
40
  array: readonly T[],
23
- start = 0,
24
- end = array.length - 1
41
+ start?: number,
42
+ end?: number
25
43
  ): T[] {
26
- const length = end - start + 1;
44
+ const _start = start ?? 0;
45
+ const _end = end ?? array.length - 1;
46
+ const length = _end - _start + 1;
27
47
  const res = [] as T[];
28
48
 
29
- let arrayIndex = start - 1;
49
+ let arrayIndex = _start - 1;
30
50
  let resIndex = length - 1;
31
51
 
32
- while (++arrayIndex <= end) res[resIndex--] = array[arrayIndex];
52
+ while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex];
33
53
 
34
54
  return res;
35
55
  }
36
56
 
57
+ // Returns an copy of the array between the start and end indices, with the elements in reversed order.
58
+ export const reverse =
59
+ 'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
60
+
37
61
  // Performs given function on each element of the array, in reverse order if 'reversed' is true.
38
62
  export function forEach<T>(
39
63
  array: readonly T[],
@@ -67,6 +91,11 @@ export function map<T, R>(
67
91
  f: (value: T, index: number) => R,
68
92
  indexOffset = 0
69
93
  ): R[] {
94
+ if (indexOffset === 0) {
95
+ // without offset, can use standard array map
96
+ return array.map(f);
97
+ }
98
+
70
99
  const result: R[] = [];
71
100
 
72
101
  let index = indexOffset;
@@ -95,59 +124,136 @@ export function reverseMap<T, R>(
95
124
  return result;
96
125
  }
97
126
 
98
- // Returns a copy of the given array with the given value added at the start
99
- export function prepend<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
127
+ export function _prependNew<T>(
128
+ array: readonly T[],
129
+ value: T
130
+ ): ArrayNonEmpty<T> {
131
+ return array.toSpliced(0, 0, value) as ArrayNonEmpty<T>;
132
+ }
133
+
134
+ export function _prependOld<T>(
135
+ array: readonly T[],
136
+ value: T
137
+ ): ArrayNonEmpty<T> {
100
138
  const clone = array.slice();
101
139
  clone.unshift(value);
102
140
  return clone as ArrayNonEmpty<T>;
103
141
  }
104
142
 
105
- // Returns the last element of the array
106
- export function last<T>(arr: readonly T[]): T {
143
+ // Returns a copy of the given array with the given value added at the start
144
+ export const prepend =
145
+ `toSpliced` in Array.prototype ? _prependNew : _prependOld;
146
+
147
+ export function _lastNew<T>(arr: readonly T[]): T {
148
+ return arr.at(-1)!;
149
+ }
150
+
151
+ export function _lastOld<T>(arr: readonly T[]): T {
107
152
  return arr[arr.length - 1];
108
153
  }
109
154
 
110
- // Returns a copy of the array where the element at given index is replaced by the given updater.
111
- // If the new element is the same as the old element, the original array is returned
112
- export function update<T>(
155
+ // Returns the last element of the array
156
+ export const last = `at` in Array.prototype ? _lastNew : _lastOld;
157
+
158
+ export function _updateNew<T>(
159
+ arr: readonly T[],
160
+ index: number,
161
+ updater: Update<T>
162
+ ): readonly T[] {
163
+ if (index < 0 || index >= arr.length) {
164
+ return arr;
165
+ }
166
+ const curValue = arr[index];
167
+
168
+ const newValue = Update(curValue, updater);
169
+ if (Object.is(newValue, curValue)) {
170
+ return arr;
171
+ }
172
+
173
+ return arr.with(index, newValue);
174
+ }
175
+
176
+ export function _updateOld<T>(
113
177
  arr: readonly T[],
114
178
  index: number,
115
179
  updater: Update<T>
116
180
  ): readonly T[] {
117
- if (index < 0 || index >= arr.length) return arr;
181
+ if (index < 0 || index >= arr.length) {
182
+ return arr;
183
+ }
118
184
  const curValue = arr[index];
119
185
 
120
186
  const newValue = Update(curValue, updater);
121
- if (Object.is(newValue, curValue)) return arr;
187
+ if (Object.is(newValue, curValue)) {
188
+ return arr;
189
+ }
190
+
122
191
  const newArr = arr.slice();
123
192
  newArr[index] = newValue;
124
193
  return newArr;
125
194
  }
126
195
 
127
- // Returns a copy of the array where the element at given index is replaced by applying given function.
196
+ // Returns a copy of the array where the element at given index is replaced by the given updater.
128
197
  // If the new element is the same as the old element, the original array is returned
129
- export function mod<T>(
198
+ export const update = `with` in Array.prototype ? _updateNew : _updateOld;
199
+
200
+ export function _modNew<T>(
130
201
  arr: readonly T[],
131
202
  index: number,
132
203
  f: (value: T) => T
133
204
  ): readonly T[] {
134
- if (index < 0 || index >= arr.length) return arr;
205
+ if (index < 0 || index >= arr.length) {
206
+ return arr;
207
+ }
135
208
 
136
209
  const curValue = arr[index];
137
210
  const newValue = f(curValue);
138
- if (Object.is(newValue, curValue)) return arr;
211
+
212
+ if (Object.is(newValue, curValue)) {
213
+ return arr;
214
+ }
215
+
216
+ return arr.with(index, newValue);
217
+ }
218
+
219
+ export function _modOld<T>(
220
+ arr: readonly T[],
221
+ index: number,
222
+ f: (value: T) => T
223
+ ): readonly T[] {
224
+ if (index < 0 || index >= arr.length) {
225
+ return arr;
226
+ }
227
+
228
+ const curValue = arr[index];
229
+ const newValue = f(curValue);
230
+
231
+ if (Object.is(newValue, curValue)) {
232
+ return arr;
233
+ }
234
+
139
235
  const newArr = arr.slice();
140
236
  newArr[index] = newValue;
141
237
  return newArr;
142
238
  }
143
239
 
144
- // Returns a copy of the array where at given index the given value is inserted
145
- export function insert<T>(arr: readonly T[], index: number, value: T): T[] {
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
242
+ export const mod = `with` in Array.prototype ? _modNew : _modOld;
243
+
244
+ export function _insertNew<T>(arr: readonly T[], index: number, value: T): T[] {
245
+ return arr.toSpliced(index, 0, value);
246
+ }
247
+
248
+ export function _insertOld<T>(arr: readonly T[], index: number, value: T): T[] {
146
249
  const clone = arr.slice();
147
250
  clone.splice(index, 0, value);
148
251
  return clone;
149
252
  }
150
253
 
254
+ // Returns a copy of the array where at given index the given value is inserted
255
+ export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
256
+
151
257
  // Returns a copy of the array, without its first element
152
258
  export function tail<T>(arr: readonly T[]): T[] {
153
259
  return arr.slice(1);
@@ -158,8 +264,16 @@ export function init<T>(arr: readonly T[]): T[] {
158
264
  return arr.slice(0, arr.length - 1);
159
265
  }
160
266
 
161
- // Immutable version of the array .splice command, always returns a new array
162
- export function splice<T>(
267
+ export function _spliceNew<T>(
268
+ arr: readonly T[],
269
+ start: number,
270
+ deleteCount: number,
271
+ ...items: T[]
272
+ ): T[] {
273
+ return arr.toSpliced(start, deleteCount, ...items);
274
+ }
275
+
276
+ export function _spliceOld<T>(
163
277
  arr: readonly T[],
164
278
  start: number,
165
279
  deleteCount: number,
@@ -170,6 +284,9 @@ export function splice<T>(
170
284
  return clone;
171
285
  }
172
286
 
287
+ // Immutable version of the array .splice command, always returns a new array
288
+ export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
289
+
173
290
  // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value)
174
291
  export function copySparse<T>(arr: readonly T[]): T[] {
175
292
  const clone: T[] = [];