ripple 0.2.48 → 0.2.50

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,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, flushSync, effect } from 'ripple';
2
+ import { mount, flushSync, effect, track } from 'ripple';
3
3
  import { compile } from 'ripple/compiler';
4
4
 
5
5
  describe('basic', () => {
@@ -54,10 +54,10 @@ describe('basic', () => {
54
54
 
55
55
  it('render dynamic text', () => {
56
56
  component Basic() {
57
- let $text = 'Hello World';
57
+ let text = track('Hello World');
58
58
 
59
- <button onClick={() => $text = 'Hello Ripple'}>{'Change Text'}</button>
60
- <div>{$text}</div>
59
+ <button onClick={() => { @text = 'Hello Ripple' }}>{'Change Text'}</button>
60
+ <div>{@text}</div>
61
61
  }
62
62
 
63
63
  render(Basic);
@@ -89,20 +89,20 @@ describe('basic', () => {
89
89
  });
90
90
 
91
91
  it('render tick template literal for nested children', () => {
92
- component Child({ $level, children }) {
93
- if($level == 1) {
92
+ component Child({ level, children }) {
93
+ if(level == 1) {
94
94
  <h1><children /></h1>
95
95
  }
96
- if($level == 2) {
96
+ if(level == 2) {
97
97
  <h2><children /></h2>
98
98
  }
99
- if($level == 3) {
99
+ if(level == 3) {
100
100
  <h3><children /></h3>
101
101
  }
102
102
  }
103
103
 
104
104
  component App() {
105
- <Child $level={1}>{`Heading 1`} </Child>
105
+ <Child level={1}>{`Heading 1`}</Child>
106
106
  }
107
107
 
108
108
  render(App);
@@ -111,10 +111,10 @@ describe('basic', () => {
111
111
 
112
112
  it('render dynamic class attribute', () => {
113
113
  component Basic() {
114
- let $active = false;
114
+ let active = track(false);
115
115
 
116
- <button onClick={() => $active = !$active}>{'Toggle'}</button>
117
- <div $class={$active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
116
+ <button onClick={() => { @active = !@active }}>{'Toggle'}</button>
117
+ <div class={@active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
118
118
 
119
119
  <style>
120
120
  .active {
@@ -143,10 +143,10 @@ describe('basic', () => {
143
143
 
144
144
  it('render dynamic id attribute', () => {
145
145
  component Basic() {
146
- let $count = 0;
146
+ let count = track(0);
147
147
 
148
- <button onClick={() => $count++}>{'Increment'}</button>
149
- <div $id={`item-${$count}`}>{'Dynamic ID'}</div>
148
+ <button onClick={() => { @count++ }}>{'Increment'}</button>
149
+ <div id={`item-${@count}`}>{'Dynamic ID'}</div>
150
150
  }
151
151
 
152
152
  render(Basic);
@@ -169,10 +169,10 @@ describe('basic', () => {
169
169
 
170
170
  it('render dynamic style attribute', () => {
171
171
  component Basic() {
172
- let $color = 'red';
172
+ let color = track('red');
173
173
 
174
- <button onClick={() => $color = $color === 'red' ? 'blue' : 'red'}>{'Change Color'}</button>
175
- <div $style={`color: ${$color}; font-weight: bold;`}>{'Dynamic Style'}</div>
174
+ <button onClick={() => { @color = @color === 'red' ? 'blue' : 'red' }}>{'Change Color'}</button>
175
+ <div style={`color: ${@color}; font-weight: bold;`}>{'Dynamic Style'}</div>
176
176
  }
177
177
 
178
178
  render(Basic);
@@ -217,14 +217,14 @@ describe('basic', () => {
217
217
 
218
218
  it('render dynamic boolean attributes', () => {
219
219
  component Basic() {
220
- let $disabled = false;
221
- let $checked = false;
220
+ let disabled = track(false);
221
+ let checked = track(false);
222
222
 
223
223
  <button onClick={() => {
224
- $disabled = !$disabled;
225
- $checked = !$checked;
224
+ @disabled = !@disabled;
225
+ @checked = !@checked;
226
226
  }}>{'Toggle'}</button>
227
- <input type='checkbox' $disabled={$disabled} $checked={$checked} />
227
+ <input type='checkbox' disabled={@disabled} checked={@checked} />
228
228
  }
229
229
 
230
230
  render(Basic);
@@ -244,16 +244,16 @@ describe('basic', () => {
244
244
 
245
245
  it('render multiple dynamic attributes', () => {
246
246
  component Basic() {
247
- let $theme = 'light';
248
- let $size = 'medium';
247
+ let theme = track('light');
248
+ let size = track('medium');
249
249
 
250
250
  <button
251
251
  onClick={() => {
252
- $theme = $theme === 'light' ? 'dark' : 'light';
253
- $size = $size === 'medium' ? 'large' : 'medium';
252
+ @theme = @theme === 'light' ? 'dark' : 'light';
253
+ @size = @size === 'medium' ? 'large' : 'medium';
254
254
  }}
255
255
  >{'Toggle Theme & Size'}</button>
256
- <div $class={`theme-${$theme} size-${$size}`} $data-theme={$theme} $data-size={$size}>{'Multiple Dynamic Attributes'}</div>
256
+ <div class={`theme-${@theme} size-${@size}`} data-theme={@theme} data-size={@size}>{'Multiple Dynamic Attributes'}</div>
257
257
  }
258
258
 
259
259
  render(Basic);
@@ -275,16 +275,16 @@ describe('basic', () => {
275
275
 
276
276
  it('render conditional attributes', () => {
277
277
  component Basic() {
278
- let $showTitle = false;
279
- let $showAria = false;
278
+ let showTitle = track(false);
279
+ let showAria = track(false);
280
280
 
281
281
  <button onClick={() => {
282
- $showTitle = !$showTitle;
283
- $showAria = !$showAria;
282
+ @showTitle = !@showTitle;
283
+ @showAria = !@showAria;
284
284
  }}>{'Toggle Attributes'}</button>
285
285
  <div
286
- $title={$showTitle ? 'This is a title' : null}
287
- $aria-label={$showAria ? 'Accessible label' : null}
286
+ title={@showTitle ? 'This is a title' : null}
287
+ aria-label={@showAria ? 'Accessible label' : null}
288
288
  >{'Conditional Attributes'}</div>
289
289
  }
290
290
 
@@ -311,21 +311,21 @@ describe('basic', () => {
311
311
 
312
312
  it('render spread attributes', () => {
313
313
  component Basic() {
314
- let $attrs = {
314
+ let attrs = track({
315
315
  class: 'initial',
316
316
  id: 'test-1'
317
- };
317
+ });
318
318
 
319
319
  <button
320
320
  onClick={() => {
321
- $attrs = {
321
+ @attrs = {
322
322
  class: 'updated',
323
323
  id: 'test-2',
324
324
  'data-extra': 'value'
325
325
  };
326
326
  }}
327
327
  >{'Update Attributes'}</button>
328
- <div {...$attrs}>{'Spread Attributes'}</div>
328
+ <div {...@attrs}>{'Spread Attributes'}</div>
329
329
  }
330
330
 
331
331
  render(Basic);
@@ -349,19 +349,19 @@ describe('basic', () => {
349
349
  component Basic() {
350
350
  <div>
351
351
  let obj = {
352
- $count: 0
352
+ count: track(0)
353
353
  };
354
354
 
355
- <span>{obj.$count}</span>
355
+ <span>{obj.@count}</span>
356
356
  </div>
357
357
  <div>
358
358
  let b = {
359
- $count: 0
359
+ count: track(0)
360
360
  };
361
361
 
362
- <button onClick={() => b.$count--}>{'-'}</button>
363
- <span class='count'>{b.$count}</span>
364
- <button onClick={() => b.$count++}>{'+'}</button>
362
+ <button onClick={() => { b.@count-- }}>{'-'}</button>
363
+ <span class='count'>{b.@count}</span>
364
+ <button onClick={() => { b.@count++ }}>{'+'}</button>
365
365
  </div>
366
366
  }
367
367
  render(Basic);
@@ -379,25 +379,27 @@ describe('basic', () => {
379
379
  expect(container.querySelector('.count').textContent).toBe('0');
380
380
  });
381
381
 
382
- it('renders multiple reactive lexical blocks with complexity', () => {
382
+ // TODO
383
+ it.skip('renders multiple reactive lexical blocks with complexity', () => {
384
+
383
385
  component Basic() {
384
- const count = '$count';
386
+ const count = 'count';
385
387
 
386
388
  <div>
387
389
  let obj = {
388
- $count: 0
390
+ count: track(0)
389
391
  };
390
392
 
391
393
  <span>{obj[count]}</span>
392
394
  </div>
393
395
  <div>
394
396
  let b = {
395
- $count: 0
397
+ count: track(0)
396
398
  };
397
399
 
398
- <button onClick={() => b[count]--}>{'-'}</button>
400
+ <button onClick={() => { b[count]-- }}>{'-'}</button>
399
401
  <span class='count'>{b[count]}</span>
400
- <button onClick={() => b[count]++}>{'+'}</button>
402
+ <button onClick={() => { b[count]++ }}>{'+'}</button>
401
403
  </div>
402
404
  }
403
405
  render(Basic);
@@ -417,15 +419,15 @@ describe('basic', () => {
417
419
 
418
420
  it('renders with different event types', () => {
419
421
  component Basic() {
420
- let $focusCount = 0;
421
- let $clickCount = 0;
422
+ let focusCount = track(0);
423
+ let clickCount = track(0);
422
424
 
423
425
  <button
424
- onFocus={() => $focusCount++}
425
- onClick={() => $clickCount++}
426
+ onFocus={() => { @focusCount++ }}
427
+ onClick={() => { @clickCount++ }}
426
428
  >{'Test Button'}</button>
427
- <div class='focus-count'>{$focusCount}</div>
428
- <div class='click-count'>{$clickCount}</div>
429
+ <div class='focus-count'>{@focusCount}</div>
430
+ <div class='click-count'>{@clickCount}</div>
429
431
  }
430
432
 
431
433
  render(Basic);
@@ -445,13 +447,13 @@ describe('basic', () => {
445
447
 
446
448
  it('renders with capture events', () => {
447
449
  component Basic() {
448
- let $captureClicks = 0;
449
- let $bubbleClicks = 0;
450
+ let captureClicks = track(0);
451
+ let bubbleClicks = track(0);
450
452
 
451
- <div onClickCapture={() => $captureClicks++}>
452
- <button onClick={() => $bubbleClicks++}>{'Click me'}</button>
453
- <div class='capture-count'>{$captureClicks}</div>
454
- <div class='bubble-count'>{$bubbleClicks}</div>
453
+ <div onClickCapture={() => { @captureClicks++ }}>
454
+ <button onClick={() => { @bubbleClicks++ }}>{'Click me'}</button>
455
+ <div class='capture-count'>{@captureClicks}</div>
456
+ <div class='bubble-count'>{@bubbleClicks}</div>
455
457
  </div>
456
458
  }
457
459
 
@@ -471,13 +473,13 @@ describe('basic', () => {
471
473
  it('renders with component composition and children', () => {
472
474
  component Card(props) {
473
475
  <div class='card'>
474
- <props.$children />
476
+ <props.children />
475
477
  </div>
476
478
  }
477
479
 
478
480
  component Basic() {
479
481
  <Card>
480
- component $children() {
482
+ component children() {
481
483
  <p>{'Card content here'}</p>
482
484
  }
483
485
  </Card>
@@ -494,22 +496,22 @@ describe('basic', () => {
494
496
 
495
497
  it('renders with error handling simulation', () => {
496
498
  component Basic() {
497
- let $hasError = false;
498
- let $errorMessage = '';
499
+ let hasError = track(false);
500
+ let errorMessage = track('');
499
501
 
500
502
  const triggerError = () => {
501
503
  try {
502
504
  throw new Error('Test error');
503
505
  } catch (e) {
504
- $hasError = true;
505
- $errorMessage = e.message;
506
+ @hasError = true;
507
+ @errorMessage = e.message;
506
508
  }
507
509
  };
508
510
 
509
511
  <div>
510
512
  <button onClick={triggerError}>{'Trigger Error'}</button>
511
- if ($hasError) {
512
- <div class='error'>{'Error caught: ' + $errorMessage}</div>
513
+ if (@hasError) {
514
+ <div class='error'>{'Error caught: ' + @errorMessage}</div>
513
515
  } else {
514
516
  <div class='success'>{'No error'}</div>
515
517
  }
@@ -534,12 +536,12 @@ describe('basic', () => {
534
536
 
535
537
  it('renders with computed reactive state', () => {
536
538
  component Basic() {
537
- let $count = 5;
539
+ let count = track(5);
538
540
 
539
- <div class='count'>{$count}</div>
540
- <div class='doubled'>{$count * 2}</div>
541
- <div class='is-even'>{$count % 2 === 0 ? 'Even' : 'Odd'}</div>
542
- <button onClick={() => $count++}>{'Increment'}</button>
541
+ <div class='count'>{@count}</div>
542
+ <div class='doubled'>{@count * 2}</div>
543
+ <div class='is-even'>{@count % 2 === 0 ? 'Even' : 'Odd'}</div>
544
+ <button onClick={() => { @count++ }}>{'Increment'}</button>
543
545
  }
544
546
 
545
547
  render(Basic);
@@ -577,16 +579,46 @@ describe('basic', () => {
577
579
 
578
580
  it('renders with simple reactive objects', () => {
579
581
  component Basic() {
580
- let $user = {
581
- $name: 'John',
582
- $age: 25
583
- };
582
+ let user = track({
583
+ name: 'John',
584
+ age: 25
585
+ });
586
+
587
+ <div class='name'>{@user.name}</div>
588
+ <div class='age'>{@user.age}</div>
589
+ <button onClick={() => {
590
+ @user = {...@user, name: 'Jane', age: 30}
591
+ }}>{'Update User'}</button>
592
+ }
593
+
594
+ render(Basic);
595
+
596
+ const nameDiv = container.querySelector('.name');
597
+ const ageDiv = container.querySelector('.age');
598
+ const button = container.querySelector('button');
599
+
600
+ expect(nameDiv.textContent).toBe('John');
601
+ expect(ageDiv.textContent).toBe('25');
602
+
603
+ button.click();
604
+ flushSync();
605
+
606
+ expect(nameDiv.textContent).toBe('Jane');
607
+ expect(ageDiv.textContent).toBe('30');
608
+ });
609
+
610
+ it('renders with nested reactive objects', () => {
611
+ component Basic() {
612
+ let user = track({
613
+ name: track('John'),
614
+ age: track(25)
615
+ });
584
616
 
585
- <div class='name'>{$user.$name}</div>
586
- <div class='age'>{$user.$age}</div>
617
+ <div class='name'>{@user.@name}</div>
618
+ <div class='age'>{@user.@age}</div>
587
619
  <button onClick={() => {
588
- $user.$name = 'Jane';
589
- $user.$age = 30;
620
+ @user.@name = 'Jane';
621
+ @user.@age = 30;
590
622
  }}>{'Update User'}</button>
591
623
  }
592
624
 
@@ -608,15 +640,15 @@ describe('basic', () => {
608
640
 
609
641
  it('renders with conditional rendering using if statements', () => {
610
642
  component Basic() {
611
- let $showContent = false;
612
- let $userRole = 'guest';
643
+ let showContent = track(false);
644
+ let userRole = track('guest');
613
645
 
614
- <button onClick={() => $showContent = !$showContent}>{'Toggle Content'}</button>
615
- <button onClick={() => $userRole = $userRole === 'guest' ? 'admin' : 'guest'}>{'Toggle Role'}</button>
646
+ <button onClick={() => { @showContent = !@showContent }}>{'Toggle Content'}</button>
647
+ <button onClick={() => { @userRole = @userRole === 'guest' ? 'admin' : 'guest' }}>{'Toggle Role'}</button>
616
648
 
617
649
  <div class='content'>
618
- if ($showContent) {
619
- if ($userRole === 'admin') {
650
+ if (@showContent) {
651
+ if (@userRole === 'admin') {
620
652
  <div class='admin-content'>{'Admin content'}</div>
621
653
  } else {
622
654
  <div class='user-content'>{'User content'}</div>
@@ -667,15 +699,15 @@ describe('basic', () => {
667
699
  }
668
700
 
669
701
  component Basic() {
670
- let $clicked = false;
702
+ let clicked = track(false);
671
703
 
672
704
  <Card
673
705
  title='Test Card'
674
706
  content='This is a test card'
675
707
  buttonText='Click me'
676
- onAction={() => $clicked = true}
708
+ onAction={() => @clicked = true}
677
709
  />
678
- <div class='status'>{$clicked ? 'Clicked' : 'Not clicked'}</div>
710
+ <div class='status'>{@clicked ? 'Clicked' : 'Not clicked'}</div>
679
711
  }
680
712
 
681
713
  render(Basic);
@@ -700,31 +732,31 @@ describe('basic', () => {
700
732
 
701
733
  it('renders with complex event handling and state updates', () => {
702
734
  component Basic() {
703
- let $counter = 0;
704
- let $history = [];
705
- let $isEven = true;
735
+ let counter = track(0);
736
+ let history = track([]);
737
+ let isEven = track(true);
706
738
 
707
739
  const handleIncrement = () => {
708
- $counter++;
709
- $history = [...$history, `Inc to ${$counter}`];
710
- $isEven = $counter % 2 === 0;
740
+ @counter++;
741
+ @history = [...@history, `Inc to ${@counter}`];
742
+ @isEven = @counter % 2 === 0;
711
743
  };
712
744
 
713
745
  const handleDecrement = () => {
714
- $counter--;
715
- $history = [...$history, `Dec to ${$counter}`];
716
- $isEven = $counter % 2 === 0;
746
+ @counter--;
747
+ @history = [...@history, `Dec to ${@counter}`];
748
+ @isEven = @counter % 2 === 0;
717
749
  };
718
750
 
719
751
  const handleReset = () => {
720
- $counter = 0;
721
- $history = [...$history, 'Reset'];
722
- $isEven = true;
752
+ @counter = 0;
753
+ @history = [...@history, 'Reset'];
754
+ @isEven = true;
723
755
  };
724
756
 
725
- <div class='counter'>{$counter}</div>
726
- <div class='parity'>{$isEven ? 'Even' : 'Odd'}</div>
727
- <div class='history-count'>{$history.length}</div>
757
+ <div class='counter'>{@counter}</div>
758
+ <div class='parity'>{@isEven ? 'Even' : 'Odd'}</div>
759
+ <div class='history-count'>{@history.length}</div>
728
760
 
729
761
  <button class='inc-btn' onClick={handleIncrement}>{'+'}</button>
730
762
  <button class='dec-btn' onClick={handleDecrement}>{'-'}</button>
@@ -775,18 +807,18 @@ describe('basic', () => {
775
807
 
776
808
  it('renders with reactive component props', () => {
777
809
  component ChildComponent(props) {
778
- <div class='child-content'>{props.$text}</div>
779
- <div class='child-count'>{props.$count}</div>
810
+ <div class='child-content'>{props.@text}</div>
811
+ <div class='child-count'>{props.@count}</div>
780
812
  }
781
813
 
782
814
  component Basic() {
783
- let $message = 'Hello';
784
- let $number = 1;
815
+ let message = track('Hello');
816
+ let number = track(1);
785
817
 
786
- <ChildComponent $text={$message} $count={$number} />
818
+ <ChildComponent text={message} count={number} />
787
819
  <button onClick={() => {
788
- $message = $message === 'Hello' ? 'Goodbye' : 'Hello';
789
- $number++;
820
+ @message = @message === 'Hello' ? 'Goodbye' : 'Hello';
821
+ @number++;
790
822
  }}>{'Update Props'}</button>
791
823
  }
792
824
 
@@ -850,16 +882,16 @@ describe('basic', () => {
850
882
 
851
883
  it('renders with mixed static and dynamic content', () => {
852
884
  component Basic() {
853
- let $name = 'World';
854
- let $count = 0;
885
+ let name = track('World');
886
+ let count = track(0);
855
887
  const staticMessage = 'Welcome to Ripple!';
856
888
 
857
889
  <div class='mixed-content'>
858
890
  <h1>{staticMessage}</h1>
859
- <p class='greeting'>{'Hello, ' + $name + '!'}</p>
860
- <p class='notifications'>{'You have ' + $count + ' notifications'}</p>
861
- <button onClick={() => $count++}>{'Add Notification'}</button>
862
- <button onClick={() => $name = $name === 'World' ? 'User' : 'World'}>{'Toggle Name'}</button>
891
+ <p class='greeting'>{'Hello, ' + @name + '!'}</p>
892
+ <p class='notifications'>{'You have ' + @count + ' notifications'}</p>
893
+ <button onClick={() => { @count++ }}>{'Add Notification'}</button>
894
+ <button onClick={() => { @name = @name === 'World' ? 'User' : 'World' }}>{'Toggle Name'}</button>
863
895
  </div>
864
896
  }
865
897
 
@@ -885,14 +917,14 @@ describe('basic', () => {
885
917
 
886
918
  it('renders with reactive attributes with nested reactive attributes', () => {
887
919
  component App() {
888
- let $value = 'parent-class';
920
+ let value = track('parent-class');
889
921
 
890
- <p $class={$value}>{'Colored parent value'}</p>
922
+ <p class={@value}>{'Colored parent value'}</p>
891
923
 
892
924
  <div>
893
- let $nested = 'nested-class';
925
+ let nested = track('nested-class');
894
926
 
895
- <p $class={$nested}>{'Colored nested value'}</p>
927
+ <p class={@nested}>{'Colored nested value'}</p>
896
928
  </div>
897
929
  }
898
930
 
@@ -927,35 +959,35 @@ describe('basic', () => {
927
959
  let logs = [];
928
960
 
929
961
  component App() {
930
- let $first = 0;
931
- let $second = 0;
932
- const arr = [$first, $second];
962
+ let first = track(0);
963
+ let second = track(0);
964
+ const arr = [first, second];
933
965
 
934
- const $total = arr.reduce((a, b) => a + b, 0);
966
+ const total = track(() => arr.reduce((a, b) => a + @b, 0));
935
967
 
936
- <button onClick={() => { $first++; }}>{'first:' + $first}</button>
937
- <button onClick={() => { $second++; }}>{'second: ' + $second}</button>
968
+ <button onClick={() => { @first++; }}>{'first:' + @first}</button>
969
+ <button onClick={() => { @second++; }}>{'second: ' + @second}</button>
938
970
 
939
971
  effect(() => {
940
972
  let _arr = [];
941
973
 
942
974
  arr.forEach((item) => {
943
- _arr.push(item);
975
+ _arr.push(@item);
944
976
  });
945
977
 
946
978
  logs.push(_arr.join(', '));
947
979
  });
948
980
 
949
981
  effect(() => {
950
- if (arr.includes(1)) {
982
+ if (arr.map(a => @a).includes(1)) {
951
983
  logs.push('arr includes 1');
952
984
  }
953
985
  });
954
986
 
955
- <div>{'Sum: ' + $total}</div>
956
- <div>{'Comma Separated: ' + arr.join(', ')}</div>
957
- <div>{'Number to string: ' + arr.map(a => String(a))}</div>
958
- <div>{'Even numbers: ' + arr.filter(a => a % 2 === 0)}</div>
987
+ <div>{'Sum: ' + @total}</div>
988
+ <div>{'Comma Separated: ' + arr.map(a => @a).join(', ')}</div>
989
+ <div>{'Number to string: ' + arr.map(a => String(@a))}</div>
990
+ <div>{'Even numbers: ' + arr.map(a => @a).filter(a => a % 2 === 0)}</div>
959
991
  }
960
992
 
961
993
  render(App);
@@ -986,22 +1018,22 @@ describe('basic', () => {
986
1018
  expect(divs[1].textContent).toBe('Comma Separated: 1, 1');
987
1019
  expect(divs[2].textContent).toBe('Number to string: 1,1');
988
1020
  expect(divs[3].textContent).toBe('Even numbers: ');
989
- expect(logs).toEqual(['0, 0', '1, 0', 'arr includes 1', '1, 1']);
1021
+ expect(logs).toEqual(['0, 0', '1, 0', 'arr includes 1', '1, 1', 'arr includes 1']);
990
1022
  });
991
1023
 
992
1024
  it('it retains this context with bracketed prop functions and keeps original chaining', () => {
993
1025
  component App() {
994
1026
  const SYMBOL_PROP = Symbol();
995
- let $hasError = false;
1027
+ let hasError = track(false);
996
1028
  const obj = {
997
- $count: 0,
1029
+ count: track(0),
998
1030
  increment() {
999
- this.$count++;
1031
+ this.@count++;
1000
1032
  },
1001
1033
  [SYMBOL_PROP]() {
1002
- this.$count++;
1034
+ this.@count++;
1003
1035
  },
1004
- arr: [() => obj.$count++, () => obj.$count--],
1036
+ arr: [() => obj.@count++, () => obj.@count--],
1005
1037
  };
1006
1038
 
1007
1039
  const obj2 = null;
@@ -1010,48 +1042,48 @@ describe('basic', () => {
1010
1042
  <button onClick={() => obj[SYMBOL_PROP]()}>{'Increment'}</button>
1011
1043
  <button
1012
1044
  onClick={() => {
1013
- $hasError = false;
1045
+ @hasError = false;
1014
1046
  try {
1015
1047
  obj['nonexistent']();
1016
1048
  } catch {
1017
- $hasError = true;
1049
+ @hasError = true;
1018
1050
  }
1019
1051
  }}
1020
1052
  >{'Nonexistent'}</button>
1021
1053
  <button
1022
1054
  onClick={() => {
1023
- $hasError = false;
1055
+ @hasError = false;
1024
1056
  try {
1025
1057
  obj['nonexistent']?.();
1026
1058
  } catch {
1027
- $hasError = true;
1059
+ @hasError = true;
1028
1060
  }
1029
1061
  }}
1030
1062
  >{'Nonexistent chaining'}</button>
1031
1063
  <button
1032
1064
  onClick={() => {
1033
- $hasError = false;
1065
+ @hasError = false;
1034
1066
  try {
1035
1067
  obj2['nonexistent']();
1036
1068
  } catch {
1037
- $hasError = true;
1069
+ @hasError = true;
1038
1070
  }
1039
1071
  }}
1040
1072
  >{'Object null'}</button>
1041
1073
  <button
1042
1074
  onClick={() => {
1043
- $hasError = false;
1075
+ @hasError = false;
1044
1076
  try {
1045
1077
  obj2?.['nonexistent']?.();
1046
1078
  } catch {
1047
- $hasError = true;
1079
+ @hasError = true;
1048
1080
  }
1049
1081
  }}
1050
1082
  >{'Object null chained'}</button>
1051
1083
  <button onClick={() => obj.arr[obj.arr.length - 1]()}>{'BinaryExpression prop'}</button>
1052
1084
 
1053
- <span>{obj.$count}</span>
1054
- <span>{$hasError}</span>
1085
+ <span>{obj.@count}</span>
1086
+ <span>{@hasError}</span>
1055
1087
  }
1056
1088
 
1057
1089
  render(App);