ripple 0.2.52 → 0.2.54

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.
@@ -1,661 +1,209 @@
1
- import {
2
- TRACKED_OBJECT,
3
- ARRAY_SET_INDEX_AT,
4
- MAX_ARRAY_LENGTH,
5
- } from './internal/client/constants.js';
1
+ /** @import { Block } from '#client' */
2
+ import { MAX_ARRAY_LENGTH, TRACKED_ARRAY, UNINITIALIZED } from './internal/client/constants.js';
6
3
  import { get, safe_scope, set, tracked } from './internal/client/runtime.js';
7
- import { is_ripple_array } from './internal/client/utils.js';
8
- /** @import { Block, Tracked } from '#client' */
9
-
10
- /** @type {unique symbol} */
11
- const INIT_AFTER_NEW = Symbol();
12
-
13
- /** @type {(symbol | string | any)[]} */
14
- const introspect_methods = [
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',
44
- ];
45
-
46
- let is_proto_set = false;
4
+ import { get_descriptor } from './internal/client/utils.js';
47
5
 
48
6
  /**
49
7
  * @template T
50
- * @extends {Array<T>}
8
+ * @constructor
9
+ * @param {...T} elements
10
+ * @returns {TrackedArray<T>}
51
11
  */
52
- export class RippleArray extends Array {
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);
12
+ export function TrackedArray(...elements) {
13
+ if (!new.target) {
14
+ throw new Error("TrackedArray must be called with 'new'");
70
15
  }
71
16
 
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];
97
- }
98
- }
99
- }
17
+ var block = safe_scope();
100
18
 
101
- result[INIT_AFTER_NEW](block);
102
-
103
- return result;
104
- }
19
+ return proxy(elements, block);
20
+ }
105
21
 
106
- /**
107
- * @template U
108
- * @param {...U} elements
109
- * @returns {RippleArray<U>}
110
- */
111
- static of(...elements) {
112
- var arr = Array.of(...elements);
22
+ /**
23
+ * @template T
24
+ * @param {ArrayLike<T> | Iterable<T>} arrayLike
25
+ * @param {(v: T, k: number) => any | undefined} [mapFn]
26
+ * @param {*} [thisArg]
27
+ * @returns {TrackedArray<T>}
28
+ */
29
+ TrackedArray.from = function (arrayLike, mapFn, thisArg) {
30
+ var block = safe_scope();
31
+ var elements = mapFn ? Array.from(arrayLike, mapFn, thisArg) : Array.from(arrayLike);
32
+ return proxy(elements, block, true);
33
+ };
113
34
 
114
- return get_instance_from_static(arr);
115
- }
35
+ /**
36
+ * @template T
37
+ * @param {...T} items
38
+ * @returns {TrackedArray<T>}
39
+ */
40
+ TrackedArray.of = function (...items) {
41
+ var block = safe_scope();
42
+ var elements = Array.of(...items);
43
+ return proxy(elements, block, true);
44
+ };
116
45
 
