ripple 0.2.53 → 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.
@@ -50,11 +50,11 @@ export function track(v, b) {
50
50
  return tracked(v, b);
51
51
  }
52
52
 
53
- export { RippleArray } from './array.js';
53
+ export { TrackedArray } from './array.js';
54
54
 
55
- export { RippleSet } from './set.js';
55
+ export { TrackedSet } from './set.js';
56
56
 
57
- export { RippleMap } from './map.js';
57
+ export { TrackedMap } from './map.js';
58
58
 
59
59
  export { keyed } from './internal/client/for.js';
60
60
 
@@ -20,7 +20,7 @@ export var LOGIC_BLOCK = FOR_BLOCK | IF_BLOCK | TRY_BLOCK;
20
20
 
21
21
  export var UNINITIALIZED = Symbol();
22
22
  /** @type {unique symbol} */
23
- export const TRACKED_OBJECT = Symbol();
23
+ export const TRACKED_ARRAY = Symbol();
24
24
  export var COMPUTED_PROPERTY = Symbol();
25
25
  export var REF_PROP = 'ref';
26
26
  /** @type {unique symbol} */
@@ -1,7 +1,6 @@
1
1
  import { IS_CONTROLLED } from '../../../constants';
2
- import { get_all_elements } from '../../array';
3
2
  import { branch, destroy_block, destroy_block_children, render } from './blocks';
4
- import { FOR_BLOCK, TRACKED_OBJECT } from './constants';
3
+ import { FOR_BLOCK, TRACKED_ARRAY } from './constants';
5
4
  import { create_text } from './operations';
6
5
  import { active_block, untrack } from './runtime';
7
6
  import { array_from, is_array } from './utils';
