ripple 0.2.140 → 0.2.141

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.
@@ -15,183 +15,183 @@ let init = false;
15
15
  * @returns {TrackedSet<T>}
16
16
  */
17
17
  export class TrackedSet extends Set {
18
- /** @type {Tracked} */
19
- #tracked_size;
20
- /** @type {Map<T, Tracked>} */
21
- #tracked_items = new Map();
22
- /** @type {Block} */
23
- #block;
24
-
25
- /**
26
- * @param {Iterable<T>} [iterable]
27
- */
28
- constructor(iterable) {
29
- super();
30
-
31
- var block = this.#block = safe_scope();
32
-
33
- if (iterable) {
34
- for (var item of iterable) {
35
- super.add(item);
36
- this.#tracked_items.set(item, tracked(0, block));
37
- }
38
- }
39
-
40
- this.#tracked_size = tracked(super.size, block);
41
-
42
- if (!init) {
43
- init = true;
44
- this.#init();
45
- }
46
- }
47
-
48
- /**
49
- * @returns {void}
50
- */
51
- #init() {
52
- var proto = TrackedSet.prototype;
53
- var set_proto = Set.prototype;
54
-
55
- for (const method of introspect_methods) {
56
- if (!(method in set_proto)) {
57
- continue;
58
- }
18
+ /** @type {Tracked} */
19
+ #tracked_size;
20
+ /** @type {Map<T, Tracked>} */
21
+ #tracked_items = new Map();
22
+ /** @type {Block} */
23
+ #block;
24
+
25
+ /**
26
+ * @param {Iterable<T>} [iterable]
27
+ */
28
+ constructor(iterable) {
29
+ super();
30
+
31
+ var block = this.#block = safe_scope();
32
+
33
+ if (iterable) {
34
+ for (var item of iterable) {
35
+ super.add(item);
36
+ this.#tracked_items.set(item, tracked(0, block));
37
+ }
38
+ }
39
+
40
+ this.#tracked_size = tracked(super.size, block);
41
+
42
+ if (!init) {
43
+ init = true;
44
+ this.#init();
45
+ }
46
+ }
47
+
48
+ /**
49
+ * @returns {void}
50
+ */
51
+ #init() {
52
+ var proto = TrackedSet.prototype;
53
+ var set_proto = Set.prototype;
54
+
55
+ for (const method of introspect_methods) {
56
+ if (!(method in set_proto)) {
57
+ continue;
58
+ }
59
59
 
60
60
  /** @type {any} */ (proto)[method] = function (/** @type {...any} */ ...v) {
61
- this.size;
61
+ this.size;
62
62
 
63
- return /** @type {any} */ (set_proto)[method].apply(this, v);
64
- };
65
- }
63
+ return /** @type {any} */ (set_proto)[method].apply(this, v);
64
+ };
65
+ }
66
66
 
67
- for (const method of compare_other_methods) {
68
- if (!(method in set_proto)) {
69
- continue;
70
- }
67
+ for (const method of compare_other_methods) {
68
+ if (!(method in set_proto)) {
69
+ continue;
70
+ }
71
71
 
72
72
  /** @type {any} */ (proto)[method] = function (/** @type {any} */ other, /** @type {...any} */ ...v) {
73
- this.size;
73
+ this.size;
74
74
 
75
- if (other instanceof TrackedSet) {
76
- other.size;
77
- }
75
+ if (other instanceof TrackedSet) {
76
+ other.size;
77
+ }
78
78
 
79
- return /** @type {any} */ (set_proto)[method].apply(this, [other, ...v]);
80
- };
81
- }
79
+ return /** @type {any} */ (set_proto)[method].apply(this, [other, ...v]);
80
+ };
81
+ }
82
82
 