117
- /**
118
- * @param {...T} elements
119
- */
120
- constructor(...elements) {
121
- super(...elements);
46
+ /**
47
+ * @template T
48
+ * @param {ArrayLike<T> | Iterable<T>} arrayLike
49
+ * @param {(v: T, k: number) => any | undefined} [mapFn]
50
+ * @param {any} [thisArg]
51
+ * @returns {Promise<TrackedArray<T>>}
52
+ */
53
+ TrackedArray.fromAsync = async function (arrayLike, mapFn, thisArg) {
54
+ var block = safe_scope();
55
+ var elements = mapFn
56
+ ? await Array.fromAsync(arrayLike, mapFn, thisArg)
57
+ : await Array.fromAsync(arrayLike);
58
+ return proxy(elements, block, true);
59
+ };
122
60
 
123
- this[INIT_AFTER_NEW]();
61
+ /**
62
+ * @template T
63
+ * @param {Iterable<T>} elements
64
+ * @param {Block} block
65
+ * @param {boolean} is_from_static
66
+ * @returns {TrackedArray<T>}
67
+ */
68
+ function proxy(elements, block, is_from_static = false) {
69
+ var arr;
70
+ var first;
124
71
 
125
- if (!is_proto_set) {
126
- is_proto_set = true;
127
- this.#set_proto();
128
- }
72
+ if (
73
+ is_from_static &&
74
+ (first = get_first_if_length(/** @type {Array<T>} */ (elements))) !== undefined
75
+ ) {
76
+ arr = new Array();
77
+ arr[0] = first;
78
+ } else {
79
+ arr = new Array(...elements);
129
80
  }
130
81
 
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;
137
- }
138
- tracked_elements[i] = tracked(this[i], block);
139
- }
140
- }
141
-
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
- }
82
+ var tracked_elements = new Map();
83
+ var tracked_len = tracked(arr.length, block);
84
+ tracked_elements.set('length', tracked_len);
148
85
 
149
- #set_proto() {
150
- var proto = RippleArray.prototype;
151
- var array_proto = Array.prototype;
86
+ return new Proxy(arr, {
87
+ get(target, prop, receiver) {
88
+ var t = tracked_elements.get(prop);
89
+ var exists = prop in target;
152
90
 
153
- for (const method of introspect_methods) {
154
- if (!(method in array_proto)) {
155
- continue;
91
+ if (t === undefined && (!exists || get_descriptor(target, prop)?.writable)) {
92
+ t = tracked(exists ? target[prop] : UNINITIALIZED, block);
93
+ tracked_elements.set(prop, t);
156
94
  }
157
95
 
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();
96
+ if (t !== undefined) {
97
+ var v = get(t);
98
+ return v === UNINITIALIZED ? undefined : v;
99
+ }
165
100
 
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
- }
101
+ return Reflect.get(target, prop, receiver);
102
+ },
103
+
104
+ set(target, prop, value, receiver) {
105
+ var t = tracked_elements.get(prop);
106
+ var exists = prop in target;
107
+
108
+ if (prop === 'length') {
109
+ for (var i = value; i < tracked_len.v; i += 1) {
110
+ var other_t = tracked_elements.get(i + '');
111
+ if (other_t !== undefined) {
112
+ set(other_t, UNINITIALIZED, block);
113
+ } else if (i in target) {
114
+ // If the item exists in the original, we need to create a uninitialized tracked,
115
+ // else a later read of the property would result in a tracked being created with
116
+ // the value of the original item at that index.
117
+ other_t = tracked(UNINITIALIZED, block);
118
+ tracked_elements.set(i + '', other_t);
172
119
  }
173
120
  }
174
-
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
- }
216
-
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
- }
224
-
225
- if (target >= length) {
226
- return this;
227
- }
228
-
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
121
  }
243
- }
244
122
 
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
- }
123
+ // If we haven't yet created a tracked for this property, we need to ensure
124
+ // we do so otherwise if we read it later, then the write won't be tracked and
125
+ // the heuristics of effects will be different vs if we had read the proxied
126
+ // object property before writing to that property.
127
+ if (t === undefined) {
128
+ if (!exists || get_descriptor(target, prop)?.writable) {
129
+ t = tracked(undefined, block);
130
+ set(t, value, block);
279
131
 
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);
132
+ tracked_elements.set(prop, t);
133
+ }
292
134
  } 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
