ripple 0.2.46 → 0.2.48
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 +1 -1
- package/src/compiler/phases/1-parse/index.js +52 -2
- package/src/compiler/phases/2-analyze/index.js +640 -667
- package/src/compiler/phases/3-transform/index.js +1878 -1879
- package/src/compiler/phases/3-transform/segments.js +2 -2
- package/src/compiler/utils.js +598 -550
- package/src/jsx-runtime.js +12 -12
- package/src/runtime/array.js +611 -609
- package/src/runtime/index.js +29 -17
- package/src/runtime/internal/client/array.js +121 -121
- package/src/runtime/internal/client/blocks.js +206 -206
- package/src/runtime/internal/client/constants.js +2 -2
- package/src/runtime/internal/client/context.js +40 -40
- package/src/runtime/internal/client/events.js +191 -191
- package/src/runtime/internal/client/for.js +355 -355
- package/src/runtime/internal/client/if.js +25 -25
- package/src/runtime/internal/client/index.js +57 -56
- package/src/runtime/internal/client/operations.js +32 -32
- package/src/runtime/internal/client/portal.js +19 -19
- package/src/runtime/internal/client/render.js +132 -132
- package/src/runtime/internal/client/runtime.js +839 -835
- package/src/runtime/internal/client/template.js +36 -36
- package/src/runtime/internal/client/try.js +113 -113
- package/src/runtime/internal/client/types.d.ts +12 -11
- package/src/runtime/internal/client/utils.js +5 -5
- package/src/runtime/map.js +139 -139
- package/src/runtime/set.js +130 -130
- package/src/utils/ast.js +189 -189
- package/src/utils/builders.js +244 -244
- package/src/utils/sanitize_template_string.js +1 -1
- package/tests/__snapshots__/composite.test.ripple.snap +1 -1
- package/tests/accessors-props.test.ripple +9 -9
- package/tests/basic.test.ripple +4 -4
- package/tests/boundaries.test.ripple +17 -17
- package/tests/compiler.test.ripple +14 -14
- package/tests/composite.test.ripple +43 -72
- package/tests/context.test.ripple +35 -12
- package/types/index.d.ts +38 -34
package/src/runtime/array.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
TRACKED_OBJECT,
|
|
3
|
+
ARRAY_SET_INDEX_AT,
|
|
4
|
+
MAX_ARRAY_LENGTH,
|
|
5
|
+
} from './internal/client/constants.js';
|
|
2
6
|
import { get, safe_scope, set, tracked } from './internal/client/runtime.js';
|
|
3
7
|
import { is_ripple_array } from './internal/client/utils.js';
|
|
4
8
|
/** @import { Block, Tracked } from '#client' */
|
|
@@ -8,35 +12,35 @@ const INIT_AFTER_NEW = Symbol();
|
|
|
8
12
|
|
|
9
13
|
/** @type {(symbol | string | any)[]} */
|
|
10
14
|
const introspect_methods = [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
'concat',
|
|
16
|
+
'entries',
|
|
17
|
+
'every',
|
|
18
|
+
'filter',
|
|
19
|
+
'find',
|
|
20
|
+
'findIndex',
|
|
21
|
+
'findLast',
|
|
22
|
+
'findLastIndex',
|
|
23
|
+
'flat',
|
|
24
|
+
'flatMap',
|
|
25
|
+
'forEach',
|
|
26
|
+
'includes',
|
|
27
|
+
'indexOf',
|
|
28
|
+
'join',
|
|
29
|
+
'keys',
|
|
30
|
+
'lastIndexOf',
|
|
31
|
+
'map',
|
|
32
|
+
'reduce',
|
|
33
|
+
'reduceRight',
|
|
34
|
+
'some',
|
|
35
|
+
'slice',
|
|
36
|
+
'toLocaleString',
|
|
37
|
+
'toReversed',
|
|
38
|
+
'toSorted',
|
|
39
|
+
'toSpliced',
|
|
40
|
+
'toString',
|
|
41
|
+
Symbol.iterator,
|
|
42
|
+
'values',
|
|
43
|
+
'with',
|
|
40
44
|
];
|
|
41
45
|
|
|
42
46
|
let is_proto_set = false;
|
|
@@ -46,549 +50,545 @@ let is_proto_set = false;
|
|
|
46
50
|
* @extends {Array<T>}
|
|
47
51
|
*/
|
|
48
52
|
export class RippleArray extends Array {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (i in arr) {
|
|
94
|
-
result[i] = arr[i];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
result[INIT_AFTER_NEW](block);
|
|
100
|
-
|
|
101
|
-
return result
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* @template U
|
|
106
|
-
* @param {...U} elements
|
|
107
|
-
* @returns {RippleArray<U>}
|
|
108
|
-
*/
|
|
109
|
-
static of(...elements) {
|
|
110
|
-
var arr = Array.of(...elements);
|
|
111
|
-
|
|
112
|
-
return get_instance_from_static(arr);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* @param {...T} elements
|
|
117
|
-
*/
|
|
118
|
-
constructor(...elements) {
|
|
119
|
-
super(...elements);
|
|
120
|
-
|
|
121
|
-
this[INIT_AFTER_NEW]();
|
|
122
|
-
|
|
123
|
-
if (!is_proto_set) {
|
|
124
|
-
is_proto_set = true;
|
|
125
|
-
this.#set_proto();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
[INIT_AFTER_NEW](block = safe_scope()) {
|
|
130
|
-
if (this.length !== 0) {
|
|
131
|
-
var tracked_elements = this.#tracked_elements;
|
|
132
|
-
for (var i = 0; i < this.length; i++) {
|
|
133
|
-
if (!(i in this)) {
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
tracked_elements[i] = tracked(this[i], block);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (!this.#tracked_index) {
|
|
141
|
-
this.#tracked_index = tracked(this.length, block);
|
|
142
|
-
} else if (this.#tracked_index.v !== this.length) {
|
|
143
|
-
set(this.#tracked_index, this.length, block);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
#set_proto() {
|
|
148
|
-
var proto = RippleArray.prototype;
|
|
149
|
-
var array_proto = Array.prototype;
|
|
150
|
-
|
|
151
|
-
for (const method of introspect_methods) {
|
|
152
|
-
if (!(method in array_proto)) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/** @param {...any} v */
|
|
157
|
-
proto[method] = function (...v) {
|
|
158
|
-
var result = array_proto[method].apply(this, v);
|
|
159
|
-
|
|
160
|
-
if (is_ripple_array(result) && this !== result) {
|
|
161
|
-
var tracked_elements = result[TRACKED_OBJECT];
|
|
162
|
-
var block = safe_scope();
|
|
163
|
-
|
|
164
|
-
if (tracked_elements.length != result.length) {
|
|
165
|
-
for (var i = 0; i < result.length; i++) {
|
|
166
|
-
if ((i in result) && tracked_elements[i] === undefined) {
|
|
167
|
-
tracked_elements[i] = tracked(result[i], block);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// the caller reruns on length changes
|
|
174
|
-
this.$length;
|
|
175
|
-
// the caller reruns on element changes
|
|
176
|
-
establish_trackable_deps(this);
|
|
177
|
-
return result;
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* @param {number} target
|
|
184
|
-
* @param {number} start
|
|
185
|
-
* @param {number} [end]
|
|
186
|
-
* @returns {this}
|
|
187
|
-
*/
|
|
188
|
-
copyWithin(target, start, end) {
|
|
189
|
-
var block = safe_scope();
|
|
190
|
-
var tracked_elements = this.#tracked_elements;
|
|
191
|
-
var length = this.length;
|
|
192
|
-
|
|
193
|
-
super.copyWithin(target, start, end);
|
|
194
|
-
|
|
195
|
-
if (!target && !start) {
|
|
196
|
-
return this;
|
|
197
|
-
} else if (!target && start) {
|
|
198
|
-
target = 0;
|
|
199
|
-
} else if (target && !start) {
|
|
200
|
-
start = 0;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (target < 0) {
|
|
204
|
-
target = Math.max(length + target, 0);
|
|
205
|
-
} else {
|
|
206
|
-
target = Math.min(target, length);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (start < 0) {
|
|
210
|
-
start = Math.max(length + start, 0);
|
|
211
|
-
} else {
|
|
212
|
-
start = Math.min(start, length);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (end === undefined) {
|
|
216
|
-
end = length;
|
|
217
|
-
} else if (end < 0) {
|
|
218
|
-
end = Math.max(length + end, 0);
|
|
219
|
-
} else {
|
|
220
|
-
end = Math.min(end, length);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (target >= length) {
|
|
224
|
-
return this;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const copyCount = Math.min(end - start, length - target);
|
|
228
|
-
|
|
229
|
-
// If no elements are copied (start >= end or copyCount <= 0), return early
|
|
230
|
-
if (start >= end || copyCount <= 0) {
|
|
231
|
-
return this;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
for (let i = 0; i < copyCount; i++) {
|
|
235
|
-
const index = target + i;
|
|
236
|
-
// Only update if source and target are different positions
|
|
237
|
-
// to avoid unnecessary updates when copying onto itself
|
|
238
|
-
if (index !== start + i) {
|
|
239
|
-
this.#update_tracked_at_index({array: this, i: index, block, tracked_elements});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return this;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* @param {T} value
|
|
248
|
-
* @param {number} [start]
|
|
249
|
-
* @param {number} [end]
|
|
250
|
-
* @returns {this}
|
|
251
|
-
*/
|
|
252
|
-
fill(value, start, end) {
|
|
253
|
-
var block = safe_scope();
|
|
254
|
-
var tracked_elements = this.#tracked_elements;
|
|
255
|
-
var length = this.length;
|
|
256
|
-
|
|
257
|
-
// avoid unexpected behavior with method args being undefined
|
|
258
|
-
if (value === undefined && start === undefined && end === undefined) {
|
|
259
|
-
// @ts-ignore
|
|
260
|
-
super.fill();
|
|
261
|
-
} else if (start === undefined && end === undefined) {
|
|
262
|
-
super.fill(value);
|
|
263
|
-
} else if (end === undefined) {
|
|
264
|
-
super.fill(value, start);
|
|
265
|
-
} else {
|
|
266
|
-
super.fill(value, start, end);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
let actual_start = 0;
|
|
270
|
-
if (start !== undefined) {
|
|
271
|
-
if (start < 0) {
|
|
272
|
-
actual_start = Math.max(length + start, 0);
|
|
273
|
-
} else {
|
|
274
|
-
actual_start = Math.min(start, length);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
let actual_end = length;
|
|
279
|
-
if (end !== undefined) {
|
|
280
|
-
if (end < 0) {
|
|
281
|
-
actual_end = Math.max(length + end, 0);
|
|
282
|
-
} else {
|
|
283
|
-
actual_end = Math.min(end, length);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
for (let i = actual_start; i < actual_end; i++) {
|
|
288
|
-
if (tracked_elements[i] === undefined) {
|
|
289
|
-
tracked_elements[i] = tracked(this[i], block);
|
|
290
|
-
} else {
|
|
291
|
-
set(tracked_elements[i], this[i], block);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return this;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
reverse() {
|
|
299
|
-
var result = /** @type {RippleArray<T>} */ (super.reverse());
|
|
300
|
-
this.#update_all_tracked_from_array(result);
|
|
301
|
-
return result;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* @param {(a: T, b: T) => number} [fn]
|
|
306
|
-
* @returns {this}
|
|
307
|
-
*/
|
|
308
|
-
sort(fn) {
|
|
309
|
-
var result = super.sort(fn);
|
|
310
|
-
this.#update_all_tracked_from_array(result);
|
|
311
|
-
return result;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* @param {RippleArray<T>} array
|
|
316
|
-
* @returns {RippleArray<T>}
|
|
317
|
-
*/
|
|
318
|
-
#update_all_tracked_from_array(array) {
|
|
319
|
-
var block = safe_scope();
|
|
320
|
-
var tracked_elements = this.#tracked_elements;
|
|
321
|
-
|
|
322
|
-
for (var i = 0; i < array.length; i++) {
|
|
323
|
-
this.#update_tracked_at_index({array, i, block, tracked_elements});
|
|
324
|
-
}
|
|
325
|
-
return array;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* @param {Object} param0
|
|
330
|
-
* @param {RippleArray<T>} param0.array
|
|
331
|
-
* @param {number} param0.i
|
|
332
|
-
* @param {Block} param0.block
|
|
333
|
-
* @param {Tracked[]} param0.tracked_elements
|
|
334
|
-
*/
|
|
335
|
-
#update_tracked_at_index({
|
|
336
|
-
array,
|
|
337
|
-
i,
|
|
338
|
-
block = safe_scope(),
|
|
339
|
-
tracked_elements = this.#tracked_elements
|
|
340
|
-
}) {
|
|
341
|
-
if ((i in array)) {
|
|
342
|
-
if (tracked_elements[i] === undefined) {
|
|
343
|
-
tracked_elements[i] = tracked(array[i], block);
|
|
344
|
-
} else {
|
|
345
|
-
set(tracked_elements[i], array[i], block);
|
|
346
|
-
}
|
|
347
|
-
} else {
|
|
348
|
-
if (tracked_elements[i] !== undefined) {
|
|
349
|
-
set(tracked_elements[i], undefined, block);
|
|
350
|
-
}
|
|
351
|
-
delete tracked_elements[i];
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* @param {...T} elements
|
|
357
|
-
* @returns {number}
|
|
358
|
-
*/
|
|
359
|
-
unshift(...elements) {
|
|
360
|
-
var block = safe_scope();
|
|
361
|
-
var tracked_elements = this.#tracked_elements;
|
|
362
|
-
var length = this.length;
|
|
363
|
-
var shift_len = elements.length;
|
|
364
|
-
var new_len = length + shift_len;
|
|
365
|
-
|
|
366
|
-
super.unshift(...elements);
|
|
367
|
-
|
|
368
|
-
// extend the array to fit the new elements
|
|
369
|
-
tracked_elements.push(...(elements.map(() => tracked(undefined, block))));
|
|
370
|
-
|
|
371
|
-
// copy the existing ones to the end
|
|
372
|
-
for (let i = length - 1; i >= 0; i--) {
|
|
373
|
-
set(tracked_elements[i + shift_len], tracked_elements[i].v, block);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// set new values at the start
|
|
377
|
-
for (let i = shift_len - 1; i >= 0; i--) {
|
|
378
|
-
set(tracked_elements[i], elements[i], block);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
set(this.#tracked_index, new_len, block);
|
|
382
|
-
return new_len;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
shift() {
|
|
386
|
-
var block = safe_scope();
|
|
387
|
-
var tracked_elements = this.#tracked_elements;
|
|
388
|
-
|
|
389
|
-
var result = super.shift();
|
|
390
|
-
for (var i = 0; i < tracked_elements.length; i++) {
|
|
391
|
-
// the last must be set to undefined
|
|
392
|
-
set(tracked_elements[i], tracked_elements[i + 1]?.v, block);
|
|
393
|
-
}
|
|
394
|
-
tracked_elements.pop();
|
|
395
|
-
|
|
396
|
-
set(this.#tracked_index, this.length, block);
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* @param {...T} elements
|
|
402
|
-
* @returns {number}
|
|
403
|
-
*/
|
|
404
|
-
push(...elements) {
|
|
405
|
-
var block = safe_scope();
|
|
406
|
-
var start_index = this.length;
|
|
407
|
-
var tracked_elements = this.#tracked_elements;
|
|
408
|
-
|
|
409
|
-
super.push(...elements);
|
|
410
|
-
|
|
411
|
-
for (var i = 0; i < elements.length; i++) {
|
|
412
|
-
if (!(i in elements)) {
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
tracked_elements[start_index + i] = tracked(elements[i], block);
|
|
416
|
-
}
|
|
417
|
-
var length = this.length;
|
|
418
|
-
set(this.#tracked_index, this.length, block);
|
|
419
|
-
return length;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
pop() {
|
|
423
|
-
var block = safe_scope();
|
|
424
|
-
var tracked_elements = this.#tracked_elements;
|
|
425
|
-
var length = tracked_elements.length;
|
|
426
|
-
var result = super.pop();
|
|
427
|
-
|
|
428
|
-
if (length > 0 && tracked_elements[length - 1] !== undefined) {
|
|
429
|
-
set(tracked_elements[length - 1], undefined, block);
|
|
430
|
-
}
|
|
431
|
-
tracked_elements.pop();
|
|
432
|
-
|
|
433
|
-
set(this.#tracked_index, this.length, block);
|
|
434
|
-
return result;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Assigns value at index
|
|
439
|
-
* Same as bracket [] assignment
|
|
440
|
-
* Supports negative index to count back from the end
|
|
441
|
-
* @param {number} index
|
|
442
|
-
* @param {T} value
|
|
443
|
-
* @returns {T}
|
|
444
|
-
*/
|
|
445
|
-
[ARRAY_SET_INDEX_AT](index, value) {
|
|
446
|
-
var block = safe_scope();
|
|
447
|
-
var tracked_elements = this.#tracked_elements;
|
|
448
|
-
var length = this.length;
|
|
449
|
-
var init_index = index;
|
|
450
|
-
|
|
451
|
-
if (!Number.isInteger(index)) {
|
|
452
|
-
throw new TypeError('Provided index must be a valid integer');
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (init_index < -length) {
|
|
456
|
-
throw new RangeError('Provided negative index out of bounds');
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
index = index < 0 ? index + length : index;
|
|
460
|
-
|
|
461
|
-
super[index] = value;
|
|
462
|
-
|
|
463
|
-
if (tracked_elements[index] === undefined) {
|
|
464
|
-
tracked_elements[index] = tracked(value, block);
|
|
465
|
-
} else {
|
|
466
|
-
set(tracked_elements[index], value, block);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
if (this.length > length) {
|
|
470
|
-
set(this.#tracked_index, this.length, block);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
return value;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* @param {number} index
|
|
478
|
-
* @returns {T | undefined}
|
|
479
|
-
*/
|
|
480
|
-
at(index) {
|
|
481
|
-
var tracked_elements = this.#tracked_elements;
|
|
482
|
-
var normalized = index < 0 ? index + this.length : index;
|
|
483
|
-
|
|
484
|
-
if (tracked_elements[normalized] !== undefined) {
|
|
485
|
-
get(tracked_elements[normalized]);
|
|
486
|
-
}
|
|
487
|
-
this.$length;
|
|
488
|
-
|
|
489
|
-
return super.at(index);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* @param {number} start
|
|
494
|
-
* @param {number} [delete_count]
|
|
495
|
-
* @param {...T} elements
|
|
496
|
-
* @returns {Array<T>}
|
|
497
|
-
*/
|
|
498
|
-
splice(start, delete_count, ...elements) {
|
|
499
|
-
var block = safe_scope();
|
|
500
|
-
var tracked_elements = this.#tracked_elements;
|
|
501
|
-
var tracked_len = tracked_elements.length;
|
|
502
|
-
var before_len = this.length;
|
|
503
|
-
var el_len = elements.length;
|
|
504
|
-
var result;
|
|
505
|
-
|
|
506
|
-
if (start !== undefined && delete_count === undefined && !el_len) {
|
|
507
|
-
// we can't just call super.splice(start, delete_count, ...elements)
|
|
508
|
-
// delete_count if undefined will be converted to 0 and nothing will be removed
|
|
509
|
-
result = super.splice(start);
|
|
510
|
-
} else if (start === undefined && delete_count === undefined && !el_len) {
|
|
511
|
-
// If start is undefined the native code will get converted to 0
|
|
512
|
-
// which would cause to remove all elements.
|
|
513
|
-
// Typically no sense to `.splice()` with no args as it does nothing
|
|
514
|
-
// since we get args as undefined, we need to handle this case
|
|
515
|
-
|
|
516
|
-
// @ts-ignore
|
|
517
|
-
result = super.splice();
|
|
518
|
-
} else {
|
|
519
|
-
// @ts-ignore
|
|
520
|
-
result = super.splice(start, delete_count, ...elements);
|
|
53
|
+
/** @type {Array<Tracked>} */
|
|
54
|
+
#tracked_elements = [];
|
|
55
|
+
/** @type {Tracked} */
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
#tracked_index;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @template U
|
|
61
|
+
* @param {ArrayLike<U> | Iterable<U>} arrayLike
|
|
62
|
+
* @param {(v: U, k: number) => any | undefined} [mapFn]
|
|
63
|
+
* @param {any} [thisArg]
|
|
64
|
+
* @returns {RippleArray<U>}
|
|
65
|
+
*/
|
|
66
|
+
static from(arrayLike, mapFn, thisArg) {
|
|
67
|
+
var arr = mapFn ? Array.from(arrayLike, mapFn, thisArg) : Array.from(arrayLike);
|
|
68
|
+
|
|
69
|
+
return get_instance_from_static(arr);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @template U
|
|
74
|
+
* @param {ArrayLike<U> | Iterable<U>} arrayLike
|
|
75
|
+
* @param {(v: U, k: number) => any | undefined} [mapFn]
|
|
76
|
+
* @param {any} [thisArg]
|
|
77
|
+
* @returns {Promise<RippleArray<U>>}
|
|
78
|
+
*/
|
|
79
|
+
static async fromAsync(arrayLike, mapFn, thisArg) {
|
|
80
|
+
var block = safe_scope();
|
|
81
|
+
// create empty array to get the right scope
|
|
82
|
+
var result = new RippleArray();
|
|
83
|
+
|
|
84
|
+
var arr = mapFn
|
|
85
|
+
? await Array.fromAsync(arrayLike, mapFn, thisArg)
|
|
86
|
+
: await Array.fromAsync(arrayLike);
|
|
87
|
+
|
|
88
|
+
var first = get_first_if_length(arr);
|
|
89
|
+
|
|
90
|
+
if (first) {
|
|
91
|
+
result[0] = first;
|
|
92
|
+
} else {
|
|
93
|
+
result.length = arr.length;
|
|
94
|
+
for (let i = 0; i < arr.length; i++) {
|
|
95
|
+
if (i in arr) {
|
|
96
|
+
result[i] = arr[i];
|
|
521
97
|
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
result[INIT_AFTER_NEW](block);
|
|
102
|
+
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @template U
|
|
108
|
+
* @param {...U} elements
|
|
109
|
+
* @returns {RippleArray<U>}
|
|
110
|
+
*/
|
|
111
|
+
static of(...elements) {
|
|
112
|
+
var arr = Array.of(...elements);
|
|
113
|
+
|
|
114
|
+
return get_instance_from_static(arr);
|
|
115
|
+
}
|
|
522
116
|
|
|
523
|
-
|
|
524
|
-
|
|
117
|
+
/**
|
|
118
|
+
* @param {...T} elements
|
|
119
|
+
*/
|
|
120
|
+
constructor(...elements) {
|
|
121
|
+
super(...elements);
|
|
525
122
|
|
|
526
|
-
|
|
527
|
-
|
|
123
|
+
this[INIT_AFTER_NEW]();
|
|
124
|
+
|
|
125
|
+
if (!is_proto_set) {
|
|
126
|
+
is_proto_set = true;
|
|
127
|
+
this.#set_proto();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
[INIT_AFTER_NEW](block = safe_scope()) {
|
|
132
|
+
if (this.length !== 0) {
|
|
133
|
+
var tracked_elements = this.#tracked_elements;
|
|
134
|
+
for (var i = 0; i < this.length; i++) {
|
|
135
|
+
if (!(i in this)) {
|
|
136
|
+
continue;
|
|
528
137
|
}
|
|
138
|
+
tracked_elements[i] = tracked(this[i], block);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
529
141
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
142
|
+
if (!this.#tracked_index) {
|
|
143
|
+
this.#tracked_index = tracked(this.length, block);
|
|
144
|
+
} else if (this.#tracked_index.v !== this.length) {
|
|
145
|
+
set(this.#tracked_index, this.length, block);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#set_proto() {
|
|
150
|
+
var proto = RippleArray.prototype;
|
|
151
|
+
var array_proto = Array.prototype;
|
|
152
|
+
|
|
153
|
+
for (const method of introspect_methods) {
|
|
154
|
+
if (!(method in array_proto)) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** @param {...any} v */
|
|
159
|
+
proto[method] = function (...v) {
|
|
160
|
+
var result = array_proto[method].apply(this, v);
|
|
161
|
+
|
|
162
|
+
if (is_ripple_array(result) && this !== result) {
|
|
163
|
+
var tracked_elements = result[TRACKED_OBJECT];
|
|
164
|
+
var block = safe_scope();
|
|
165
|
+
|
|
166
|
+
if (tracked_elements.length != result.length) {
|
|
167
|
+
for (var i = 0; i < result.length; i++) {
|
|
168
|
+
if (i in result && tracked_elements[i] === undefined) {
|
|
169
|
+
tracked_elements[i] = tracked(result[i], block);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
534
173
|
}
|
|
535
174
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
175
|
+
// the caller reruns on length changes
|
|
176
|
+
this.$length;
|
|
177
|
+
// the caller reruns on element changes
|
|
178
|
+
establish_trackable_deps(this);
|
|
179
|
+
return result;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {number} target
|
|
186
|
+
* @param {number} start
|
|
187
|
+
* @param {number} [end]
|
|
188
|
+
* @returns {this}
|
|
189
|
+
*/
|
|
190
|
+
copyWithin(target, start, end) {
|
|
191
|
+
var block = safe_scope();
|
|
192
|
+
var tracked_elements = this.#tracked_elements;
|
|
193
|
+
var length = this.length;
|
|
194
|
+
|
|
195
|
+
super.copyWithin(target, start, end);
|
|
196
|
+
|
|
197
|
+
if (!target && !start) {
|
|
198
|
+
return this;
|
|
199
|
+
} else if (!target && start) {
|
|
200
|
+
target = 0;
|
|
201
|
+
} else if (target && !start) {
|
|
202
|
+
start = 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (target < 0) {
|
|
206
|
+
target = Math.max(length + target, 0);
|
|
207
|
+
} else {
|
|
208
|
+
target = Math.min(target, length);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (start < 0) {
|
|
212
|
+
start = Math.max(length + start, 0);
|
|
213
|
+
} else {
|
|
214
|
+
start = Math.min(start, length);
|
|
215
|
+
}
|
|
539
216
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
217
|
+
if (end === undefined) {
|
|
218
|
+
end = length;
|
|
219
|
+
} else if (end < 0) {
|
|
220
|
+
end = Math.max(length + end, 0);
|
|
221
|
+
} else {
|
|
222
|
+
end = Math.min(end, length);
|
|
223
|
+
}
|
|
543
224
|
|
|
544
|
-
|
|
225
|
+
if (target >= length) {
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
545
228
|
|
|
546
|
-
|
|
547
|
-
|
|
229
|
+
const copyCount = Math.min(end - start, length - target);
|
|
230
|
+
|
|
231
|
+
// If no elements are copied (start >= end or copyCount <= 0), return early
|
|
232
|
+
if (start >= end || copyCount <= 0) {
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (let i = 0; i < copyCount; i++) {
|
|
237
|
+
const index = target + i;
|
|
238
|
+
// Only update if source and target are different positions
|
|
239
|
+
// to avoid unnecessary updates when copying onto itself
|
|
240
|
+
if (index !== start + i) {
|
|
241
|
+
this.#update_tracked_at_index({ array: this, i: index, block, tracked_elements });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {T} value
|
|
250
|
+
* @param {number} [start]
|
|
251
|
+
* @param {number} [end]
|
|
252
|
+
* @returns {this}
|
|
253
|
+
*/
|
|
254
|
+
fill(value, start, end) {
|
|
255
|
+
var block = safe_scope();
|
|
256
|
+
var tracked_elements = this.#tracked_elements;
|
|
257
|
+
var length = this.length;
|
|
258
|
+
|
|
259
|
+
// avoid unexpected behavior with method args being undefined
|
|
260
|
+
if (value === undefined && start === undefined && end === undefined) {
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
super.fill();
|
|
263
|
+
} else if (start === undefined && end === undefined) {
|
|
264
|
+
super.fill(value);
|
|
265
|
+
} else if (end === undefined) {
|
|
266
|
+
super.fill(value, start);
|
|
267
|
+
} else {
|
|
268
|
+
super.fill(value, start, end);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
let actual_start = 0;
|
|
272
|
+
if (start !== undefined) {
|
|
273
|
+
if (start < 0) {
|
|
274
|
+
actual_start = Math.max(length + start, 0);
|
|
275
|
+
} else {
|
|
276
|
+
actual_start = Math.min(start, length);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let actual_end = length;
|
|
281
|
+
if (end !== undefined) {
|
|
282
|
+
if (end < 0) {
|
|
283
|
+
actual_end = Math.max(length + end, 0);
|
|
284
|
+
} else {
|
|
285
|
+
actual_end = Math.min(end, length);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
for (let i = actual_start; i < actual_end; i++) {
|
|
290
|
+
if (tracked_elements[i] === undefined) {
|
|
291
|
+
tracked_elements[i] = tracked(this[i], block);
|
|
292
|
+
} else {
|
|
293
|
+
set(tracked_elements[i], this[i], block);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
reverse() {
|
|
301
|
+
var result = /** @type {RippleArray<T>} */ (super.reverse());
|
|
302
|
+
this.#update_all_tracked_from_array(result);
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @param {(a: T, b: T) => number} [fn]
|
|
308
|
+
* @returns {this}
|
|
309
|
+
*/
|
|
310
|
+
sort(fn) {
|
|
311
|
+
var result = super.sort(fn);
|
|
312
|
+
this.#update_all_tracked_from_array(result);
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @param {RippleArray<T>} array
|
|
318
|
+
* @returns {RippleArray<T>}
|
|
319
|
+
*/
|
|
320
|
+
#update_all_tracked_from_array(array) {
|
|
321
|
+
var block = safe_scope();
|
|
322
|
+
var tracked_elements = this.#tracked_elements;
|
|
323
|
+
|
|
324
|
+
for (var i = 0; i < array.length; i++) {
|
|
325
|
+
this.#update_tracked_at_index({ array, i, block, tracked_elements });
|
|
326
|
+
}
|
|
327
|
+
return array;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @param {Object} param0
|
|
332
|
+
* @param {RippleArray<T>} param0.array
|
|
333
|
+
* @param {number} param0.i
|
|
334
|
+
* @param {Block} param0.block
|
|
335
|
+
* @param {Tracked[]} param0.tracked_elements
|
|
336
|
+
*/
|
|
337
|
+
#update_tracked_at_index({
|
|
338
|
+
array,
|
|
339
|
+
i,
|
|
340
|
+
block = safe_scope(),
|
|
341
|
+
tracked_elements = this.#tracked_elements,
|
|
342
|
+
}) {
|
|
343
|
+
if (i in array) {
|
|
344
|
+
if (tracked_elements[i] === undefined) {
|
|
345
|
+
tracked_elements[i] = tracked(array[i], block);
|
|
346
|
+
} else {
|
|
347
|
+
set(tracked_elements[i], array[i], block);
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
if (tracked_elements[i] !== undefined) {
|
|
351
|
+
set(tracked_elements[i], undefined, block);
|
|
352
|
+
}
|
|
353
|
+
delete tracked_elements[i];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* @param {...T} elements
|
|
359
|
+
* @returns {number}
|
|
360
|
+
*/
|
|
361
|
+
unshift(...elements) {
|
|
362
|
+
var block = safe_scope();
|
|
363
|
+
var tracked_elements = this.#tracked_elements;
|
|
364
|
+
var length = this.length;
|
|
365
|
+
var shift_len = elements.length;
|
|
366
|
+
var new_len = length + shift_len;
|
|
367
|
+
|
|
368
|
+
super.unshift(...elements);
|
|
369
|
+
|
|
370
|
+
// extend the array to fit the new elements
|
|
371
|
+
tracked_elements.push(...elements.map(() => tracked(undefined, block)));
|
|
372
|
+
|
|
373
|
+
// copy the existing ones to the end
|
|
374
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
375
|
+
set(tracked_elements[i + shift_len], tracked_elements[i].v, block);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// set new values at the start
|
|
379
|
+
for (let i = shift_len - 1; i >= 0; i--) {
|
|
380
|
+
set(tracked_elements[i], elements[i], block);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
set(this.#tracked_index, new_len, block);
|
|
384
|
+
return new_len;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
shift() {
|
|
388
|
+
var block = safe_scope();
|
|
389
|
+
var tracked_elements = this.#tracked_elements;
|
|
390
|
+
|
|
391
|
+
var result = super.shift();
|
|
392
|
+
for (var i = 0; i < tracked_elements.length; i++) {
|
|
393
|
+
// the last must be set to undefined
|
|
394
|
+
set(tracked_elements[i], tracked_elements[i + 1]?.v, block);
|
|
395
|
+
}
|
|
396
|
+
tracked_elements.pop();
|
|
397
|
+
|
|
398
|
+
set(this.#tracked_index, this.length, block);
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* @param {...T} elements
|
|
404
|
+
* @returns {number}
|
|
405
|
+
*/
|
|
406
|
+
push(...elements) {
|
|
407
|
+
var block = safe_scope();
|
|
408
|
+
var start_index = this.length;
|
|
409
|
+
var tracked_elements = this.#tracked_elements;
|
|
410
|
+
|
|
411
|
+
super.push(...elements);
|
|
412
|
+
|
|
413
|
+
for (var i = 0; i < elements.length; i++) {
|
|
414
|
+
if (!(i in elements)) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
tracked_elements[start_index + i] = tracked(elements[i], block);
|
|
418
|
+
}
|
|
419
|
+
var length = this.length;
|
|
420
|
+
set(this.#tracked_index, this.length, block);
|
|
421
|
+
return length;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
pop() {
|
|
425
|
+
var block = safe_scope();
|
|
426
|
+
var tracked_elements = this.#tracked_elements;
|
|
427
|
+
var length = tracked_elements.length;
|
|
428
|
+
var result = super.pop();
|
|
429
|
+
|
|
430
|
+
if (length > 0 && tracked_elements[length - 1] !== undefined) {
|
|
431
|
+
set(tracked_elements[length - 1], undefined, block);
|
|
432
|
+
}
|
|
433
|
+
tracked_elements.pop();
|
|
434
|
+
|
|
435
|
+
set(this.#tracked_index, this.length, block);
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Assigns value at index
|
|
441
|
+
* Same as bracket [] assignment
|
|
442
|
+
* Supports negative index to count back from the end
|
|
443
|
+
* @param {number} index
|
|
444
|
+
* @param {T} value
|
|
445
|
+
* @returns {T}
|
|
446
|
+
*/
|
|
447
|
+
[ARRAY_SET_INDEX_AT](index, value) {
|
|
448
|
+
var block = safe_scope();
|
|
449
|
+
var tracked_elements = this.#tracked_elements;
|
|
450
|
+
var length = this.length;
|
|
451
|
+
var init_index = index;
|
|
452
|
+
|
|
453
|
+
if (!Number.isInteger(index)) {
|
|
454
|
+
throw new TypeError('Provided index must be a valid integer');
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (init_index < -length) {
|
|
458
|
+
throw new RangeError('Provided negative index out of bounds');
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
index = index < 0 ? index + length : index;
|
|
462
|
+
|
|
463
|
+
super[index] = value;
|
|
464
|
+
|
|
465
|
+
if (tracked_elements[index] === undefined) {
|
|
466
|
+
tracked_elements[index] = tracked(value, block);
|
|
467
|
+
} else {
|
|
468
|
+
set(tracked_elements[index], value, block);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (this.length > length) {
|
|
472
|
+
set(this.#tracked_index, this.length, block);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return value;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* @param {number} index
|
|
480
|
+
* @returns {T | undefined}
|
|
481
|
+
*/
|
|
482
|
+
at(index) {
|
|
483
|
+
var tracked_elements = this.#tracked_elements;
|
|
484
|
+
var normalized = index < 0 ? index + this.length : index;
|
|
485
|
+
|
|
486
|
+
if (tracked_elements[normalized] !== undefined) {
|
|
487
|
+
get(tracked_elements[normalized]);
|
|
488
|
+
}
|
|
489
|
+
this.$length;
|
|
490
|
+
|
|
491
|
+
return super.at(index);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* @param {number} start
|
|
496
|
+
* @param {number} [delete_count]
|
|
497
|
+
* @param {...T} elements
|
|
498
|
+
* @returns {Array<T>}
|
|
499
|
+
*/
|
|
500
|
+
splice(start, delete_count, ...elements) {
|
|
501
|
+
var block = safe_scope();
|
|
502
|
+
var tracked_elements = this.#tracked_elements;
|
|
503
|
+
var tracked_len = tracked_elements.length;
|
|
504
|
+
var before_len = this.length;
|
|
505
|
+
var el_len = elements.length;
|
|
506
|
+
var result;
|
|
507
|
+
|
|
508
|
+
if (start !== undefined && delete_count === undefined && !el_len) {
|
|
509
|
+
// we can't just call super.splice(start, delete_count, ...elements)
|
|
510
|
+
// delete_count if undefined will be converted to 0 and nothing will be removed
|
|
511
|
+
result = super.splice(start);
|
|
512
|
+
} else if (start === undefined && delete_count === undefined && !el_len) {
|
|
513
|
+
// If start is undefined the native code will get converted to 0
|
|
514
|
+
// which would cause to remove all elements.
|
|
515
|
+
// Typically no sense to `.splice()` with no args as it does nothing
|
|
516
|
+
// since we get args as undefined, we need to handle this case
|
|
517
|
+
|
|
518
|
+
// @ts-ignore
|
|
519
|
+
result = super.splice();
|
|
520
|
+
} else {
|
|
521
|
+
// @ts-ignore
|
|
522
|
+
result = super.splice(start, delete_count, ...elements);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
var after_len = this.length;
|
|
526
|
+
delete_count = result.length;
|
|
527
|
+
|
|
528
|
+
if (delete_count === 0 && !el_len) {
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (start < 0) {
|
|
533
|
+
start = Math.max(before_len + start, 0);
|
|
534
|
+
} else {
|
|
535
|
+
start = Math.min(start, before_len);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
var range_end = el_len - delete_count === 0 ? start + el_len : Math.max(after_len, before_len);
|
|
539
|
+
|
|
540
|
+
for (let i = start; i < range_end; i++) {
|
|
541
|
+
this.#update_tracked_at_index({ array: this, i, block, tracked_elements });
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
tracked_elements.length = after_len;
|
|
545
|
+
|
|
546
|
+
set(this.#tracked_index, this.length, block);
|
|
547
|
+
return result;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
get [TRACKED_OBJECT]() {
|
|
551
|
+
return this.#tracked_elements;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
get $length() {
|
|
555
|
+
return get(this.#tracked_index);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/** @param {number} length */
|
|
559
|
+
set $length(length) {
|
|
560
|
+
if (length === this.length) {
|
|
561
|
+
return;
|
|
548
562
|
}
|
|
549
563
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
set(this.#tracked_index, length, block);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
/** @param {number} _ */
|
|
582
|
-
set length(_) {
|
|
583
|
-
// This doesn't actually work because length cannot be overridden.
|
|
584
|
-
// This error is now moved to runtime to catch direct assignments to length
|
|
585
|
-
throw new Error('Cannot set length on RippleArray, use $length instead');
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
toJSON() {
|
|
589
|
-
this.$length;
|
|
590
|
-
return get_all_elements(this);
|
|
591
|
-
}
|
|
564
|
+
var block = safe_scope();
|
|
565
|
+
var tracked_elements = this.#tracked_elements;
|
|
566
|
+
var tracked_len = tracked_elements.length;
|
|
567
|
+
|
|
568
|
+
if (length < tracked_len) {
|
|
569
|
+
for (var i = length; i < tracked_len; i++) {
|
|
570
|
+
if (tracked_elements[i] !== undefined) {
|
|
571
|
+
set(tracked_elements[i], undefined, block);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
this.length = length;
|
|
577
|
+
tracked_elements.length = length;
|
|
578
|
+
set(this.#tracked_index, length, block);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/** @param {number} _ */
|
|
582
|
+
set length(_) {
|
|
583
|
+
// This doesn't actually work because length cannot be overridden.
|
|
584
|
+
// This error is now moved to runtime to catch direct assignments to length
|
|
585
|
+
throw new Error('Cannot set length on RippleArray, use $length instead');
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
toJSON() {
|
|
589
|
+
this.$length;
|
|
590
|
+
return get_all_elements(this);
|
|
591
|
+
}
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
/**
|
|
@@ -597,22 +597,22 @@ export class RippleArray extends Array {
|
|
|
597
597
|
* @returns {T[]}
|
|
598
598
|
*/
|
|
599
599
|
export function get_all_elements(array) {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
600
|
+
/** @type {Tracked[]} */
|
|
601
|
+
var tracked_elements = /** @type {Tracked[]} */ (array[TRACKED_OBJECT]);
|
|
602
|
+
// pre-allocate to support holey arrays
|
|
603
|
+
var result = new Array(array.length);
|
|
604
|
+
|
|
605
|
+
for (var i = 0; i < array.length; i++) {
|
|
606
|
+
if (tracked_elements[i] !== undefined) {
|
|
607
|
+
get(tracked_elements[i]);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (i in array) {
|
|
611
|
+
result[i] = array[i];
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return result;
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
/**
|
|
@@ -620,14 +620,14 @@ export function get_all_elements(array) {
|
|
|
620
620
|
* @param {RippleArray<T>} array
|
|
621
621
|
* @returns {void}
|
|
622
622
|
*/
|
|
623
|
-
function establish_trackable_deps
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
623
|
+
function establish_trackable_deps(array) {
|
|
624
|
+
var tracked_elements = array[TRACKED_OBJECT];
|
|
625
|
+
|
|
626
|
+
for (var i = 0; i < tracked_elements.length; i++) {
|
|
627
|
+
if (tracked_elements[i] !== undefined) {
|
|
628
|
+
get(tracked_elements[i]);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
631
|
}
|
|
632
632
|
|
|
633
633
|
/**
|
|
@@ -636,20 +636,20 @@ function establish_trackable_deps (array) {
|
|
|
636
636
|
* @returns {RippleArray<T>}
|
|
637
637
|
*/
|
|
638
638
|
function get_instance_from_static(array) {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
639
|
+
/** @type RippleArray<T> */
|
|
640
|
+
var result;
|
|
641
|
+
/** @type {T | void} */
|
|
642
|
+
var first = get_first_if_length(array);
|
|
643
|
+
|
|
644
|
+
if (first) {
|
|
645
|
+
result = new RippleArray();
|
|
646
|
+
result[0] = first;
|
|
647
|
+
result[INIT_AFTER_NEW]();
|
|
648
|
+
} else {
|
|
649
|
+
result = new RippleArray(...array);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return result;
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
/**
|
|
@@ -657,14 +657,16 @@ function get_instance_from_static(array) {
|
|
|
657
657
|
* @param {T[]} array
|
|
658
658
|
* @returns {T | void}
|
|
659
659
|
*/
|
|
660
|
-
function get_first_if_length
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
660
|
+
function get_first_if_length(array) {
|
|
661
|
+
var first = array[0];
|
|
662
|
+
|
|
663
|
+
if (
|
|
664
|
+
array.length === 1 &&
|
|
665
|
+
0 in array &&
|
|
666
|
+
Number.isInteger(first) &&
|
|
667
|
+
/** @type {number} */ (first) >= 0 &&
|
|
668
|
+
/** @type {number} */ (first) <= MAX_ARRAY_LENGTH
|
|
669
|
+
) {
|
|
670
|
+
return first;
|
|
671
|
+
}
|
|
670
672
|
}
|