@@ -45,9 +44,10 @@ export function for_block(node, get_collection, render_fn, flags) {
45
44
  ? []
46
45
  : array_from(collection);
47
46
 
48
- if (array[TRACKED_OBJECT] !== undefined) {
49
- array = get_all_elements(collection);
50
- collection.$length;
47
+ // If we are working with a tracked array, then we need to get a copy of
48
+ // the elements, as the array itself is proxied, and not useful in diffing
49
+ if (TRACKED_ARRAY in array) {
50
+ array = array_from(array);
51
51
  }
52
52
 
53
53
  untrack(() => reconcile(anchor, block, array, render_fn, is_controlled));
@@ -24,25 +24,15 @@ export {
24
24
  set,
25
25
  async_computed,
26
26
  tracked,
27
- tracked_object,
28
- tracked_spread_object,
27
+ spread_props,
29
28
  computed_property,
30
29
  call_property,
31
30
  get_property,
32
- old_get_property,
33
- old_set_property,
34
31
  set_property,
35
32
  update,
36
33
  update_pre,
37
- old_update_property,
38
34
  update_property,
39
- old_update_pre_property,
40
35
  update_pre_property,
41
- object_values,
42
- object_entries,
43
- object_keys,
44
- spread_object,
45
- structured_clone,
46
36
  push_component,
47
37
  pop_component,
48
38
  untrack,
@@ -1,4 +1,3 @@
1
- import { TRACKED_OBJECT } from './constants.js';
2
1
  import { get_descriptor } from './utils.js';
3
2
 
4
3
  /** @type {() => Node | null} */
@@ -33,8 +32,6 @@ export function init_operations() {
33
32
  // @ts-expect-error
34
33
  element_prototype.__e = undefined;
35
34
  // @ts-expect-error
36
- object_prototype[TRACKED_OBJECT] = undefined;
37
- // @ts-expect-error
38
35
  event_target_prototype.__root = undefined;
39
36
  }
40
37
 
@@ -2,26 +2,25 @@ import { branch, destroy_block, render } from './blocks';
2
2
  import { UNINITIALIZED } from './constants';
3
3
  import { handle_root_events } from './events';
4
4
  import { create_text } from './operations';
5
- import { old_get_property } from './runtime';
6
5
 
7
6
  export function Portal(_, props) {
8
- let $target = UNINITIALIZED;
7
+ let target = UNINITIALIZED;
9
8
  let children = UNINITIALIZED;
10
9
  var b = null;
11
10
  var anchor = null;
12
11
 
13
12
  render(() => {
14
- if ($target === ($target = old_get_property(props, '$target'))) return;
15
- if (children === (children = old_get_property(props, 'children'))) return;
13
+ if (target === (target = props.target)) return;
14
+ if (children === (children = props.children)) return;
16
15
 
17
16
  if (b !== null) {
18
17
  destroy_block(b);
19
18
  }
20
19
 
21
20
  anchor = create_text();
22
- $target.append(anchor);
21
+ target.append(anchor);
23
22
 
24
- const cleanup_events = handle_root_events($target);
23
+ const cleanup_events = handle_root_events(target);
25
24
 
26
25
  b = branch(() => children(anchor));
27
26
 
@@ -21,20 +21,12 @@ import {
21
21
  PAUSED,
22
22
  ROOT_BLOCK,
23
23
  TRACKED,
24
- TRACKED_OBJECT,
25
24
  TRY_BLOCK,
26
25
  UNINITIALIZED,
27
26
  REF_PROP,
28
- ARRAY_SET_INDEX_AT,
29
27
  } from './constants';
30
28
  import { capture, suspend } from './try.js';
31
- import { define_property, get_descriptor, is_ripple_array, is_positive_integer } from './utils';
32
- import {
33
- object_keys as original_object_keys,
34
- object_values as original_object_values,
35
- object_entries as original_object_entries,
36
- structured_clone as original_structured_clone,
37
- } from './utils.js';
29
+ import { define_property, is_ripple_array } from './utils';
38
30
 
39
31
  const FLUSH_MICROTASK = 0;
40
32
  const FLUSH_SYNC = 1;
@@ -408,50 +400,43 @@ export function async_computed(fn, block) {
408
400
  }
409
401
 
410
402
  export function deferred(fn) {
411
- var parent = active_block;
412
- var block = active_scope;
413
- var res = [UNINITIALIZED];
414
- // TODO implement DEFERRED flag on tracked
415
- var t = tracked(UNINITIALIZED, block, DEFERRED);
416
- var tracked_properties = [t];
417
- var prev_value = UNINITIALIZED;
418
-
419
- define_property(res, TRACKED_OBJECT, {
420
- value: tracked_properties,
421
- enumerable: false,
422
- });
423
-
424
- render(() => {
425
- if (prev_value !== UNINITIALIZED) {
426
- t.v = prev_value;
427
- } else {
428
- prev_value = t.v;
429
- }
430
- var prev_version = t.c;
431
- var value = fn();
432
-
433
- res[0] = value;
434
- old_set_property(res, 0, value, block);
435
-
436
- if (prev_value !== UNINITIALIZED) {
437
- if ((t.f & DEFERRED) === 0) {
438
- t.f ^= DEFERRED;
439
- }
440
-
441
- var is_awaited = flush_deferred_upodates(parent);
442
- if ((t.f & DEFERRED) !== 0) {
443
- t.f ^= DEFERRED;
444
- }
445
-
446
- if (is_awaited) {
447
- t.c = prev_version;
448
- t.v = prev_value;
449
- prev_value = value;
450
- }
451
- }
452
- });
453
-
454
- return res;
403
+ // var parent = active_block;
404
+ // var block = active_scope;
405
+ // var res = [UNINITIALIZED];
406
+ // // TODO implement DEFERRED flag on tracked
407
+ // var t = tracked(UNINITIALIZED, block, DEFERRED);
408
+ // var tracked_properties = [t];
409
+ // var prev_value = UNINITIALIZED;
410
+ // define_property(res, TRACKED_OBJECT, {
411
+ // value: tracked_properties,
412
+ // enumerable: false,
413
+ // });
414
+ // render(() => {
415
+ // if (prev_value !== UNINITIALIZED) {
416
+ // t.v = prev_value;
417
+ // } else {
418
+ // prev_value = t.v;
419
+ // }
420
+ // var prev_version = t.c;
421
+ // var value = fn();
422
+ // res[0] = value;
423
+ // old_set_property(res, 0, value, block);
424
+ // if (prev_value !== UNINITIALIZED) {
425
+ // if ((t.f & DEFERRED) === 0) {
426
+ // t.f ^= DEFERRED;
427
+ // }
428
+ // var is_awaited = flush_deferred_upodates(parent);
429
+ // if ((t.f & DEFERRED) !== 0) {
430
+ // t.f ^= DEFERRED;
431
+ // }
432
+ // if (is_awaited) {
433
+ // t.c = prev_version;
434
+ // t.v = prev_value;
435
+ // prev_value = value;
436
+ // }
437
+ // }
438
+ // });
439
+ // return res;
455
440
  }
456
441
 
457
442
  function capture_deferred(fn) {
@@ -783,68 +768,18 @@ export function flush_sync(fn) {
783
768
  * @param {Block} block
784
769
  * @returns {Object}
785
770
  */
786
- export function tracked_spread_object(fn, block) {
771
+ export function spread_props(fn, block) {
787
772
  let computed = derived(fn, block);
788
773
 
789
- return new Proxy({}, {
790
- get(target, property) {
791
- const obj = get_derived(computed);
792
- return obj[property];
793
- }
794
- });
795
- }
796
-
797
- /**
798
- * @param {any} obj
799
- * @param {string[]} properties
800
- * @param {Block} block
801
- * @returns {object}
802
- */
803
- export function tracked_object(obj, properties, block) {
804
- /** @type {Record<string, Tracked | Derived>} */
805
- var tracked_properties = obj[TRACKED_OBJECT];
806
-
807
- if (tracked_properties === undefined) {
808
- tracked_properties = {};
809
- define_property(obj, TRACKED_OBJECT, {
810
- value: tracked_properties,
811
- enumerable: false,
812
- });
813
- }
814
-
815
- for (var i = 0; i < properties.length; i++) {
816
- var property = properties[i];
817
- /** @type {Tracked | Derived} */
818
- var tracked_property;
819
-
820
- // accessor passed in, to avoid an expensive get_descriptor call in the fast path
821
- if (property[0] === '#') {
822
- property = property.slice(1);
823
- var descriptor = /** @type {PropertyDescriptor} */ (get_descriptor(obj, property));
824
- var desc_get = descriptor.get;
825
- tracked_property = derived(desc_get, block);
826
- /** @type {any} */
827
- var initial = run_derived(/** @type {Derived} */ (tracked_property));
828
- // If there's a setter, we need to set the initial value
829
- if (descriptor.set !== undefined) {
830
- obj[property] = initial;
831
- }
832
- } else {
833
- var initial = obj[property];
834
-
835
- if (typeof initial === 'function' && initial[COMPUTED_PROPERTY] === true) {
836
- tracked_property = derived(initial, block);
837
- initial = run_derived(/** @type {Derived} */ (tracked_property));
838
- obj[property] = initial;
839
- } else {
840
- tracked_property = tracked(initial, block);
841
- }
842
- }
843
-
844
- tracked_properties[property] = tracked_property;
845
- }
846
-
847
- return obj;
774
+ return new Proxy(
775
+ {},
776
+ {
777
+ get(target, property) {
778
+ const obj = get_derived(computed);
779
+ return obj[property];
780
+ },
781
+ },
782
+ );
848
783
  }
849
784
 
850
785
  /**
@@ -899,72 +834,11 @@ export function get_property(obj, property, chain = false) {
899
834
  return get(tracked);
900
835
  }
901
836
 
902
- /**
903
- * @param {any} obj
904
- * @param {string | number | symbol} property
905
- * @param {boolean} [chain=false]
906
- * @returns {any}
907
- */
908
- export function old_get_property(obj, property, chain = false) {
909
- if (chain && obj == null) {
910
- return undefined;
911
- }
912
- var value = obj[property];
913
- var tracked_properties = obj[TRACKED_OBJECT];
914
- var tracked_property = tracked_properties?.[property];
915
-
916
- if (tracked_property !== undefined) {
917
- value = get(tracked_property);
918
- if (obj[property] !== value) {
919
- obj[property] = value;
920
- }
921
- } else if (is_ripple_array(obj)) {
922
- obj.$length;
923
- }
924
-
925
- return value;
926
- }
927
-
928
837
  export function set_property(obj, property, value, block) {
929
838
  var tracked = obj[property];
930
839
  set(tracked, value, block);
931
840
  }
932
841
 
933
- /**
934
- * @param {any} obj
935
- * @param {string | number | symbol} property
936
- * @param {any} value
937
- * @param {Block} block
938
- * @returns {any}
939
- */
940
- export function old_set_property(obj, property, value, block) {
941
- var tracked_properties = obj[TRACKED_OBJECT];
942
- var rip_arr = is_ripple_array(obj);
943
- var tracked = !(rip_arr && property === 'length') ? tracked_properties?.[property] : undefined;
944
-
945
- if (tracked === undefined) {
946
- // Handle computed assignments to arrays
947
- if (rip_arr) {
948
- if (property === 'length') {
949
- // overriding `length` in RippleArray class doesn't work
950
- // placing it here instead
951
- throw new Error('Cannot set length on RippleArray, use $length instead');
952
- } else if (is_positive_integer(property)) {
953
- // for any other type we use obj[property] = value below as per native JS
954
- return with_scope(block, () => {
955
- obj[ARRAY_SET_INDEX_AT](property, value);
956
- });
957
- }
958
- }
959
-
960
- return (obj[property] = value);
961
- }
962
-
963
- obj[property] = value;
964
-
965
- set(tracked, value, block);
966
- }
967
-
968
842
  /**
969
843
  * @param {Tracked} tracked
970
844
  * @param {Block} block
@@ -1017,36 +891,6 @@ export function update_property(obj, property, block, d = 1) {
1017
891
  return new_value;
1018
892
  }
1019
893
 
1020
- /**
1021
- * @param {any} obj
1022
- * @param {string | number | symbol} property
1023
- * @param {Block} block
1024
- * @param {number} [d]
1025
- * @returns {number}
1026
- */
1027
- export function old_update_property(obj, property, block, d = 1) {
1028
- var tracked_properties = obj[TRACKED_OBJECT];
1029
- var tracked = tracked_properties?.[property];
1030
- var tracked_exists = tracked !== undefined;
1031
- var value = tracked_exists ? get(tracked) : obj[property];
1032
-
1033
- if (d === 1) {
1034
- value++;
1035
- if (tracked_exists) {
1036
- increment(tracked, block);
1037
- }
1038
- } else {
1039
- value--;
1040
- if (tracked_exists) {
1041
- decrement(tracked, block);
1042
- }
1043
- }
1044
-
1045
- obj[property] = value;
1046
-
1047
- return value;
1048
- }
1049
-
1050
894
  export function update_pre_property(obj, property, block, d = 1) {
1051
895
  var tracked = obj[property];
1052
896
  var value = get(tracked);
@@ -1055,117 +899,6 @@ export function update_pre_property(obj, property, block, d = 1) {
1055
899
  return new_value;
1056
900
  }
1057
901
 
1058
- /**
1059
- * @param {any} obj
1060
- * @param {string | number | symbol} property
1061
- * @param {Block} block
1062
- * @param {number} [d]
1063
- * @returns {number}
1064
- */
1065
- export function old_update_pre_property(obj, property, block, d = 1) {
1066
- var tracked_properties = obj[TRACKED_OBJECT];
1067
- var tracked = tracked_properties?.[property];
1068
- var tracked_exists = tracked !== undefined;
1069
- var value = tracked_exists ? get(tracked) : obj[property];
1070
-
1071
- if (d === 1) {
1072
- ++value;
1073
- if (tracked_exists) {
1074
- increment(tracked, block);
1075
- }
1076
- } else {
1077
- --value;
1078
- if (tracked_exists) {
1079
- decrement(tracked, block);
1080
- }
1081
- }
1082
-
1083
- obj[property] = value;
1084
-
1085
- return value;
1086
- }
1087
-
1088
- /**
1089
- * @param {any} val
1090
- * @param {StructuredSerializeOptions} [options]
1091
- * @returns {any}
1092
- */
1093
- export function structured_clone(val, options) {
1094
- if (typeof val === 'object' && val !== null) {
1095
- var tracked_properties = val[TRACKED_OBJECT];
1096
- if (tracked_properties !== undefined) {
1097
- if (is_ripple_array(val)) {
1098
- val.$length;
1099
- }
1100
- return structured_clone(object_values(val), options);
1101
- }
1102
- }
1103
- return original_structured_clone(val, options);
1104
- }
1105
-
1106
- export function object_keys(obj) {
1107
- if (is_ripple_array(obj)) {
1108
- obj.$length;
1109
- }
1110
- return original_object_keys(obj);
1111
- }
1112
-
1113
- export function object_values(obj) {
1114
- var tracked_properties = obj[TRACKED_OBJECT];
1115
-
1116
- if (tracked_properties === undefined) {
1117
- return original_object_values(obj);
1118
- }
1119
- if (is_ripple_array(obj)) {
1120
- obj.$length;
1121
- }
1122
- var keys = original_object_keys(obj);
1123
- var values = [];
1124
-
1125
- for (var i = 0; i < keys.length; i++) {
1126
- values.push(old_get_property(obj, keys[i]));
1127
- }
1128
-
1129
- return values;
1130
- }
1131
-
1132
- export function object_entries(obj) {
1133
- var tracked_properties = obj[TRACKED_OBJECT];
1134
-
1135
- if (tracked_properties === undefined) {
1136
- return original_object_entries(obj);
1137
- }
1138
- if (is_ripple_array(obj)) {
1139
- obj.$length;
1140
- }
1141
- var keys = original_object_keys(obj);
1142
- var entries = [];
1143
-
1144
- for (var i = 0; i < keys.length; i++) {
1145
- var key = keys[i];
1146
- entries.push([key, old_get_property(obj, key)]);
1147
- }
1148
-
1149
- return entries;
1150
- }
1151
-
1152
- export function spread_object(obj) {
1153
- var tracked_properties = obj[TRACKED_OBJECT];
1154
-
1155
- if (tracked_properties === undefined) {
1156
- return { ...obj };
1157
- }
1158
- var keys = original_object_keys(obj);
1159
- var values = {};
1160
-
1161
- for (var i = 0; i < keys.length; i++) {
1162
- var key = keys[i];
1163
- values[key] = old_get_property(obj, key);
1164
- }
1165
-
1166
- return values;
1167
- }
1168
-
1169
902
  /**
1170
903
  * @template T
1171
904
  * @param {Block} block
@@ -1,5 +1,3 @@
1
- import { TRACKED_OBJECT } from './constants.js';
2
-
3
1
  export var get_descriptor = Object.getOwnPropertyDescriptor;
4
2
  export var get_descriptors = Object.getOwnPropertyDescriptors;
5
3
  export var array_from = Array.from;
@@ -18,14 +16,6 @@ export function create_anchor() {
18
16
  return t;
19
17
  }
20
18
 
21
- /**
22
- * @param {any} obj
23
- * @returns {boolean}
24
- */
25
- export function is_ripple_array(obj) {
26
- return is_array(obj) && TRACKED_OBJECT in obj && '$length' in obj;
27
- }
28
-
29
19
  /**
30
20
  * @param {any} value
31
21
  * @returns {boolean}
@@ -1,17 +1,30 @@
1
+ /** @import { Block, Tracked } from '#client' */
1
2
  import { get, increment, safe_scope, set, tracked } from './internal/client/runtime.js';
2
3
 
3
4
  const introspect_methods = ['entries', 'forEach', 'values', Symbol.iterator];
4
5
 
5
6
  let init = false;
6
7
 
7
- export class RippleMap extends Map {
8
+ /**
9
+ * @template K, V
10
+ * @extends {Map<K, V>}
11
+ * @returns {TrackedMap<K, V>}
12
+ */
13
+ export class TrackedMap extends Map {
14
+ /** @type {Tracked} */
8
15
  #tracked_size;
16
+ /** @type {Map<K, Tracked>} */
9
17
  #tracked_items = new Map();
18
+ /** @type {Block} */
19
+ #block;
10
20
 
21
+ /**
22
+ * @param {Iterable<readonly [K, V]>} [iterable]
23
+ */
11
24
  constructor(iterable) {
12
25
  super();
13
26
 
14
- var block = safe_scope();
27
+ var block = this.#block = safe_scope();
15
28
 
16
29
  if (iterable) {
17
30
  for (var [key, value] of iterable) {
@@ -20,7 +33,7 @@ export class RippleMap extends Map {
20
33
  }
21
34
  }
22
35
 
23
- this.#tracked_size = tracked(this.size, block);
36
+ this.#tracked_size = tracked(super.size, block);
24
37
 
25
38
  if (!init) {
26
39
  init = true;
@@ -29,12 +42,12 @@ export class RippleMap extends Map {
29
42
  }
30
43
 
31
44
  #init() {
32
- var proto = RippleMap.prototype;
45
+ var proto = TrackedMap.prototype;
33
46
  var map_proto = Map.prototype;
34
47
 
35
48
  for (const method of introspect_methods) {
36
49
  proto[method] = function (...v) {
37
- this.$size;
50
+ this.size;
38
51
  this.#read_all();
39
52
 
40
53
  return map_proto[method].apply(this, v);
@@ -48,7 +61,7 @@ export class RippleMap extends Map {
48
61
 
49
62
  if (t === undefined) {
50
63
  // same logic as has
51
- this.$size;
64
+ this.size;
52
65
  } else {
53
66
  get(t);
54
67
  }
@@ -66,7 +79,7 @@ export class RippleMap extends Map {
66
79
  // It's not possible to have a disconnect, we tract each key
67
80
  // If the key doesn't exist, track the size in case it's added later
68
81
  // but don't create tracked entries willy-nilly to track all possible keys
69
- this.$size;
82
+ this.size;
70
83
  } else {
71
84
  get(t);
72
85
  }
@@ -75,7 +88,7 @@ export class RippleMap extends Map {
75
88
  }
76
89
 
77
90
  set(key, value) {
78
- var block = safe_scope();
91
+ var block = this.#block;
79
92
  var tracked_items = this.#tracked_items;
80
93
  var t = tracked_items.get(key);
81
94
  var prev_res = super.get(key);
@@ -84,7 +97,7 @@ export class RippleMap extends Map {
84
97
 
85
98
  if (!t) {
86
99
  tracked_items.set(key, tracked(0, block));
87
- set(this.#tracked_size, this.size, block);
100
+ set(this.#tracked_size, super.size, block);
88
101
  } else if (prev_res !== value) {
89
102
  increment(t, block);
90
103
  }
@@ -93,7 +106,7 @@ export class RippleMap extends Map {
93
106
  }
94
107
 
95
108
  delete(key) {
96
- var block = safe_scope();
109
+ var block = this.#block;
97
110
  var tracked_items = this.#tracked_items;
98
111
  var t = tracked_items.get(key);
99
112
  var result = super.delete(key);
@@ -101,14 +114,14 @@ export class RippleMap extends Map {
101
114
  if (t) {
102
115
  increment(t, block);
103
116
  tracked_items.delete(key);
104
- set(this.#tracked_size, this.size, block);
117
+ set(this.#tracked_size, super.size, block);
105
118
  }
106
119
 
107
120
  return result;
108
121
  }
109
122
 
110
123
  clear() {
111
- var block = safe_scope();
124
+ var block = this.#block;
112
125
 
113
126
  if (super.size === 0) {
114
127
  return;
@@ -124,7 +137,7 @@ export class RippleMap extends Map {
124
137
  }
125
138
 
126
139
  keys() {
127
- this.$size;
140
+ this.size;
128
141
  return super.keys();
129
142
  }
130
143
 
@@ -134,12 +147,12 @@ export class RippleMap extends Map {
134
147
  }
135
148
  }
136
149
 
137
- get $size() {
150
+ get size() {
138
151
  return get(this.#tracked_size);
139
152
  }
140
153
 
141
154
  toJSON() {
142
- this.$size;
155
+ this.size;
143
156
  this.#read_all();
144
157
 
145
158
  return [...this];