- }
135
+ exists = t.v !== UNINITIALIZED;
329
136
 
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);
137
+ set(t, value, block);
352
138
  }
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
139
 
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();
140
+ var result = Reflect.set(target, prop, value, receiver);
397
141
 
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;
142
+ if (!exists) {
143
+ // If we have mutated an array directly, we might need to
144
+ // signal that length has also changed. Do it before updating metadata
145
+ // to ensure that iterating over the array as a result of a metadata update
146
+ // will not cause the length to be out of sync.
147
+ if (typeof prop === 'string') {
148
+ var n = Number(prop);
410
149
 
411
- super.push(...elements);
412
-
413
- for (var i = 0; i < elements.length; i++) {
414
- if (!(i in elements)) {
415
- continue;
150
+ if (Number.isInteger(n) && n >= tracked_len.v) {
151
+ set(tracked_len, n + 1, block);
152
+ }
153
+ }
416
154
  }
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
155
 
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
156
  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);
157
+ },
539
158
 
540
- for (let i = start; i < range_end; i++) {
541
- this.#update_tracked_at_index({ array: this, i, block, tracked_elements });
542
- }
159
+ setPrototypeOf() {
160
+ throw new Error(`Cannot set prototype of \`TrackedArray\``);
161
+ },
543
162
 
544
- tracked_elements.length = after_len;
163
+ deleteProperty(target, prop) {
164
+ var t = tracked_elements.get(prop);
545
165
 
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;
562
- }
563
-
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);
166
+ if (t === undefined) {
167
+ if (prop in target) {
168
+ const t = tracked(UNINITIALIZED, block);
169
+ tracked_elements.set(prop, t);
572
170
  }
171
+ } else {
172
+ set(t, UNINITIALIZED, block);
573
173
  }
574
- }
575
174
 
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
- }
175
+ return Reflect.deleteProperty(target, prop);
176
+ },
587
177
 
588
- toJSON() {
589
- this.$length;
590
- return get_all_elements(this);
591
- }
592
- }
593
-
594
- /**
595
- * @template T
596
- * @param {RippleArray<T>} array
597
- * @returns {T[]}
598
- */
599
- export function get_all_elements(array) {
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
- }
178
+ has(target, prop) {
179
+ if (prop === TRACKED_ARRAY) {
180
+ return true;
181
+ }
182
+ var t = tracked_elements.get(prop);
183
+ var exists = (t !== undefined && t.v !== UNINITIALIZED) || Reflect.has(target, prop);
617
184
 
618
- /**
619
- * @template T
620
- * @param {RippleArray<T>} array
621
- * @returns {void}
622
- */
623
- function establish_trackable_deps(array) {
624
- var tracked_elements = array[TRACKED_OBJECT];
185
+ if (t !== undefined || !exists || get_descriptor(target, prop)?.writable) {
186
+ if (t === undefined) {
187
+ t = tracked(exists ? target[prop] : UNINITIALIZED, block);
625
188
 
626
- for (var i = 0; i < tracked_elements.length; i++) {
627
- if (tracked_elements[i] !== undefined) {
628
- get(tracked_elements[i]);
629
- }
630
- }
631
- }
189
+ tracked_elements.set(prop, t);
190
+ }
632
191
 
633
- /**
634
- * @template T
635
- * @param {T[]} array
636
- * @returns {RippleArray<T>}
637
- */
638
- function get_instance_from_static(array) {
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
- }
192
+ var value = get(t);
193
+ if (value === UNINITIALIZED) {
194
+ return false;
195
+ }
196
+ }
651
197
 
652
- return result;
198
+ return exists;
199
+ },
200
+ });
653
201
  }
654
202
 
655
203
  /**
656
204
  * @template T
657
- * @param {T[]} array
658
- * @returns {T | void}
205
+ * @param {Array<T>} array
206
+ * @returns {number | void}
659
207
  */
660
208
  function get_first_if_length(array) {
661
209
  var first = array[0];
@@ -667,6 +215,6 @@ function get_first_if_length(array) {
667
215
  /** @type {number} */ (first) >= 0 &&
668
216
  /** @type {number} */ (first) <= MAX_ARRAY_LENGTH
669
217
  ) {
670
- return first;
218
+ return /** @type {number} */ (first);
671
219
  }
672
220
  }