ripple 0.3.7 → 0.3.9
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/CHANGELOG.md +14 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +48 -349
- package/src/compiler/phases/2-analyze/index.js +343 -52
- package/src/compiler/phases/3-transform/client/index.js +28 -160
- package/src/compiler/phases/3-transform/segments.js +0 -7
- package/src/compiler/phases/3-transform/server/index.js +31 -154
- package/src/compiler/types/acorn.d.ts +1 -1
- package/src/compiler/types/estree.d.ts +1 -1
- package/src/compiler/types/import.d.ts +0 -2
- package/src/compiler/types/index.d.ts +5 -17
- package/src/compiler/types/parse.d.ts +1 -17
- package/src/compiler/utils.js +53 -20
- package/src/runtime/index-client.js +2 -13
- package/src/runtime/index-server.js +2 -2
- package/src/runtime/internal/client/bindings.js +3 -1
- package/src/runtime/internal/client/composite.js +3 -2
- package/src/runtime/internal/client/events.js +1 -1
- package/src/runtime/internal/client/head.js +3 -4
- package/src/runtime/internal/client/index.js +0 -1
- package/src/runtime/internal/client/runtime.js +0 -52
- package/src/runtime/internal/server/index.js +31 -55
- package/tests/client/array/array.copy-within.test.ripple +12 -12
- package/tests/client/array/array.derived.test.ripple +46 -46
- package/tests/client/array/array.iteration.test.ripple +10 -10
- package/tests/client/array/array.mutations.test.ripple +20 -20
- package/tests/client/array/array.to-methods.test.ripple +6 -6
- package/tests/client/async-suspend.test.ripple +5 -5
- package/tests/client/basic/basic.attributes.test.ripple +81 -81
- package/tests/client/basic/basic.collections.test.ripple +9 -9
- package/tests/client/basic/basic.components.test.ripple +28 -28
- package/tests/client/basic/basic.errors.test.ripple +46 -18
- package/tests/client/basic/basic.events.test.ripple +37 -37
- package/tests/client/basic/basic.get-set.test.ripple +6 -6
- package/tests/client/basic/basic.reactivity.test.ripple +58 -203
- package/tests/client/basic/basic.rendering.test.ripple +19 -19
- package/tests/client/basic/basic.utilities.test.ripple +3 -3
- package/tests/client/boundaries.test.ripple +12 -12
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
- package/tests/client/compiler/compiler.basic.test.ripple +46 -27
- package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
- package/tests/client/composite/composite.props.test.ripple +14 -16
- package/tests/client/composite/composite.reactivity.test.ripple +69 -70
- package/tests/client/composite/composite.render.test.ripple +3 -3
- package/tests/client/computed-properties.test.ripple +4 -4
- package/tests/client/date.test.ripple +42 -42
- package/tests/client/dynamic-elements.test.ripple +44 -45
- package/tests/client/events.test.ripple +70 -70
- package/tests/client/for.test.ripple +25 -25
- package/tests/client/head.test.ripple +19 -19
- package/tests/client/html.test.ripple +3 -3
- package/tests/client/input-value.test.ripple +84 -84
- package/tests/client/lazy-destructuring.test.ripple +138 -26
- package/tests/client/map.test.ripple +16 -16
- package/tests/client/media-query.test.ripple +7 -7
- package/tests/client/portal.test.ripple +11 -11
- package/tests/client/ref.test.ripple +4 -4
- package/tests/client/return.test.ripple +52 -52
- package/tests/client/set.test.ripple +6 -6
- package/tests/client/svg.test.ripple +5 -5
- package/tests/client/switch.test.ripple +44 -44
- package/tests/client/try.test.ripple +5 -5
- package/tests/client/url/url.derived.test.ripple +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
- package/tests/hydration/compiled/client/events.js +25 -25
- package/tests/hydration/compiled/client/for.js +70 -66
- package/tests/hydration/compiled/client/head.js +25 -25
- package/tests/hydration/compiled/client/hmr.js +2 -2
- package/tests/hydration/compiled/client/html.js +3 -3
- package/tests/hydration/compiled/client/if-children.js +24 -24
- package/tests/hydration/compiled/client/if.js +18 -18
- package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
- package/tests/hydration/compiled/client/portal.js +3 -3
- package/tests/hydration/compiled/client/reactivity.js +16 -16
- package/tests/hydration/compiled/client/return.js +40 -40
- package/tests/hydration/compiled/client/switch.js +12 -12
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +41 -41
- package/tests/hydration/compiled/server/head.js +26 -26
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +2 -2
- package/tests/hydration/compiled/server/if-children.js +16 -16
- package/tests/hydration/compiled/server/if.js +11 -11
- package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
- package/tests/hydration/compiled/server/portal.js +2 -2
- package/tests/hydration/compiled/server/reactivity.js +16 -16
- package/tests/hydration/compiled/server/return.js +25 -25
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/components/events.ripple +25 -25
- package/tests/hydration/components/for.ripple +66 -66
- package/tests/hydration/components/head.ripple +16 -16
- package/tests/hydration/components/hmr.ripple +2 -2
- package/tests/hydration/components/html.ripple +3 -3
- package/tests/hydration/components/if-children.ripple +24 -24
- package/tests/hydration/components/if.ripple +18 -18
- package/tests/hydration/components/mixed-control-flow.ripple +9 -9
- package/tests/hydration/components/portal.ripple +3 -3
- package/tests/hydration/components/reactivity.ripple +16 -16
- package/tests/hydration/components/return.ripple +40 -40
- package/tests/hydration/components/switch.ripple +20 -20
- package/tests/server/await.test.ripple +3 -3
- package/tests/server/basic.attributes.test.ripple +34 -34
- package/tests/server/basic.components.test.ripple +10 -10
- package/tests/server/basic.test.ripple +38 -40
- package/tests/server/compiler.test.ripple +22 -0
- package/tests/server/composite.props.test.ripple +12 -14
- package/tests/server/dynamic-elements.test.ripple +15 -15
- package/tests/server/head.test.ripple +11 -11
- package/tests/server/lazy-destructuring.test.ripple +92 -13
- package/tsconfig.typecheck.json +4 -0
- package/types/index.d.ts +0 -19
- package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +0 -34
- package/tests/client/tracked-expression.test.ripple +0 -26
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsWithChildren, Tracked } from 'ripple';
|
|
2
|
-
import { effect, flushSync, track,
|
|
2
|
+
import { effect, flushSync, track, untrack } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('basic client > reactivity', () => {
|
|
5
5
|
it('renders multiple reactive lexical blocks', () => {
|
|
@@ -9,7 +9,7 @@ describe('basic client > reactivity', () => {
|
|
|
9
9
|
count: track(0),
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
<span>{obj
|
|
12
|
+
<span>{obj.count.value}</span>
|
|
13
13
|
</div>
|
|
14
14
|
<div>
|
|
15
15
|
let b = {
|
|
@@ -18,15 +18,15 @@ describe('basic client > reactivity', () => {
|
|
|
18
18
|
|
|
19
19
|
<button
|
|
20
20
|
onClick={() => {
|
|
21
|
-
b
|
|
21
|
+
b.count.value--;
|
|
22
22
|
}}
|
|
23
23
|
>
|
|
24
24
|
{'-'}
|
|
25
25
|
</button>
|
|
26
|
-
<span class="count">{b
|
|
26
|
+
<span class="count">{b.count.value}</span>
|
|
27
27
|
<button
|
|
28
28
|
onClick={() => {
|
|
29
|
-
b
|
|
29
|
+
b.count.value++;
|
|
30
30
|
}}
|
|
31
31
|
>
|
|
32
32
|
{'+'}
|
|
@@ -57,7 +57,7 @@ describe('basic client > reactivity', () => {
|
|
|
57
57
|
count: track(0),
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
<span>{obj
|
|
60
|
+
<span>{obj[count].value}</span>
|
|
61
61
|
</div>
|
|
62
62
|
<div>
|
|
63
63
|
let b = {
|
|
@@ -66,15 +66,15 @@ describe('basic client > reactivity', () => {
|
|
|
66
66
|
|
|
67
67
|
<button
|
|
68
68
|
onClick={() => {
|
|
69
|
-
b
|
|
69
|
+
b[count].value--;
|
|
70
70
|
}}
|
|
71
71
|
>
|
|
72
72
|
{'-'}
|
|
73
73
|
</button>
|
|
74
|
-
<span class="count">{b
|
|
74
|
+
<span class="count">{b[count].value}</span>
|
|
75
75
|
<button
|
|
76
76
|
onClick={() => {
|
|
77
|
-
b
|
|
77
|
+
b[count].value++;
|
|
78
78
|
}}
|
|
79
79
|
>
|
|
80
80
|
{'+'}
|
|
@@ -98,14 +98,14 @@ describe('basic client > reactivity', () => {
|
|
|
98
98
|
|
|
99
99
|
it('renders with computed reactive state', () => {
|
|
100
100
|
component Basic() {
|
|
101
|
-
let count = track(5);
|
|
101
|
+
let &[count] = track(5);
|
|
102
102
|
|
|
103
|
-
<div class="count">{
|
|
104
|
-
<div class="doubled">{
|
|
105
|
-
<div class="is-even">{
|
|
103
|
+
<div class="count">{count}</div>
|
|
104
|
+
<div class="doubled">{count * 2}</div>
|
|
105
|
+
<div class="is-even">{count % 2 === 0 ? 'Even' : 'Odd'}</div>
|
|
106
106
|
<button
|
|
107
107
|
onClick={() => {
|
|
108
|
-
|
|
108
|
+
count++;
|
|
109
109
|
}}
|
|
110
110
|
>
|
|
111
111
|
{'Increment'}
|
|
@@ -139,43 +139,43 @@ describe('basic client > reactivity', () => {
|
|
|
139
139
|
let second = track(0);
|
|
140
140
|
const arr = [first, second];
|
|
141
141
|
|
|
142
|
-
const total = track(() => arr.reduce((a, b) => a +
|
|
142
|
+
const total = track(() => arr.reduce((a, b) => a + b.value, 0));
|
|
143
143
|
|
|
144
144
|
<button
|
|
145
145
|
onClick={() => {
|
|
146
|
-
|
|
146
|
+
first.value++;
|
|
147
147
|
}}
|
|
148
148
|
>
|
|
149
|
-
{'first:' +
|
|
149
|
+
{'first:' + first.value}
|
|
150
150
|
</button>
|
|
151
151
|
<button
|
|
152
152
|
onClick={() => {
|
|
153
|
-
|
|
153
|
+
second.value++;
|
|
154
154
|
}}
|
|
155
155
|
>
|
|
156
|
-
{'second: ' +
|
|
156
|
+
{'second: ' + second.value}
|
|
157
157
|
</button>
|
|
158
158
|
|
|
159
159
|
effect(() => {
|
|
160
160
|
let _arr: number[] = [];
|
|
161
161
|
|
|
162
162
|
arr.forEach((item) => {
|
|
163
|
-
_arr.push(
|
|
163
|
+
_arr.push(item.value);
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
logs.push(_arr.join(', '));
|
|
167
167
|
});
|
|
168
168
|
|
|
169
169
|
effect(() => {
|
|
170
|
-
if (arr.map((a) =>
|
|
170
|
+
if (arr.map((a) => a.value).includes(1)) {
|
|
171
171
|
logs.push('arr includes 1');
|
|
172
172
|
}
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
-
<div>{'Sum: ' +
|
|
176
|
-
<div>{'Comma Separated: ' + arr.map((a) =>
|
|
177
|
-
<div>{'Number to string: ' + arr.map((a) => String(
|
|
178
|
-
<div>{'Even numbers: ' + arr.map((a) =>
|
|
175
|
+
<div>{'Sum: ' + total.value}</div>
|
|
176
|
+
<div>{'Comma Separated: ' + arr.map((a) => a.value).join(', ')}</div>
|
|
177
|
+
<div>{'Number to string: ' + arr.map((a) => String(a.value))}</div>
|
|
178
|
+
<div>{'Even numbers: ' + arr.map((a) => a.value).filter((a) => a % 2 === 0)}</div>
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
render(App);
|
|
@@ -211,12 +211,12 @@ describe('basic client > reactivity', () => {
|
|
|
211
211
|
|
|
212
212
|
it('uses track get and set where both mutate value', () => {
|
|
213
213
|
component App() {
|
|
214
|
-
let count = track(0, (v) => v + 1, (v) => v * 2);
|
|
214
|
+
let &[count] = track(0, (v) => v + 1, (v) => v * 2);
|
|
215
215
|
|
|
216
|
-
<div class="count">{
|
|
216
|
+
<div class="count">{count}</div>
|
|
217
217
|
<button
|
|
218
218
|
onClick={() => {
|
|
219
|
-
|
|
219
|
+
count++;
|
|
220
220
|
}}
|
|
221
221
|
>
|
|
222
222
|
{'Increment'}
|
|
@@ -237,12 +237,12 @@ describe('basic client > reactivity', () => {
|
|
|
237
237
|
|
|
238
238
|
it('uses track get and set where set only mutates value', () => {
|
|
239
239
|
component App() {
|
|
240
|
-
let count = track(1, (v) => v, (v) => v * 2);
|
|
240
|
+
let &[count] = track(1, (v) => v, (v) => v * 2);
|
|
241
241
|
|
|
242
|
-
<div class="count">{
|
|
242
|
+
<div class="count">{count}</div>
|
|
243
243
|
<button
|
|
244
244
|
onClick={() => {
|
|
245
|
-
|
|
245
|
+
count++;
|
|
246
246
|
}}
|
|
247
247
|
>
|
|
248
248
|
{'Increment'}
|
|
@@ -263,12 +263,12 @@ describe('basic client > reactivity', () => {
|
|
|
263
263
|
|
|
264
264
|
it('uses track get and set where get only mutates value', () => {
|
|
265
265
|
component App() {
|
|
266
|
-
let count = track(0, (v) => v + 1, (v) => v);
|
|
266
|
+
let &[count] = track(0, (v) => v + 1, (v) => v);
|
|
267
267
|
|
|
268
|
-
<div class="count">{
|
|
268
|
+
<div class="count">{count}</div>
|
|
269
269
|
<button
|
|
270
270
|
onClick={() => {
|
|
271
|
-
|
|
271
|
+
count++;
|
|
272
272
|
}}
|
|
273
273
|
>
|
|
274
274
|
{'Increment'}
|
|
@@ -291,14 +291,14 @@ describe('basic client > reactivity', () => {
|
|
|
291
291
|
let logs: number[] = [];
|
|
292
292
|
|
|
293
293
|
component App() {
|
|
294
|
-
let count = track(0, (v) => v, (next, prev) => {
|
|
294
|
+
let &[count] = track(0, (v) => v, (next, prev) => {
|
|
295
295
|
logs.push(prev, next);
|
|
296
296
|
return next;
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
<button
|
|
300
300
|
onClick={() => {
|
|
301
|
-
|
|
301
|
+
count++;
|
|
302
302
|
}}
|
|
303
303
|
>
|
|
304
304
|
{'Increment'}
|
|
@@ -316,14 +316,14 @@ describe('basic client > reactivity', () => {
|
|
|
316
316
|
|
|
317
317
|
it('doesn\'t error on mutating a tracked variable in track() setter', () => {
|
|
318
318
|
component Basic() {
|
|
319
|
-
let count = track(0);
|
|
319
|
+
let &[count] = track(0);
|
|
320
320
|
|
|
321
|
-
const doubled = track(0, undefined, (value) => {
|
|
322
|
-
|
|
321
|
+
const &[doubled] = track(0, undefined, (value) => {
|
|
322
|
+
count += value;
|
|
323
323
|
return value;
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
-
<p>{
|
|
326
|
+
<p>{doubled}</p>
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
render(Basic);
|
|
@@ -335,10 +335,10 @@ describe('basic client > reactivity', () => {
|
|
|
335
335
|
let state: { count?: number } = {};
|
|
336
336
|
|
|
337
337
|
component Basic() {
|
|
338
|
-
let count = track(0);
|
|
338
|
+
let &[count] = track(0);
|
|
339
339
|
|
|
340
340
|
effect(() => {
|
|
341
|
-
state.count =
|
|
341
|
+
state.count = count;
|
|
342
342
|
});
|
|
343
343
|
}
|
|
344
344
|
|
|
@@ -359,16 +359,16 @@ describe('basic client > reactivity', () => {
|
|
|
359
359
|
} = {};
|
|
360
360
|
|
|
361
361
|
component Basic() {
|
|
362
|
-
let count = track(5);
|
|
362
|
+
let &[count] = track(5);
|
|
363
363
|
|
|
364
364
|
effect(() => {
|
|
365
365
|
untrack(() => {
|
|
366
|
-
state.initialValue =
|
|
367
|
-
state.preIncrement =
|
|
368
|
-
state.postIncrement =
|
|
369
|
-
state.preDecrement =
|
|
370
|
-
state.postDecrement =
|
|
371
|
-
state.finalValue =
|
|
366
|
+
state.initialValue = count;
|
|
367
|
+
state.preIncrement = ++count;
|
|
368
|
+
state.postIncrement = count++;
|
|
369
|
+
state.preDecrement = --count;
|
|
370
|
+
state.postDecrement = count--;
|
|
371
|
+
state.finalValue = count;
|
|
372
372
|
});
|
|
373
373
|
});
|
|
374
374
|
}
|
|
@@ -384,162 +384,17 @@ describe('basic client > reactivity', () => {
|
|
|
384
384
|
expect(state.finalValue).toBe(5);
|
|
385
385
|
});
|
|
386
386
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
try {
|
|
393
|
-
const [a, b, rest] = trackSplit(null, ['a', 'b']);
|
|
394
|
-
} catch (e) {
|
|
395
|
-
@message = (e as Error).message;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
<pre>{@message}</pre>
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
render(App);
|
|
402
|
-
|
|
403
|
-
const pre = container.querySelectorAll('pre')[0];
|
|
404
|
-
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
it('errors on invalid value as array for track with trackSplit', () => {
|
|
408
|
-
component App() {
|
|
409
|
-
let message = track('');
|
|
410
|
-
|
|
411
|
-
try {
|
|
412
|
-
const [a, b, rest] = trackSplit([1, 2, 3], ['a', 'b']);
|
|
413
|
-
} catch (e) {
|
|
414
|
-
@message = (e as Error).message;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
<pre>{@message}</pre>
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
render(App);
|
|
421
|
-
|
|
422
|
-
const pre = container.querySelectorAll('pre')[0];
|
|
423
|
-
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it('errors on invalid value as tracked for track with trackSplit', () => {
|
|
427
|
-
component App() {
|
|
428
|
-
const t = track({ a: 1, b: 2, c: 3 });
|
|
429
|
-
let message = track('');
|
|
430
|
-
|
|
431
|
-
try {
|
|
432
|
-
const [a, b, rest] = trackSplit(t, ['a', 'b']);
|
|
433
|
-
} catch (e) {
|
|
434
|
-
@message = (e as Error).message;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
<pre>{@message}</pre>
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
render(App);
|
|
441
|
-
|
|
442
|
-
const pre = container.querySelectorAll('pre')[0];
|
|
443
|
-
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
it('returns undefined for non-existent props in track with trackSplit', () => {
|
|
447
|
-
component App() {
|
|
448
|
-
const [a, b, rest] = trackSplit({ a: 1, c: 1 }, ['a', 'b']);
|
|
449
|
-
|
|
450
|
-
<pre>{@a}</pre>
|
|
451
|
-
<pre>{String(@b)}</pre>
|
|
452
|
-
<pre>{@rest.c}</pre>
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
render(App);
|
|
456
|
-
|
|
457
|
-
const preA = container.querySelectorAll('pre')[0];
|
|
458
|
-
const preB = container.querySelectorAll('pre')[1];
|
|
459
|
-
const preC = container.querySelectorAll('pre')[2];
|
|
460
|
-
|
|
461
|
-
expect(preA.textContent).toBe('1');
|
|
462
|
-
expect(preB.textContent).toBe('undefined');
|
|
463
|
-
expect(preC.textContent).toBe('1');
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
it('returns the same tracked object if plain track is called with a tracked object', () => {
|
|
467
|
-
component App() {
|
|
468
|
-
const t = track({ a: 1, b: 2, c: 3 });
|
|
469
|
-
const doublet = track(t);
|
|
470
|
-
|
|
471
|
-
<pre>{t === doublet}</pre>
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
render(App);
|
|
475
|
-
|
|
476
|
-
const pre = container.querySelectorAll('pre')[0];
|
|
477
|
-
expect(pre.textContent).toBe('true');
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it('can retain reactivity for destructure rest via track trackSplit', () => {
|
|
481
|
-
let logs: string[] = [];
|
|
482
|
-
|
|
483
|
-
component App() {
|
|
484
|
-
let count = track(0);
|
|
485
|
-
let name = track('Click Me');
|
|
486
|
-
|
|
487
|
-
function buttonRef(el: HTMLButtonElement) {
|
|
488
|
-
logs.push('ref called');
|
|
489
|
-
return () => {
|
|
490
|
-
logs.push('cleanup ref');
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
<Child
|
|
495
|
-
class="my-button"
|
|
496
|
-
onClick={() => @name === 'Click Me' ? @name = 'Clicked' : @name = 'Click Me'}
|
|
497
|
-
{count}
|
|
498
|
-
{ref buttonRef}
|
|
499
|
-
>
|
|
500
|
-
{@name}
|
|
501
|
-
</Child>
|
|
502
|
-
|
|
503
|
-
<button onClick={() => @count++}>{'Increment Count'}</button>
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
component Child(props: PropsWithChildren<{
|
|
507
|
-
count: Tracked<number>;
|
|
508
|
-
class: string;
|
|
509
|
-
onClick: () => void;
|
|
510
|
-
}>) {
|
|
511
|
-
const [children, count, rest] = trackSplit(props, ['children', 'count']);
|
|
512
|
-
|
|
513
|
-
if (@count < 2) {
|
|
514
|
-
<button {...@rest}>
|
|
515
|
-
<@children />
|
|
516
|
-
</button>
|
|
517
|
-
}
|
|
518
|
-
<pre>{@count}</pre>
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
render(App);
|
|
522
|
-
flushSync();
|
|
523
|
-
|
|
524
|
-
const buttonClickMe = container.querySelectorAll('button')[0];
|
|
525
|
-
const buttonIncrement = container.querySelectorAll('button')[1];
|
|
526
|
-
const countPre = container.querySelector('pre');
|
|
527
|
-
|
|
528
|
-
expect(buttonClickMe.textContent).toBe('Click Me');
|
|
529
|
-
expect(countPre.textContent).toBe('0');
|
|
530
|
-
expect(logs).toEqual(['ref called']);
|
|
531
|
-
|
|
532
|
-
buttonClickMe.click();
|
|
533
|
-
buttonIncrement.click();
|
|
534
|
-
flushSync();
|
|
387
|
+
it('returns the same tracked object if plain track is called with a tracked object', () => {
|
|
388
|
+
component App() {
|
|
389
|
+
const t = track({ a: 1, b: 2, c: 3 });
|
|
390
|
+
const doublet = track(t);
|
|
535
391
|
|
|
536
|
-
|
|
537
|
-
|
|
392
|
+
<pre>{t === doublet}</pre>
|
|
393
|
+
}
|
|
538
394
|
|
|
539
|
-
|
|
540
|
-
flushSync();
|
|
395
|
+
render(App);
|
|
541
396
|
|
|
542
|
-
|
|
543
|
-
|
|
397
|
+
const pre = container.querySelectorAll('pre')[0];
|
|
398
|
+
expect(pre.textContent).toBe('true');
|
|
544
399
|
});
|
|
545
400
|
});
|
|
@@ -27,16 +27,16 @@ describe('basic client > rendering & text', () => {
|
|
|
27
27
|
|
|
28
28
|
it('renders dynamic text', () => {
|
|
29
29
|
component Basic() {
|
|
30
|
-
let text = track('Hello World');
|
|
30
|
+
let &[text] = track('Hello World');
|
|
31
31
|
|
|
32
32
|
<button
|
|
33
33
|
onClick={() => {
|
|
34
|
-
|
|
34
|
+
text = 'Hello Ripple';
|
|
35
35
|
}}
|
|
36
36
|
>
|
|
37
37
|
{'Change Text'}
|
|
38
38
|
</button>
|
|
39
|
-
<div>{
|
|
39
|
+
<div>{text}</div>
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
render(Basic);
|
|
@@ -104,24 +104,24 @@ describe('basic client > rendering & text', () => {
|
|
|
104
104
|
|
|
105
105
|
it('renders with mixed static and dynamic content', () => {
|
|
106
106
|
component Basic() {
|
|
107
|
-
let name = track('World');
|
|
108
|
-
let count = track(0);
|
|
107
|
+
let &[name] = track('World');
|
|
108
|
+
let &[count] = track(0);
|
|
109
109
|
const staticMessage = 'Welcome to Ripple!';
|
|
110
110
|
|
|
111
111
|
<div class="mixed-content">
|
|
112
112
|
<h1>{staticMessage}</h1>
|
|
113
|
-
<p class="greeting">{'Hello, ' +
|
|
114
|
-
<p class="notifications">{'You have ' +
|
|
113
|
+
<p class="greeting">{'Hello, ' + name + '!'}</p>
|
|
114
|
+
<p class="notifications">{'You have ' + count + ' notifications'}</p>
|
|
115
115
|
<button
|
|
116
116
|
onClick={() => {
|
|
117
|
-
|
|
117
|
+
count++;
|
|
118
118
|
}}
|
|
119
119
|
>
|
|
120
120
|
{'Add Notification'}
|
|
121
121
|
</button>
|
|
122
122
|
<button
|
|
123
123
|
onClick={() => {
|
|
124
|
-
|
|
124
|
+
name = name === 'World' ? 'User' : 'World';
|
|
125
125
|
}}
|
|
126
126
|
>
|
|
127
127
|
{'Toggle Name'}
|
|
@@ -151,11 +151,11 @@ describe('basic client > rendering & text', () => {
|
|
|
151
151
|
|
|
152
152
|
it('basic operations', () => {
|
|
153
153
|
component App() {
|
|
154
|
-
let count = track(0);
|
|
155
|
-
<div>{
|
|
156
|
-
<div>{
|
|
154
|
+
let &[count] = track(0);
|
|
155
|
+
<div>{count++}</div>
|
|
156
|
+
<div>{++count}</div>
|
|
157
157
|
<div>{5}</div>
|
|
158
|
-
<div>{
|
|
158
|
+
<div>{count}</div>
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
render(App);
|
|
@@ -164,27 +164,27 @@ describe('basic client > rendering & text', () => {
|
|
|
164
164
|
|
|
165
165
|
it('renders with conditional rendering using if statements', () => {
|
|
166
166
|
component Basic() {
|
|
167
|
-
let showContent = track(false);
|
|
168
|
-
let userRole = track('guest');
|
|
167
|
+
let &[showContent] = track(false);
|
|
168
|
+
let &[userRole] = track('guest');
|
|
169
169
|
|
|
170
170
|
<button
|
|
171
171
|
onClick={() => {
|
|
172
|
-
|
|
172
|
+
showContent = !showContent;
|
|
173
173
|
}}
|
|
174
174
|
>
|
|
175
175
|
{'Toggle Content'}
|
|
176
176
|
</button>
|
|
177
177
|
<button
|
|
178
178
|
onClick={() => {
|
|
179
|
-
|
|
179
|
+
userRole = userRole === 'guest' ? 'admin' : 'guest';
|
|
180
180
|
}}
|
|
181
181
|
>
|
|
182
182
|
{'Toggle Role'}
|
|
183
183
|
</button>
|
|
184
184
|
|
|
185
185
|
<div class="content">
|
|
186
|
-
if (
|
|
187
|
-
if (
|
|
186
|
+
if (showContent) {
|
|
187
|
+
if (userRole === 'admin') {
|
|
188
188
|
<div class="admin-content">{'Admin content'}</div>
|
|
189
189
|
} else {
|
|
190
190
|
<div class="user-content">{'User content'}</div>
|
|
@@ -6,14 +6,14 @@ describe('basic client > utilities', () => {
|
|
|
6
6
|
const promise = new Promise<void>((res) => (resolve = res));
|
|
7
7
|
|
|
8
8
|
component Basic() {
|
|
9
|
-
let value = track(0);
|
|
9
|
+
let &[value] = track(0);
|
|
10
10
|
effect(() => {
|
|
11
11
|
untrack(() => {
|
|
12
|
-
|
|
12
|
+
value++;
|
|
13
13
|
tick().then(() => resolve());
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
|
-
<p>{
|
|
16
|
+
<p>{value}</p>
|
|
17
17
|
}
|
|
18
18
|
render(Basic);
|
|
19
19
|
|
|
@@ -4,25 +4,25 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
4
4
|
it('can pass reactivity between functions with simple arrays and destructuring', () => {
|
|
5
5
|
let log: string[] = [];
|
|
6
6
|
|
|
7
|
-
function createDouble([count]:
|
|
8
|
-
const double = track(() =>
|
|
7
|
+
function createDouble(&[count]: Tracked<number>) {
|
|
8
|
+
const double = track(() => count * 2);
|
|
9
9
|
|
|
10
10
|
effect(() => {
|
|
11
|
-
log.push('Count:' +
|
|
11
|
+
log.push('Count:' + count);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
return
|
|
14
|
+
return double;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
component App() {
|
|
18
|
-
let count = track(0);
|
|
18
|
+
let &[count, countTracked] = track(0);
|
|
19
19
|
|
|
20
|
-
const [double] = createDouble(
|
|
20
|
+
const &[double] = createDouble(countTracked);
|
|
21
21
|
|
|
22
|
-
<div>{'Double: ' +
|
|
22
|
+
<div>{'Double: ' + double}</div>
|
|
23
23
|
<button
|
|
24
24
|
onClick={() => {
|
|
25
|
-
|
|
25
|
+
count++;
|
|
26
26
|
}}
|
|
27
27
|
>
|
|
28
28
|
{'Increment'}
|
|
@@ -54,10 +54,10 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
54
54
|
let log: string[] = [];
|
|
55
55
|
|
|
56
56
|
function createDouble({ count }: { count: Tracked<number> }) {
|
|
57
|
-
const double = track(() =>
|
|
57
|
+
const double = track(() => count.value * 2);
|
|
58
58
|
|
|
59
59
|
effect(() => {
|
|
60
|
-
log.push('Count:' +
|
|
60
|
+
log.push('Count:' + count.value);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
return { double };
|
|
@@ -68,10 +68,10 @@ describe('passing reactivity between boundaries tests', () => {
|
|
|
68
68
|
|
|
69
69
|
const { double } = createDouble({ count });
|
|
70
70
|
|
|
71
|
-
<div>{'Double: ' +
|
|
71
|
+
<div>{'Double: ' + double.value}</div>
|
|
72
72
|
<button
|
|
73
73
|
onClick={() => {
|
|
74
|
-
|
|
74
|
+
count.value++;
|
|
75
75
|
}}
|
|
76
76
|
>
|
|
77
77
|
{'Increment'}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`compiler > assignments > compiles tracked values in effect with assignment expression 1`] = `"state.count = _$_.get(
|
|
3
|
+
exports[`compiler > assignments > compiles tracked values in effect with assignment expression 1`] = `"state.count = _$_.get(lazy);"`;
|
|
4
4
|
|
|
5
5
|
exports[`compiler > assignments > compiles tracked values in effect with update expressions 1`] = `
|
|
6
6
|
"_$_.untrack(() => {
|
|
7
|
-
state.preIncrement = _$_.update_pre(
|
|
8
|
-
state.postIncrement = _$_.update(
|
|
9
|
-
state.preDecrement = _$_.update_pre(
|
|
10
|
-
state.postDecrement = _$_.update(
|
|
7
|
+
state.preIncrement = _$_.update_pre(lazy);
|
|
8
|
+
state.postIncrement = _$_.update(lazy);
|
|
9
|
+
state.preDecrement = _$_.update_pre(lazy, -1);
|
|
10
|
+
state.postDecrement = _$_.update(lazy, -1);
|
|
11
11
|
});"
|
|
12
12
|
`;
|