83
- for (const method of new_other_methods) {
84
- if (!(method in set_proto)) {
85
- continue;
86
- }
83
+ for (const method of new_other_methods) {
84
+ if (!(method in set_proto)) {
85
+ continue;
86
+ }
87
87
 
88
88
  /** @type {any} */ (proto)[method] = function (/** @type {any} */ other, /** @type {...any} */ ...v) {
89
- this.size;
90
-
91
- if (other instanceof TrackedSet) {
92
- other.size;
93
- }
94
-
95
- return new TrackedSet(/** @type {any} */ (set_proto)[method].apply(this, [other, ...v]));
96
- };
97
- }
98
- }
99
-
100
- /**
101
- * @param {T} value
102
- * @returns {this}
103
- */
104
- add(value) {
105
- var block = this.#block;
106
-
107
- if (!super.has(value)) {
108
- super.add(value);
109
- this.#tracked_items.set(value, tracked(0, block));
110
- set(this.#tracked_size, super.size, block);
111
- }
112
-
113
- return this;
114
- }
115
-
116
- /**
117
- * @param {T} value
118
- * @returns {boolean}
119
- */
120
- delete(value) {
121
- var block = this.#block;
122
-
123
- if (!super.delete(value)) {
124
- return false;
125
- }
126
-
127
- var t = this.#tracked_items.get(value);
128
-
129
- if (t) {
130
- increment(t, block);
131
- }
132
- this.#tracked_items.delete(value);
133
- set(this.#tracked_size, super.size, block);
134
-
135
- return true;
136
- }
137
-
138
- /**
139
- * @param {T} value
140
- * @return {boolean}
141
- */
142
- has(value) {
143
-
144
- var has = super.has(value);
145
- var tracked_items = this.#tracked_items;
146
- var t = tracked_items.get(value);
147
-
148
- if (t === undefined) {
149
- // if no tracked it also means super didn't have it
150
- // It's not possible to have a disconnect, we track each value
151
- // If the value doesn't exist, track the size in case it's added later
152
- // but don't create tracked entries willy-nilly to track all possible values
153
- this.size;
154
- } else {
155
- get(t);
156
- }
157
-
158
- return has;
159
- }
160
-
161
- /**
162
- * @returns {void}
163
- */
164
- clear() {
165
- var block = this.#block;
166
-
167
- if (super.size === 0) {
168
- return;
169
- }
170
-
171
- for (var [_, t] of this.#tracked_items) {
172
- increment(t, block);
173
- }
174
-
175
- super.clear();
176
- this.#tracked_items.clear();
177
- set(this.#tracked_size, 0, block);
178
- }
179
-
180
- /**
181
- * @returns {number}
182
- */
183
- get size() {
184
- return get(this.#tracked_size);
185
- }
186
-
187
- /**
188
- * @returns {T[]}
189
- */
190
- toJSON() {
191
- this.size;
192
-
193
- return [...this];
194
- }
89
+ this.size;
90
+
91
+ if (other instanceof TrackedSet) {
92
+ other.size;
93
+ }
94
+
95
+ return new TrackedSet(/** @type {any} */(set_proto)[method].apply(this, [other, ...v]));
96
+ };
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @param {T} value
102
+ * @returns {this}
103
+ */
104
+ add(value) {
105
+ var block = this.#block;
106
+
107
+ if (!super.has(value)) {
108
+ super.add(value);
109
+ this.#tracked_items.set(value, tracked(0, block));
110
+ set(this.#tracked_size, super.size);
111
+ }
112
+
113
+ return this;
114
+ }
115
+
116
+ /**
117
+ * @param {T} value
118
+ * @returns {boolean}
119
+ */
120
+ delete(value) {
121
+ var block = this.#block;
122
+
123
+ if (!super.delete(value)) {
124
+ return false;
125
+ }
126
+
127
+ var t = this.#tracked_items.get(value);
128
+
129
+ if (t) {
130
+ increment(t);
131
+ }
132
+ this.#tracked_items.delete(value);
133
+ set(this.#tracked_size, super.size);
134
+
135
+ return true;
136
+ }
137
+
138
+ /**
139
+ * @param {T} value
140
+ * @return {boolean}
141
+ */
142
+ has(value) {
143
+
144
+ var has = super.has(value);
145
+ var tracked_items = this.#tracked_items;
146
+ var t = tracked_items.get(value);
147
+
148
+ if (t === undefined) {
149
+ // if no tracked it also means super didn't have it
150
+ // It's not possible to have a disconnect, we track each value
151
+ // If the value doesn't exist, track the size in case it's added later
152
+ // but don't create tracked entries willy-nilly to track all possible values
153
+ this.size;
154
+ } else {
155
+ get(t);
156
+ }
157
+
158
+ return has;
159
+ }
160
+
161
+ /**
162
+ * @returns {void}
163
+ */
164
+ clear() {
165
+ var block = this.#block;
166
+
167
+ if (super.size === 0) {
168
+ return;
169
+ }
170
+
171
+ for (var [_, t] of this.#tracked_items) {
172
+ increment(t);
173
+ }
174
+
175
+ super.clear();
176
+ this.#tracked_items.clear();
177
+ set(this.#tracked_size, 0);
178
+ }
179
+
180
+ /**
181
+ * @returns {number}
182
+ */
183
+ get size() {
184
+ return get(this.#tracked_size);
185
+ }
186
+
187
+ /**
188
+ * @returns {T[]}
189
+ */
190
+ toJSON() {
191
+ this.size;
192
+
193
+ return [...this];
194
+ }
195
195
  }
196
196
 
197
197
  /**
@@ -201,5 +201,5 @@ export class TrackedSet extends Set {
201
201
  * @returns {TrackedSet<V>}
202
202
  */
203
203
  export function tracked_set(block, ...args) {
204
- return with_scope(block, () => new TrackedSet(...args));
205
- }
204
+ return with_scope(block, () => new TrackedSet(...args));
205
+ }
@@ -37,7 +37,7 @@ export class TrackedURLSearchParams extends URLSearchParams {
37
37
  super.append(key, value);
38
38
  }
39
39
 
40
- increment(this.#version, this.#block);
40
+ increment(this.#version);
41
41
  this.#updating = false;
42
42
  }
43
43
 
@@ -49,7 +49,7 @@ export class TrackedURLSearchParams extends URLSearchParams {
49
49
  append(name, value) {
50
50
  super.append(name, value);
51
51
  this.#update_url();
52
- increment(this.#version, this.#block);
52
+ increment(this.#version);
53
53
  }
54
54
 
55
55
  /**
@@ -62,7 +62,7 @@ export class TrackedURLSearchParams extends URLSearchParams {
62
62
  super.delete(name, value);
63
63
  if (has_value) {
64
64
  this.#update_url();
65
- increment(this.#version, this.#block);
65
+ increment(this.#version);
66
66
  }
67
67
  }
68
68
 
@@ -111,14 +111,14 @@ export class TrackedURLSearchParams extends URLSearchParams {
111
111
  // if you set `foo` to 1, then foo=3 gets deleted whilst `has("foo", "1")` returns true
112
112
  if (previous !== super.getAll(name).join('')) {
113
113
  this.#update_url();
114
- increment(this.#version, this.#block);
114
+ increment(this.#version);
115
115
  }
116
116
  }
117
117
 
118
118
  sort() {
119
119
  super.sort();
120
120
  this.#update_url();
121
- increment(this.#version, this.#block);
121
+ increment(this.#version);
122
122
  }
123
123
 
124
124
  toString() {
@@ -39,7 +39,7 @@ export class TrackedURL extends URL {
39
39
 
40
40
  set hash(value) {
41
41
  super.hash = value;
42
- set(this.#hash, super.hash, this.#block);
42
+ set(this.#hash, super.hash);
43
43
  }
44
44
 
45
45
  get host() {
@@ -50,8 +50,8 @@ export class TrackedURL extends URL {
50
50
 
51
51
  set host(value) {
52
52
  super.host = value;
53
- set(this.#hostname, super.hostname, this.#block);
54
- set(this.#port, super.port, this.#block);
53
+ set(this.#hostname, super.hostname);
54
+ set(this.#port, super.port);
55
55
  }
56
56
 
57
57
  get hostname() {
@@ -60,7 +60,7 @@ export class TrackedURL extends URL {
60
60
 
61
61
  set hostname(value) {
62
62
  super.hostname = value;
63
- set(this.#hostname, super.hostname, this.#block);
63
+ set(this.#hostname, super.hostname);
64
64
  }
65
65
 
66
66
  get href() {
@@ -77,14 +77,14 @@ export class TrackedURL extends URL {
77
77
 
78
78
  set href(value) {
79
79
  super.href = value;
80
- set(this.#protocol, super.protocol, this.#block);
81
- set(this.#username, super.username, this.#block);
82
- set(this.#password, super.password, this.#block);
83
- set(this.#hostname, super.hostname, this.#block);
84
- set(this.#port, super.port, this.#block);
85
- set(this.#pathname, super.pathname, this.#block);
86
- set(this.#hash, super.hash, this.#block);
87
- set(this.#search, super.search, this.#block);
80
+ set(this.#protocol, super.protocol);
81
+ set(this.#username, super.username);
82
+ set(this.#password, super.password);
83
+ set(this.#hostname, super.hostname);
84
+ set(this.#port, super.port);
85
+ set(this.#pathname, super.pathname);
86
+ set(this.#hash, super.hash);
87
+ set(this.#search, super.search);
88
88
  this.#searchParams[REPLACE](super.searchParams);
89
89
  }
90
90
 
@@ -94,7 +94,7 @@ export class TrackedURL extends URL {
94
94
 
95
95
  set password(value) {
96
96
  super.password = value;
97
- set(this.#password, super.password, this.#block);
97
+ set(this.#password, super.password);
98
98
  }
99
99
 
100
100
  get pathname() {
@@ -103,7 +103,7 @@ export class TrackedURL extends URL {
103
103
 
104
104
  set pathname(value) {
105
105
  super.pathname = value;
106
- set(this.#pathname, super.pathname, this.#block);
106
+ set(this.#pathname, super.pathname);
107
107
  }
108
108
 
109
109
  get port() {
@@ -112,7 +112,7 @@ export class TrackedURL extends URL {
112
112
 
113
113
  set port(value) {
114
114
  super.port = value;
115
- set(this.#port, super.port, this.#block);
115
+ set(this.#port, super.port);
116
116
  }
117
117
 
118
118
  get protocol() {
@@ -121,7 +121,7 @@ export class TrackedURL extends URL {
121
121
 
122
122
  set protocol(value) {
123
123
  super.protocol = value;
124
- set(this.#protocol, super.protocol, this.#block);
124
+ set(this.#protocol, super.protocol);
125
125
  }
126
126
 
127
127
  get search() {
@@ -130,7 +130,7 @@ export class TrackedURL extends URL {
130
130
 
131
131
  set search(value) {
132
132
  super.search = value;
133
- set(this.#search, value, this.#block);
133
+ set(this.#search, value);
134
134
  this.#searchParams[REPLACE](super.searchParams);
135
135
  }
136
136
 
@@ -140,7 +140,7 @@ export class TrackedURL extends URL {
140
140
 
141
141
  set username(value) {
142
142
  super.username = value;
143
- set(this.#username, super.username, this.#block);
143
+ set(this.#username, super.username);
144
144
  }
145
145
 
146
146
  get origin() {
@@ -1,4 +1,4 @@
1
- import { track, effect, flushSync } from 'ripple';
1
+ import { track, trackSplit, effect, flushSync, type Props } from 'ripple';
2
2
 
3
3
  describe('composite > props', () => {
4
4
  it('correctly handles default prop values', () => {
@@ -102,5 +102,47 @@ describe('composite > props', () => {
102
102
  flushSync();
103
103
 
104
104
  expect(logs).toEqual([0, 1]);
105
- })
105
+ });
106
+
107
+ it('correctly retains prop accessors and reactivity when using rest props', () => {
108
+ component Button(props: Props) {
109
+ const [children, rest] = trackSplit(props, ['children']);
110
+ <button {...@rest}>
111
+ <@children />
112
+ </button>
113
+ <style>
114
+ .on {
115
+ color: blue;
116
+ }
117
+ .off {
118
+ color: red;
119
+ }
120
+ </style>
121
+ }
122
+
123
+ component Toggle(props) {
124
+ const [pressed, rest] = trackSplit(props, ['pressed']);
125
+ const onClick = () => @pressed = !@pressed;
126
+ <Button {...@rest} class={@pressed ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
127
+ <Button class={@pressed ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
128
+ }
129
+
130
+ component App() {
131
+ const pressed = track(true);
132
+ <Toggle {pressed} />
133
+ }
134
+
135
+ render(App);
136
+ const button1 = container.querySelectorAll('button')[0];;
137
+ const button2 = container.querySelectorAll('button')[1];
138
+
139
+ expect(button1.className).toContain('on');
140
+ expect(button2.className).toContain('on');
141
+
142
+ button1.click();
143
+ flushSync();
144
+
145
+ expect(button1.className).toContain('off');
146
+ expect(button2.className).toContain('off');
147
+ });
106
148
  });
package/types/index.d.ts CHANGED
@@ -76,7 +76,7 @@ declare global {
76
76
  scope(): any;
77
77
  get_tracked(node: any): any;
78
78
  get_derived(node: any): any;
79
- set(node: any, value: any, block?: any): any;
79
+ set(node: any, value: any): any;
80
80
  // Add other runtime functions as needed for TypeScript analysis
81
81
  };
82
82
  }