ripple 0.2.152 → 0.2.154
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/README.md +3 -3
- package/package.json +5 -5
- package/src/compiler/phases/1-parse/index.js +1 -1
- package/src/compiler/phases/3-transform/client/index.js +37 -16
- package/src/compiler/phases/3-transform/server/index.js +43 -25
- package/src/runtime/internal/client/events.js +5 -1
- package/src/runtime/internal/client/index.js +2 -1
- package/src/runtime/internal/client/render.js +18 -15
- package/src/runtime/internal/client/runtime.js +75 -10
- package/src/runtime/internal/server/index.js +51 -11
- package/src/server/index.js +1 -1
- package/tests/client/array/array.derived.test.ripple +61 -33
- package/tests/client/array/array.iteration.test.ripple +3 -1
- package/tests/client/array/array.mutations.test.ripple +19 -15
- package/tests/client/array/array.static.test.ripple +115 -104
- package/tests/client/array/array.to-methods.test.ripple +3 -3
- package/tests/client/basic/basic.attributes.test.ripple +110 -57
- package/tests/client/basic/basic.collections.test.ripple +41 -22
- package/tests/client/basic/basic.errors.test.ripple +12 -6
- package/tests/client/basic/basic.events.test.ripple +51 -33
- package/tests/client/basic/basic.reactivity.test.ripple +120 -56
- package/tests/client/basic/basic.rendering.test.ripple +49 -19
- package/tests/client/basic/basic.styling.test.ripple +2 -2
- package/tests/client/basic/basic.utilities.test.ripple +1 -1
- package/tests/client/boundaries.test.ripple +70 -58
- package/tests/client/compiler/compiler.assignments.test.ripple +32 -4
- package/tests/client/compiler/compiler.attributes.test.ripple +46 -46
- package/tests/client/compiler/compiler.basic.test.ripple +18 -15
- package/tests/client/compiler/compiler.tracked-access.test.ripple +53 -42
- package/tests/client/compiler/compiler.typescript.test.ripple +1 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
- package/tests/client/composite/composite.generics.test.ripple +39 -36
- package/tests/client/composite/composite.props.test.ripple +4 -3
- package/tests/client/composite/composite.reactivity.test.ripple +112 -27
- package/tests/client/composite/composite.render.test.ripple +9 -8
- package/tests/client/computed-properties.test.ripple +24 -24
- package/tests/client/context.test.ripple +11 -9
- package/tests/client/date.test.ripple +3 -1
- package/tests/client/dynamic-elements.test.ripple +103 -78
- package/tests/client/for.test.ripple +27 -17
- package/tests/client/head.test.ripple +42 -6
- package/tests/client/html.test.ripple +42 -32
- package/tests/client/input-value.test.ripple +4 -4
- package/tests/client/map.test.ripple +140 -141
- package/tests/client/media-query.test.ripple +31 -31
- package/tests/client/object.test.ripple +148 -112
- package/tests/client/portal.test.ripple +29 -15
- package/tests/client/ref.test.ripple +9 -3
- package/tests/client/set.test.ripple +111 -111
- package/tests/client/tracked-expression.test.ripple +16 -17
- package/tests/client/url/url.derived.test.ripple +19 -9
- package/tests/client/url/url.parsing.test.ripple +24 -8
- package/tests/client/url/url.partial-removal.test.ripple +12 -4
- package/tests/client/url/url.reactivity.test.ripple +63 -25
- package/tests/client/url/url.serialization.test.ripple +18 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +10 -6
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +3 -1
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +26 -14
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -1
- package/tests/server/await.test.ripple +23 -22
- package/tests/server/basic.test.ripple +1 -1
- package/tests/server/compiler.test.ripple +3 -7
- package/tests/server/composite.test.ripple +38 -36
- package/tests/server/for.test.ripple +9 -5
- package/tests/server/if.test.ripple +1 -1
- package/tests/server/streaming-ssr.test.ripple +67 -0
- package/types/server.d.ts +5 -4
|
@@ -5,19 +5,31 @@ describe('basic client > reactivity', () => {
|
|
|
5
5
|
component Basic() {
|
|
6
6
|
<div>
|
|
7
7
|
let obj = {
|
|
8
|
-
count: track(0)
|
|
8
|
+
count: track(0),
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
<span>{obj.@count}</span>
|
|
12
12
|
</div>
|
|
13
13
|
<div>
|
|
14
14
|
let b = {
|
|
15
|
-
count: track(0)
|
|
15
|
+
count: track(0),
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
<button
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
<button
|
|
19
|
+
onClick={() => {
|
|
20
|
+
b.@count--;
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
{'-'}
|
|
24
|
+
</button>
|
|
25
|
+
<span class="count">{b.@count}</span>
|
|
26
|
+
<button
|
|
27
|
+
onClick={() => {
|
|
28
|
+
b.@count++;
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
{'+'}
|
|
32
|
+
</button>
|
|
21
33
|
</div>
|
|
22
34
|
}
|
|
23
35
|
render(Basic);
|
|
@@ -41,19 +53,31 @@ describe('basic client > reactivity', () => {
|
|
|
41
53
|
|
|
42
54
|
<div>
|
|
43
55
|
let obj = {
|
|
44
|
-
count: track(0)
|
|
56
|
+
count: track(0),
|
|
45
57
|
};
|
|
46
58
|
|
|
47
59
|
<span>{obj[@count]}</span>
|
|
48
60
|
</div>
|
|
49
61
|
<div>
|
|
50
62
|
let b = {
|
|
51
|
-
count: track(0)
|
|
63
|
+
count: track(0),
|
|
52
64
|
};
|
|
53
65
|
|
|
54
|
-
<button
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
<button
|
|
67
|
+
onClick={() => {
|
|
68
|
+
b[@count]--;
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
{'-'}
|
|
72
|
+
</button>
|
|
73
|
+
<span class="count">{b[@count]}</span>
|
|
74
|
+
<button
|
|
75
|
+
onClick={() => {
|
|
76
|
+
b[@count]++;
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
{'+'}
|
|
80
|
+
</button>
|
|
57
81
|
</div>
|
|
58
82
|
}
|
|
59
83
|
render(Basic);
|
|
@@ -75,10 +99,16 @@ describe('basic client > reactivity', () => {
|
|
|
75
99
|
component Basic() {
|
|
76
100
|
let count = track(5);
|
|
77
101
|
|
|
78
|
-
<div class=
|
|
79
|
-
<div class=
|
|
80
|
-
<div class=
|
|
81
|
-
<button
|
|
102
|
+
<div class="count">{@count}</div>
|
|
103
|
+
<div class="doubled">{@count * 2}</div>
|
|
104
|
+
<div class="is-even">{@count % 2 === 0 ? 'Even' : 'Odd'}</div>
|
|
105
|
+
<button
|
|
106
|
+
onClick={() => {
|
|
107
|
+
@count++;
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
{'Increment'}
|
|
111
|
+
</button>
|
|
82
112
|
}
|
|
83
113
|
|
|
84
114
|
render(Basic);
|
|
@@ -110,8 +140,20 @@ describe('basic client > reactivity', () => {
|
|
|
110
140
|
|
|
111
141
|
const total = track(() => arr.reduce((a, b) => a + @b, 0));
|
|
112
142
|
|
|
113
|
-
<button
|
|
114
|
-
|
|
143
|
+
<button
|
|
144
|
+
onClick={() => {
|
|
145
|
+
@first++;
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
{'first:' + @first}
|
|
149
|
+
</button>
|
|
150
|
+
<button
|
|
151
|
+
onClick={() => {
|
|
152
|
+
@second++;
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
{'second: ' + @second}
|
|
156
|
+
</button>
|
|
115
157
|
|
|
116
158
|
effect(() => {
|
|
117
159
|
let _arr: number[] = [];
|
|
@@ -124,15 +166,15 @@ describe('basic client > reactivity', () => {
|
|
|
124
166
|
});
|
|
125
167
|
|
|
126
168
|
effect(() => {
|
|
127
|
-
if (arr.map(a => @a).includes(1)) {
|
|
169
|
+
if (arr.map((a) => @a).includes(1)) {
|
|
128
170
|
logs.push('arr includes 1');
|
|
129
171
|
}
|
|
130
172
|
});
|
|
131
173
|
|
|
132
174
|
<div>{'Sum: ' + @total}</div>
|
|
133
|
-
<div>{'Comma Separated: ' + arr.map(a => @a).join(', ')}</div>
|
|
134
|
-
<div>{'Number to string: ' + arr.map(a => String(@a))}</div>
|
|
135
|
-
<div>{'Even numbers: ' + arr.map(a => @a).filter(a => a % 2 === 0)}</div>
|
|
175
|
+
<div>{'Comma Separated: ' + arr.map((a) => @a).join(', ')}</div>
|
|
176
|
+
<div>{'Number to string: ' + arr.map((a) => String(@a))}</div>
|
|
177
|
+
<div>{'Even numbers: ' + arr.map((a) => @a).filter((a) => a % 2 === 0)}</div>
|
|
136
178
|
}
|
|
137
179
|
|
|
138
180
|
render(App);
|
|
@@ -166,15 +208,18 @@ describe('basic client > reactivity', () => {
|
|
|
166
208
|
expect(logs).toEqual(['0, 0', '1, 0', 'arr includes 1', '1, 1', 'arr includes 1']);
|
|
167
209
|
});
|
|
168
210
|
|
|
169
|
-
|
|
170
|
-
|
|
171
211
|
it('uses track get and set where both mutate value', () => {
|
|
172
212
|
component App() {
|
|
173
|
-
let count = track(0, v => v + 1, v => v * 2);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
<
|
|
177
|
-
|
|
213
|
+
let count = track(0, (v) => v + 1, (v) => v * 2);
|
|
214
|
+
|
|
215
|
+
<div class="count">{@count}</div>
|
|
216
|
+
<button
|
|
217
|
+
onClick={() => {
|
|
218
|
+
@count++;
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
{'Increment'}
|
|
222
|
+
</button>
|
|
178
223
|
}
|
|
179
224
|
|
|
180
225
|
render(App);
|
|
@@ -191,11 +236,16 @@ describe('basic client > reactivity', () => {
|
|
|
191
236
|
|
|
192
237
|
it('uses track get and set where set only mutates value', () => {
|
|
193
238
|
component App() {
|
|
194
|
-
let count = track(1, v => v, v => v * 2);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
<
|
|
198
|
-
|
|
239
|
+
let count = track(1, (v) => v, (v) => v * 2);
|
|
240
|
+
|
|
241
|
+
<div class="count">{@count}</div>
|
|
242
|
+
<button
|
|
243
|
+
onClick={() => {
|
|
244
|
+
@count++;
|
|
245
|
+
}}
|
|
246
|
+
>
|
|
247
|
+
{'Increment'}
|
|
248
|
+
</button>
|
|
199
249
|
}
|
|
200
250
|
|
|
201
251
|
render(App);
|
|
@@ -212,11 +262,16 @@ describe('basic client > reactivity', () => {
|
|
|
212
262
|
|
|
213
263
|
it('uses track get and set where get only mutates value', () => {
|
|
214
264
|
component App() {
|
|
215
|
-
let count = track(0, v => v + 1, v => v);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
<
|
|
219
|
-
|
|
265
|
+
let count = track(0, (v) => v + 1, (v) => v);
|
|
266
|
+
|
|
267
|
+
<div class="count">{@count}</div>
|
|
268
|
+
<button
|
|
269
|
+
onClick={() => {
|
|
270
|
+
@count++;
|
|
271
|
+
}}
|
|
272
|
+
>
|
|
273
|
+
{'Increment'}
|
|
274
|
+
</button>
|
|
220
275
|
}
|
|
221
276
|
|
|
222
277
|
render(App);
|
|
@@ -235,12 +290,18 @@ describe('basic client > reactivity', () => {
|
|
|
235
290
|
let logs: number[] = [];
|
|
236
291
|
|
|
237
292
|
component App() {
|
|
238
|
-
let count = track(0, v => v, (next, prev) => {
|
|
293
|
+
let count = track(0, (v) => v, (next, prev) => {
|
|
239
294
|
logs.push(prev, next);
|
|
240
295
|
return next;
|
|
241
296
|
});
|
|
242
297
|
|
|
243
|
-
<button
|
|
298
|
+
<button
|
|
299
|
+
onClick={() => {
|
|
300
|
+
@count++;
|
|
301
|
+
}}
|
|
302
|
+
>
|
|
303
|
+
{'Increment'}
|
|
304
|
+
</button>
|
|
244
305
|
}
|
|
245
306
|
|
|
246
307
|
render(App);
|
|
@@ -252,7 +313,7 @@ describe('basic client > reactivity', () => {
|
|
|
252
313
|
expect(logs).toEqual([0, 1]);
|
|
253
314
|
});
|
|
254
315
|
|
|
255
|
-
it(
|
|
316
|
+
it('doesn\'t error on mutating a tracked variable in track() setter', () => {
|
|
256
317
|
component Basic() {
|
|
257
318
|
let count = track(0);
|
|
258
319
|
|
|
@@ -270,14 +331,14 @@ describe('basic client > reactivity', () => {
|
|
|
270
331
|
});
|
|
271
332
|
|
|
272
333
|
it('unwraps tracked values inside effect', () => {
|
|
273
|
-
let state: { count?: number
|
|
334
|
+
let state: { count?: number } = {};
|
|
274
335
|
|
|
275
336
|
component Basic() {
|
|
276
337
|
let count = track(0);
|
|
277
338
|
|
|
278
339
|
effect(() => {
|
|
279
340
|
state.count = @count;
|
|
280
|
-
})
|
|
341
|
+
});
|
|
281
342
|
}
|
|
282
343
|
|
|
283
344
|
render(Basic);
|
|
@@ -308,7 +369,7 @@ describe('basic client > reactivity', () => {
|
|
|
308
369
|
state.postDecrement = @count--;
|
|
309
370
|
state.finalValue = @count;
|
|
310
371
|
});
|
|
311
|
-
})
|
|
372
|
+
});
|
|
312
373
|
}
|
|
313
374
|
|
|
314
375
|
render(Basic);
|
|
@@ -327,9 +388,9 @@ describe('basic client > reactivity', () => {
|
|
|
327
388
|
component App() {
|
|
328
389
|
let message = track('');
|
|
329
390
|
|
|
330
|
-
try{
|
|
391
|
+
try {
|
|
331
392
|
const [a, b, rest] = trackSplit(null, ['a', 'b']);
|
|
332
|
-
} catch(e) {
|
|
393
|
+
} catch (e) {
|
|
333
394
|
@message = (e as Error).message;
|
|
334
395
|
}
|
|
335
396
|
|
|
@@ -346,9 +407,9 @@ describe('basic client > reactivity', () => {
|
|
|
346
407
|
component App() {
|
|
347
408
|
let message = track('');
|
|
348
409
|
|
|
349
|
-
try{
|
|
410
|
+
try {
|
|
350
411
|
const [a, b, rest] = trackSplit([1, 2, 3], ['a', 'b']);
|
|
351
|
-
} catch(e) {
|
|
412
|
+
} catch (e) {
|
|
352
413
|
@message = (e as Error).message;
|
|
353
414
|
}
|
|
354
415
|
|
|
@@ -363,12 +424,12 @@ describe('basic client > reactivity', () => {
|
|
|
363
424
|
|
|
364
425
|
it('errors on invalid value as tracked for track with trackSplit', () => {
|
|
365
426
|
component App() {
|
|
366
|
-
const t = track({a: 1, b: 2, c: 3});
|
|
427
|
+
const t = track({ a: 1, b: 2, c: 3 });
|
|
367
428
|
let message = track('');
|
|
368
429
|
|
|
369
|
-
try{
|
|
430
|
+
try {
|
|
370
431
|
const [a, b, rest] = trackSplit(t, ['a', 'b']);
|
|
371
|
-
} catch(e) {
|
|
432
|
+
} catch (e) {
|
|
372
433
|
@message = (e as Error).message;
|
|
373
434
|
}
|
|
374
435
|
|
|
@@ -383,7 +444,7 @@ describe('basic client > reactivity', () => {
|
|
|
383
444
|
|
|
384
445
|
it('returns undefined for non-existent props in track with trackSplit', () => {
|
|
385
446
|
component App() {
|
|
386
|
-
const [a, b, rest] = trackSplit({a: 1, c: 1}, ['a', 'b']);
|
|
447
|
+
const [a, b, rest] = trackSplit({ a: 1, c: 1 }, ['a', 'b']);
|
|
387
448
|
|
|
388
449
|
<pre>{@a}</pre>
|
|
389
450
|
<pre>{String(@b)}</pre>
|
|
@@ -403,7 +464,7 @@ describe('basic client > reactivity', () => {
|
|
|
403
464
|
|
|
404
465
|
it('returns the same tracked object if plain track is called with a tracked object', () => {
|
|
405
466
|
component App() {
|
|
406
|
-
const t = track({a: 1, b: 2, c: 3});
|
|
467
|
+
const t = track({ a: 1, b: 2, c: 3 });
|
|
407
468
|
const doublet = track(t);
|
|
408
469
|
|
|
409
470
|
<pre>{t === doublet}</pre>
|
|
@@ -434,7 +495,9 @@ describe('basic client > reactivity', () => {
|
|
|
434
495
|
onClick={() => @name === 'Click Me' ? @name = 'Clicked' : @name = 'Click Me'}
|
|
435
496
|
{@count}
|
|
436
497
|
{ref buttonRef}
|
|
437
|
-
>
|
|
498
|
+
>
|
|
499
|
+
{@name}
|
|
500
|
+
</Child>
|
|
438
501
|
|
|
439
502
|
<button onClick={() => @count++}>{'Increment Count'}</button>
|
|
440
503
|
}
|
|
@@ -443,7 +506,9 @@ describe('basic client > reactivity', () => {
|
|
|
443
506
|
const [children, count, rest] = trackSplit(props, ['children', 'count']);
|
|
444
507
|
|
|
445
508
|
if (@count < 2) {
|
|
446
|
-
<button {...@rest}
|
|
509
|
+
<button {...@rest}>
|
|
510
|
+
<@children />
|
|
511
|
+
</button>
|
|
447
512
|
}
|
|
448
513
|
<pre>{@count}</pre>
|
|
449
514
|
}
|
|
@@ -459,7 +524,6 @@ describe('basic client > reactivity', () => {
|
|
|
459
524
|
expect(countPre.textContent).toBe('0');
|
|
460
525
|
expect(logs).toEqual(['ref called']);
|
|
461
526
|
|
|
462
|
-
|
|
463
527
|
buttonClickMe.click();
|
|
464
528
|
buttonIncrement.click();
|
|
465
529
|
flushSync();
|
|
@@ -470,7 +534,7 @@ describe('basic client > reactivity', () => {
|
|
|
470
534
|
buttonIncrement.click();
|
|
471
535
|
flushSync();
|
|
472
536
|
|
|
473
|
-
expect(logs).toEqual(['ref called','cleanup ref']);
|
|
537
|
+
expect(logs).toEqual(['ref called', 'cleanup ref']);
|
|
474
538
|
});
|
|
475
539
|
});
|
|
476
540
|
});
|
|
@@ -29,7 +29,13 @@ describe('basic client > rendering & text', () => {
|
|
|
29
29
|
component Basic() {
|
|
30
30
|
let text = track('Hello World');
|
|
31
31
|
|
|
32
|
-
<button
|
|
32
|
+
<button
|
|
33
|
+
onClick={() => {
|
|
34
|
+
@text = 'Hello Ripple';
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
{'Change Text'}
|
|
38
|
+
</button>
|
|
33
39
|
<div>{@text}</div>
|
|
34
40
|
}
|
|
35
41
|
|
|
@@ -62,14 +68,14 @@ describe('basic client > rendering & text', () => {
|
|
|
62
68
|
});
|
|
63
69
|
|
|
64
70
|
it('renders tick template literal for nested children', () => {
|
|
65
|
-
component Child({ level, children }: { level: number
|
|
66
|
-
if(level == 1) {
|
|
71
|
+
component Child({ level, children }: { level: number; children: any }) {
|
|
72
|
+
if (level == 1) {
|
|
67
73
|
<h1><children /></h1>
|
|
68
74
|
}
|
|
69
|
-
if(level == 2) {
|
|
75
|
+
if (level == 2) {
|
|
70
76
|
<h2><children /></h2>
|
|
71
77
|
}
|
|
72
|
-
if(level == 3) {
|
|
78
|
+
if (level == 3) {
|
|
73
79
|
<h3><children /></h3>
|
|
74
80
|
}
|
|
75
81
|
}
|
|
@@ -84,7 +90,7 @@ describe('basic client > rendering & text', () => {
|
|
|
84
90
|
|
|
85
91
|
it('renders simple JS expression logic correctly', () => {
|
|
86
92
|
component Example() {
|
|
87
|
-
let test = {}
|
|
93
|
+
let test = {};
|
|
88
94
|
let counter = 0;
|
|
89
95
|
test[counter++] = 'Test';
|
|
90
96
|
|
|
@@ -102,12 +108,24 @@ describe('basic client > rendering & text', () => {
|
|
|
102
108
|
let count = track(0);
|
|
103
109
|
const staticMessage = 'Welcome to Ripple!';
|
|
104
110
|
|
|
105
|
-
<div class=
|
|
111
|
+
<div class="mixed-content">
|
|
106
112
|
<h1>{staticMessage}</h1>
|
|
107
|
-
<p class=
|
|
108
|
-
<p class=
|
|
109
|
-
<button
|
|
110
|
-
|
|
113
|
+
<p class="greeting">{'Hello, ' + @name + '!'}</p>
|
|
114
|
+
<p class="notifications">{'You have ' + @count + ' notifications'}</p>
|
|
115
|
+
<button
|
|
116
|
+
onClick={() => {
|
|
117
|
+
@count++;
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
{'Add Notification'}
|
|
121
|
+
</button>
|
|
122
|
+
<button
|
|
123
|
+
onClick={() => {
|
|
124
|
+
@name = @name === 'World' ? 'User' : 'World';
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{'Toggle Name'}
|
|
128
|
+
</button>
|
|
111
129
|
</div>
|
|
112
130
|
}
|
|
113
131
|
|
|
@@ -133,7 +151,7 @@ describe('basic client > rendering & text', () => {
|
|
|
133
151
|
|
|
134
152
|
it('basic operations', () => {
|
|
135
153
|
component App() {
|
|
136
|
-
let count = track(0)
|
|
154
|
+
let count = track(0);
|
|
137
155
|
<div>{@count++}</div>
|
|
138
156
|
<div>{++@count}</div>
|
|
139
157
|
<div>{5}</div>
|
|
@@ -149,18 +167,30 @@ describe('basic client > rendering & text', () => {
|
|
|
149
167
|
let showContent = track(false);
|
|
150
168
|
let userRole = track('guest');
|
|
151
169
|
|
|
152
|
-
<button
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
170
|
+
<button
|
|
171
|
+
onClick={() => {
|
|
172
|
+
@showContent = !@showContent;
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
175
|
+
{'Toggle Content'}
|
|
176
|
+
</button>
|
|
177
|
+
<button
|
|
178
|
+
onClick={() => {
|
|
179
|
+
@userRole = @userRole === 'guest' ? 'admin' : 'guest';
|
|
180
|
+
}}
|
|
181
|
+
>
|
|
182
|
+
{'Toggle Role'}
|
|
183
|
+
</button>
|
|
184
|
+
|
|
185
|
+
<div class="content">
|
|
156
186
|
if (@showContent) {
|
|
157
187
|
if (@userRole === 'admin') {
|
|
158
|
-
<div class=
|
|
188
|
+
<div class="admin-content">{'Admin content'}</div>
|
|
159
189
|
} else {
|
|
160
|
-
<div class=
|
|
190
|
+
<div class="user-content">{'User content'}</div>
|
|
161
191
|
}
|
|
162
192
|
} else {
|
|
163
|
-
<div class=
|
|
193
|
+
<div class="no-content">{'No content'}</div>
|
|
164
194
|
}
|
|
165
195
|
</div>
|
|
166
196
|
}
|
|
@@ -3,9 +3,9 @@ import { compile } from 'ripple/compiler';
|
|
|
3
3
|
describe('basic client > styling', () => {
|
|
4
4
|
it('renders with styling scoped to component', () => {
|
|
5
5
|
component Basic() {
|
|
6
|
-
<div class=
|
|
6
|
+
<div class="styled-container">
|
|
7
7
|
<h1>{'Styled heading'}</h1>
|
|
8
|
-
<p class=
|
|
8
|
+
<p class="text">{'Styled paragraph'}</p>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
11
|
<style>
|
|
@@ -3,7 +3,7 @@ import { track, effect, untrack, tick } from 'ripple';
|
|
|
3
3
|
describe('basic client > utilities', () => {
|
|
4
4
|
it('tick function', async () => {
|
|
5
5
|
let resolve: () => void;
|
|
6
|
-
const promise = new Promise<void>((res) =>
|
|
6
|
+
const promise = new Promise<void>((res) => resolve = res);
|
|
7
7
|
|
|
8
8
|
component Basic() {
|
|
9
9
|
let value = track(0);
|
|
@@ -1,89 +1,101 @@
|
|
|
1
1
|
import { flushSync, effect, track } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('passing reactivity between boundaries tests', () => {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
it('can pass reactivity between functions with simple arrays and destructuring', () => {
|
|
5
|
+
let log: string[] = [];
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
function createDouble([count]) {
|
|
8
|
+
const double = track(() => @count * 2);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
effect(() => {
|
|
11
|
+
log.push('Count:' + @count);
|
|
12
|
+
});
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
return [double];
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
component App() {
|
|
18
|
+
let count = track(0);
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const [double] = createDouble([count]);
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
<div>{'Double: ' + @double}</div>
|
|
23
|
+
<button
|
|
24
|
+
onClick={() => {
|
|
25
|
+
@count++;
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
{'Increment'}
|
|
29
|
+
</button>
|
|
30
|
+
}
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
render(App);
|
|
33
|
+
flushSync();
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
expect(container.querySelector('div').textContent).toBe('Double: 0');
|
|
36
|
+
expect(log).toEqual(['Count:0']);
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
const button = container.querySelector('button');
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
button.click();
|
|
41
|
+
flushSync();
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
expect(container.querySelector('div').textContent).toBe('Double: 2');
|
|
44
|
+
expect(log).toEqual(['Count:0', 'Count:1']);
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
button.click();
|
|
47
|
+
flushSync();
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
expect(container.querySelector('div').textContent).toBe('Double: 4');
|
|
50
|
+
expect(log).toEqual(['Count:0', 'Count:1', 'Count:2']);
|
|
51
|
+
});
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
it('can pass reactivity between functions with simple objects and destructuring', () => {
|
|
54
|
+
let log: string[] = [];
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
function createDouble({ count }: { count: Tracked<number> }) {
|
|
57
|
+
const double = track(() => @count * 2);
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
effect(() => {
|
|
60
|
+
log.push('Count:' + @count);
|
|
61
|
+
});
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
return { double };
|
|
64
|
+
}
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
component App() {
|
|
67
|
+
let count = track(0);
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
const { double } = createDouble({ count });
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
<div>{'Double: ' + @double}</div>
|
|
72
|
+
<button
|
|
73
|
+
onClick={() => {
|
|
74
|
+
@count++;
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{'Increment'}
|
|
78
|
+
</button>
|
|
79
|
+
}
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
render(App);
|
|
82
|
+
flushSync();
|
|
71
83
|
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
expect(container.querySelector('div').textContent).toBe('Double: 0');
|
|
85
|
+
expect(log).toEqual(['Count:0']);
|
|
74
86
|
|
|
75
|
-
|
|
87
|
+
const button = container.querySelector('button');
|
|
76
88
|
|
|
77
|
-
|
|
78
|
-
|
|
89
|
+
button.click();
|
|
90
|
+
flushSync();
|
|
79
91
|
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
expect(container.querySelector('div').textContent).toBe('Double: 2');
|
|
93
|
+
expect(log).toEqual(['Count:0', 'Count:1']);
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
button.click();
|
|
96
|
+
flushSync();
|
|
85
97
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
expect(container.querySelector('div').textContent).toBe('Double: 4');
|
|
99
|
+
expect(log).toEqual(['Count:0', 'Count:1', 'Count:2']);
|
|
100
|
+
});
|
|
89
101
|
});
|