ripple 0.3.127 → 0.4.0

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.
Files changed (192) hide show
  1. package/CHANGELOG.md +293 -0
  2. package/package.json +10 -4
  3. package/src/runtime/element.js +23 -6
  4. package/src/runtime/index-client.js +81 -41
  5. package/src/runtime/index-server.js +1 -0
  6. package/src/runtime/internal/client/blocks.js +192 -114
  7. package/src/runtime/internal/client/component.js +4 -30
  8. package/src/runtime/internal/client/composite.js +12 -13
  9. package/src/runtime/internal/client/constants.js +14 -5
  10. package/src/runtime/internal/client/context.js +12 -19
  11. package/src/runtime/internal/client/css.js +7 -9
  12. package/src/runtime/internal/client/events.js +178 -90
  13. package/src/runtime/internal/client/expression.js +185 -124
  14. package/src/runtime/internal/client/for.js +616 -264
  15. package/src/runtime/internal/client/head.js +10 -5
  16. package/src/runtime/internal/client/html.js +1 -0
  17. package/src/runtime/internal/client/hydration.js +152 -10
  18. package/src/runtime/internal/client/if.js +239 -50
  19. package/src/runtime/internal/client/index.js +9 -13
  20. package/src/runtime/internal/client/operations.js +44 -51
  21. package/src/runtime/internal/client/portal.js +163 -85
  22. package/src/runtime/internal/client/render.js +44 -25
  23. package/src/runtime/internal/client/rpc.js +3 -3
  24. package/src/runtime/internal/client/runtime.js +799 -576
  25. package/src/runtime/internal/client/selector.js +77 -0
  26. package/src/runtime/internal/client/template.js +133 -158
  27. package/src/runtime/internal/client/transport.js +38 -0
  28. package/src/runtime/internal/client/try.js +465 -426
  29. package/src/runtime/internal/client/types.d.ts +65 -21
  30. package/src/runtime/internal/client/utils.js +1 -3
  31. package/src/runtime/internal/server/dynamic.js +20 -21
  32. package/src/runtime/internal/server/index.js +327 -275
  33. package/src/runtime/internal/server/rpc.js +3 -2
  34. package/src/runtime/internal/server/transport.js +16 -0
  35. package/src/runtime/transport.js +21 -0
  36. package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
  37. package/tests/client/array/array.copy-within.test.tsrx +12 -12
  38. package/tests/client/array/array.derived.test.tsrx +46 -46
  39. package/tests/client/array/array.iteration.test.tsrx +10 -10
  40. package/tests/client/array/array.mutations.test.tsrx +20 -20
  41. package/tests/client/array/array.static.test.tsrx +11 -11
  42. package/tests/client/array/array.to-methods.test.tsrx +6 -6
  43. package/tests/client/async-suspend.test.tsrx +74 -75
  44. package/tests/client/basic/basic.attributes.test.tsrx +86 -83
  45. package/tests/client/basic/basic.collections.test.tsrx +12 -12
  46. package/tests/client/basic/basic.components.test.tsrx +99 -25
  47. package/tests/client/basic/basic.errors.test.tsrx +18 -18
  48. package/tests/client/basic/basic.events.test.tsrx +42 -42
  49. package/tests/client/basic/basic.get-set.test.tsrx +8 -8
  50. package/tests/client/basic/basic.reactivity.test.tsrx +97 -29
  51. package/tests/client/basic/basic.rendering.test.tsrx +25 -25
  52. package/tests/client/basic/basic.utilities.test.tsrx +3 -3
  53. package/tests/client/boundaries.test.tsrx +8 -8
  54. package/tests/client/boxed-locals.test.tsrx +452 -0
  55. package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
  56. package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
  57. package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
  58. package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
  59. package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
  60. package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
  61. package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
  62. package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
  63. package/tests/client/composite/composite.props.test.tsrx +149 -12
  64. package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
  65. package/tests/client/composite/composite.render.test.tsrx +26 -9
  66. package/tests/client/css/scoped-styles.test.tsrx +8 -8
  67. package/tests/client/date.test.tsrx +42 -42
  68. package/tests/client/derived-release.test.tsrx +370 -0
  69. package/tests/client/dynamic-elements.test.tsrx +45 -45
  70. package/tests/client/events.test.tsrx +97 -71
  71. package/tests/client/for-selector.test.tsrx +221 -0
  72. package/tests/client/for-single-root-items.test.tsrx +118 -3
  73. package/tests/client/for.test.tsrx +332 -31
  74. package/tests/client/head.test.tsrx +19 -19
  75. package/tests/client/html.test.tsrx +11 -9
  76. package/tests/client/if-block.test.tsrx +80 -0
  77. package/tests/client/map.test.tsrx +16 -16
  78. package/tests/client/media-query.test.tsrx +7 -7
  79. package/tests/client/portal.test.tsrx +224 -26
  80. package/tests/client/primitive-text.test.tsrx +50 -0
  81. package/tests/client/prop-kind-switch.test.tsrx +141 -0
  82. package/tests/client/ref.test.tsrx +17 -17
  83. package/tests/client/return.test.tsrx +26 -3
  84. package/tests/client/root-boundary.test.tsrx +42 -0
  85. package/tests/client/scoped-flush.test.tsrx +8 -8
  86. package/tests/client/set.test.tsrx +6 -6
  87. package/tests/client/svg.test.tsrx +11 -11
  88. package/tests/client/switch.test.tsrx +44 -44
  89. package/tests/client/track-async-hydration.test.tsrx +4 -4
  90. package/tests/client/try.test.tsrx +151 -83
  91. package/tests/client/tsx.test.tsrx +43 -40
  92. package/tests/client/url/url.derived.test.tsrx +6 -6
  93. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
  95. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
  96. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
  97. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
  98. package/tests/hydration/basic.test.js +74 -1
  99. package/tests/hydration/build-components.js +22 -1
  100. package/tests/hydration/compiled/client/basic.js +1142 -713
  101. package/tests/hydration/compiled/client/composite.js +151 -100
  102. package/tests/hydration/compiled/client/events.js +190 -150
  103. package/tests/hydration/compiled/client/for.js +1472 -1126
  104. package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
  105. package/tests/hydration/compiled/client/head.js +255 -199
  106. package/tests/hydration/compiled/client/hmr.js +54 -41
  107. package/tests/hydration/compiled/client/html-in-template.js +54 -39
  108. package/tests/hydration/compiled/client/html.js +1633 -1263
  109. package/tests/hydration/compiled/client/if-children.js +420 -270
  110. package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
  111. package/tests/hydration/compiled/client/if.js +229 -219
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +420 -400
  113. package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1255
  114. package/tests/hydration/compiled/client/portal.js +87 -95
  115. package/tests/hydration/compiled/client/reactivity.js +140 -83
  116. package/tests/hydration/compiled/client/return.js +28 -19
  117. package/tests/hydration/compiled/client/streaming.js +390 -306
  118. package/tests/hydration/compiled/client/switch.js +258 -266
  119. package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
  120. package/tests/hydration/compiled/client/try.js +173 -129
  121. package/tests/hydration/compiled/client/typed-text.js +71 -0
  122. package/tests/hydration/compiled/fixtures/money.js +10 -0
  123. package/tests/hydration/compiled/server/basic.js +123 -6
  124. package/tests/hydration/compiled/server/composite.js +16 -30
  125. package/tests/hydration/compiled/server/events.js +19 -19
  126. package/tests/hydration/compiled/server/for.js +109 -49
  127. package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
  128. package/tests/hydration/compiled/server/head.js +20 -28
  129. package/tests/hydration/compiled/server/hmr.js +2 -2
  130. package/tests/hydration/compiled/server/html.js +71 -247
  131. package/tests/hydration/compiled/server/if-children.js +107 -15
  132. package/tests/hydration/compiled/server/if.js +11 -15
  133. package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
  134. package/tests/hydration/compiled/server/portal.js +14 -22
  135. package/tests/hydration/compiled/server/reactivity.js +14 -46
  136. package/tests/hydration/compiled/server/streaming.js +19 -19
  137. package/tests/hydration/compiled/server/switch.js +8 -8
  138. package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
  139. package/tests/hydration/compiled/server/try.js +8 -8
  140. package/tests/hydration/compiled/server/typed-text.js +17 -0
  141. package/tests/hydration/components/basic.tsrx +44 -8
  142. package/tests/hydration/components/composite.tsrx +2 -2
  143. package/tests/hydration/components/events.tsrx +25 -25
  144. package/tests/hydration/components/for.tsrx +115 -67
  145. package/tests/hydration/components/fragment-cursor.tsrx +650 -0
  146. package/tests/hydration/components/head.tsrx +16 -16
  147. package/tests/hydration/components/hmr.tsrx +2 -2
  148. package/tests/hydration/components/html.tsrx +7 -7
  149. package/tests/hydration/components/if-children.tsrx +72 -25
  150. package/tests/hydration/components/if.tsrx +18 -18
  151. package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
  152. package/tests/hydration/components/portal.tsrx +3 -3
  153. package/tests/hydration/components/reactivity.tsrx +16 -16
  154. package/tests/hydration/components/streaming.tsrx +20 -20
  155. package/tests/hydration/components/switch.tsrx +20 -20
  156. package/tests/hydration/components/text-types.ts +4 -0
  157. package/tests/hydration/components/track-async-serialization.tsrx +80 -26
  158. package/tests/hydration/components/try.tsrx +8 -8
  159. package/tests/hydration/components/typed-text.tsrx +22 -0
  160. package/tests/hydration/fixtures/money.js +10 -0
  161. package/tests/hydration/for.test.js +36 -0
  162. package/tests/hydration/fragment-cursor.test.js +111 -0
  163. package/tests/hydration/if-children.test.js +24 -0
  164. package/tests/hydration/streaming.test.js +19 -0
  165. package/tests/hydration/track-async-serialization.test.js +87 -2
  166. package/tests/hydration/tsconfig.text-types.json +10 -0
  167. package/tests/hydration/typed-text.test.js +34 -0
  168. package/tests/server/await.test.tsrx +3 -3
  169. package/tests/server/basic.attributes.test.tsrx +42 -42
  170. package/tests/server/basic.components.test.tsrx +64 -8
  171. package/tests/server/basic.test.tsrx +34 -32
  172. package/tests/server/compiler.test.tsrx +1 -70
  173. package/tests/server/composite.props.test.tsrx +6 -6
  174. package/tests/server/dynamic-elements.test.tsrx +31 -8
  175. package/tests/server/for.test.tsrx +94 -0
  176. package/tests/server/head.test.tsrx +11 -11
  177. package/tests/server/scoped-styles.test.tsrx +2 -2
  178. package/tests/server/streaming-ssr.test.tsrx +48 -43
  179. package/tests/server/track-async-serialization.test.tsrx +204 -21
  180. package/tests/server/try.test.tsrx +48 -48
  181. package/tests/types/transport.ts +40 -0
  182. package/tests/utils/vite-plugin-config.test.js +23 -0
  183. package/types/index.d.ts +48 -7
  184. package/types/server.d.ts +3 -0
  185. package/types/transport.d.ts +15 -0
  186. package/src/runtime/internal/client/switch.js +0 -113
  187. package/src/utils/errors.js +0 -13
  188. package/tests/client/lazy-array.test.tsrx +0 -31
  189. package/tests/client/lazy-destructuring.test.tsrx +0 -438
  190. package/tests/client/tracked-index-access.test.tsrx +0 -113
  191. package/tests/server/lazy-destructuring.test.tsrx +0 -595
  192. package/tests/server/tracked-index-access.test.tsrx +0 -76
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ Derived,
2
3
  Tracked,
3
4
  PropsWithChildren,
4
5
  PropsWithExtras,
@@ -74,11 +75,11 @@ describe('basic client > components & composition', () => {
74
75
  }
75
76
 
76
77
  function Basic() @{
77
- let &[test] = track(false);
78
+ const test = track(false);
78
79
  <>
79
80
  <Card test={TestSlot} />
80
81
  <div>
81
- {test ? 'yes' : 'no'}
82
+ {test.value ? 'yes' : 'no'}
82
83
  </div>
83
84
  </>
84
85
  }
@@ -210,16 +211,16 @@ describe('basic client > components & composition', () => {
210
211
  }
211
212
 
212
213
  function Basic() @{
213
- let &[clicked] = track(false);
214
+ const clicked = track(false);
214
215
  <>
215
216
  <Card
216
217
  title="Test Card"
217
218
  content="This is a test card"
218
219
  buttonText="Click me"
219
- onAction={() => (clicked = true)}
220
+ onAction={() => (clicked.value = true)}
220
221
  />
221
222
  <div class="status">
222
- {clicked ? 'Clicked' : 'Not clicked'}
223
+ {clicked.value ? 'Clicked' : 'Not clicked'}
223
224
  </div>
224
225
  </>
225
226
  }
@@ -256,14 +257,14 @@ describe('basic client > components & composition', () => {
256
257
  }
257
258
 
258
259
  function Basic() @{
259
- let &[message, messageTracked] = track('Hello');
260
- let &[number, numberTracked] = track(1);
260
+ const message = track('Hello');
261
+ const number = track(1);
261
262
  <>
262
- <ChildComponent text={messageTracked} count={numberTracked} />
263
+ <ChildComponent text={message} count={number} />
263
264
  <button
264
265
  onClick={() => {
265
- message = message === 'Hello' ? 'Goodbye' : 'Hello';
266
- number++;
266
+ message.value = message.value === 'Hello' ? 'Goodbye' : 'Hello';
267
+ number.value++;
267
268
  }}
268
269
  >{'Update Props'}</button>
269
270
  </>
@@ -292,15 +293,15 @@ describe('basic client > components & composition', () => {
292
293
  });
293
294
 
294
295
  it('updates explicit text children props reactively', () => {
295
- function TextProp(&{ children }: PropsWithChildren<{}>) @{
296
- <div class="text-prop">{children}</div>
296
+ function TextProp({ children }: { children: Derived<string> }) @{
297
+ <div class="text-prop">{children.value}</div>
297
298
  }
298
299
 
299
300
  function Basic() @{
300
- let &[show] = track(false);
301
+ const show = track(false);
301
302
  <>
302
- <TextProp children={show ? 'hello' : ''} />
303
- <button class="show-text" onClick={() => (show = true)}>{'Show'}</button>
303
+ <TextProp children={track(() => (show.value ? 'hello' : ''))} />
304
+ <button class="show-text" onClick={() => (show.value = true)}>{'Show'}</button>
304
305
  </>
305
306
  }
306
307
 
@@ -317,7 +318,7 @@ describe('basic client > components & composition', () => {
317
318
  it('it retains this context with bracketed prop functions and keeps original chaining', () => {
318
319
  function App() @{
319
320
  const SYMBOL_PROP = Symbol();
320
- let &[hasError] = track(false);
321
+ const hasError = track(false);
321
322
  const obj: {
322
323
  count: Tracked<number>;
323
324
  increment: () => void;
@@ -337,28 +338,28 @@ describe('basic client > components & composition', () => {
337
338
  const obj2 = null;
338
339
 
339
340
  function trigger_nonexistent() {
340
- hasError = did_error(() => {
341
+ hasError.value = did_error(() => {
341
342
  // @ts-ignore
342
343
  obj['nonexistent']();
343
344
  });
344
345
  }
345
346
 
346
347
  function trigger_nonexistent_chaining() {
347
- hasError = did_error(() => {
348
+ hasError.value = did_error(() => {
348
349
  // @ts-ignore
349
350
  obj['nonexistent']?.();
350
351
  });
351
352
  }
352
353
 
353
354
  function trigger_object_null() {
354
- hasError = did_error(() => {
355
+ hasError.value = did_error(() => {
355
356
  // @ts-ignore
356
357
  obj2['nonexistent']();
357
358
  });
358
359
  }
359
360
 
360
361
  function trigger_object_null_chained() {
361
- hasError = did_error(() => {
362
+ hasError.value = did_error(() => {
362
363
  // @ts-ignore
363
364
  obj2?.['nonexistent']?.();
364
365
  });
@@ -373,7 +374,7 @@ describe('basic client > components & composition', () => {
373
374
  <button onClick={trigger_object_null_chained}>{'Object null chained'}</button>
374
375
  <button onClick={() => obj.arr[obj.arr.length - 1]()}>{'BinaryExpression prop'}</button>
375
376
  <span>{obj.count.value}</span>
376
- <span>{hasError}</span>
377
+ <span>{hasError.value}</span>
377
378
  </>
378
379
  }
379
380
 
@@ -501,10 +502,10 @@ describe('basic client > components & composition', () => {
501
502
  }
502
503
 
503
504
  function App() @{
504
- let &[Content] = track(() => Noop);
505
+ const Content = track(() => Noop, undefined, true);
505
506
  <>
506
- <{Content} />
507
- <button onClick={() => (Content = Op)}>{'Show Op'}</button>
507
+ <{Content.value} />
508
+ <button onClick={() => (Content.value = Op)}>{'Show Op'}</button>
508
509
  </>
509
510
  }
510
511
 
@@ -648,7 +649,7 @@ describe('basic client > components & composition', () => {
648
649
  <div class="z">{'I am Z'}</div>
649
650
  }
650
651
 
651
- function Child(&{ Z }: { Z: Component }) @{
652
+ function Child({ Z }: { Z: Component }) @{
652
653
  <div class="child">
653
654
  {'Child Component: '}
654
655
  <Z />
@@ -666,3 +667,76 @@ describe('basic client > components & composition', () => {
666
667
  expect(container.querySelector('.wrapper .z').textContent).toBe('I am Z');
667
668
  });
668
669
  });
670
+
671
+ describe('all-component children', () => {
672
+ // Children that are all static components render into their parent through
673
+ // an append-into sentinel instead of a `<!>` placeholder per child. A child
674
+ // whose root is control flow must still re-render at its own position.
675
+ it('re-renders a root @if child in place, before its siblings', () => {
676
+ function Toggle(props: { on: Tracked<boolean> }) @{
677
+ @if (props.on.value) {
678
+ <span>{'A'}</span>
679
+ } @else {
680
+ <span>{'a'}</span>
681
+ }
682
+ }
683
+
684
+ function Trailing() @{
685
+ <span>{'B'}</span>
686
+ }
687
+
688
+ function App() @{
689
+ const on = track(true);
690
+ <>
691
+ <div class="host">
692
+ <Toggle on={on} />
693
+ <Trailing />
694
+ </div>
695
+ <button onClick={() => (on.value = !on.value)}>{'Toggle'}</button>
696
+ </>
697
+ }
698
+
699
+ render(App);
700
+
701
+ const host = container.querySelector('.host');
702
+ expect(host.textContent).toBe('AB');
703
+
704
+ container.querySelector('button').click();
705
+ flushSync();
706
+ expect(host.textContent).toBe('aB');
707
+ });
708
+
709
+ it('moves a root keyed @for child item to the end of its own list', () => {
710
+ function List(props: { items: Tracked<number[]> }) @{
711
+ @for (const item of props.items.value; key item) {
712
+ <span>{item}</span>
713
+ }
714
+ }
715
+
716
+ function Trailing() @{
717
+ <span>{'end'}</span>
718
+ }
719
+
720
+ function App() @{
721
+ const items = track([1, 2, 3]);
722
+ <>
723
+ <div class="host">
724
+ <List items={items} />
725
+ <Trailing />
726
+ </div>
727
+ <button
728
+ onClick={() => (items.value = [items.value[1], items.value[2], items.value[0]])}
729
+ >{'Rotate'}</button>
730
+ </>
731
+ }
732
+
733
+ render(App);
734
+
735
+ const host = container.querySelector('.host');
736
+ expect(host.textContent).toBe('123end');
737
+
738
+ container.querySelector('button').click();
739
+ flushSync();
740
+ expect(host.textContent).toBe('231end');
741
+ });
742
+ });
@@ -4,20 +4,20 @@ import { compile } from '@tsrx/ripple';
4
4
  describe('basic client > errors', () => {
5
5
  it('renders with error handling simulation', () => {
6
6
  function Basic() @{
7
- let &[hasError] = track(false);
8
- let &[errorMessage] = track('');
7
+ const hasError = track(false);
8
+ const errorMessage = track('');
9
9
  const triggerError = () => {
10
10
  try {
11
11
  throw new Error('Test error');
12
12
  } catch (e) {
13
- hasError = true;
14
- errorMessage = (e as Error).message;
13
+ hasError.value = true;
14
+ errorMessage.value = (e as Error).message;
15
15
  }
16
16
  };
17
17
  <div>
18
18
  <button onClick={triggerError}>{'Trigger Error'}</button>
19
- @if (hasError) {
20
- <div class="error">{'Error caught: ' + errorMessage}</div>
19
+ @if (hasError.value) {
20
+ <div class="error">{'Error caught: ' + errorMessage.value}</div>
21
21
  } @else {
22
22
  <div class="success">{'No error'}</div>
23
23
  }
@@ -113,15 +113,15 @@ describe('basic client > errors', () => {
113
113
 
114
114
  it('errors on mutating tracked value inside computed track() evaluation', () => {
115
115
  function Basic() @{
116
- let &[count] = track(0);
117
- const &[doubled] = track(() => {
116
+ const count = track(0);
117
+ const doubled = track(() => {
118
118
  try {
119
- count *= 2;
119
+ count.value *= 2;
120
120
  } catch (e) {
121
121
  error = (e as Error).message;
122
122
  }
123
123
  });
124
- <p>{doubled}</p>
124
+ <p>{doubled.value}</p>
125
125
  }
126
126
 
127
127
  render(Basic);
@@ -133,17 +133,17 @@ describe('basic client > errors', () => {
133
133
 
134
134
  it('errors on mutating tracked value inside untrack() in computed track() evaluation', () => {
135
135
  function Basic() @{
136
- let &[count] = track(0);
137
- const &[doubled] = track(() => {
136
+ const count = track(0);
137
+ const doubled = track(() => {
138
138
  try {
139
139
  untrack(() => {
140
- count *= 2;
140
+ count.value *= 2;
141
141
  });
142
142
  } catch (e) {
143
143
  error = (e as Error).message;
144
144
  }
145
145
  });
146
- <p>{doubled}</p>
146
+ <p>{doubled.value}</p>
147
147
  }
148
148
 
149
149
  render(Basic);
@@ -155,16 +155,16 @@ describe('basic client > errors', () => {
155
155
 
156
156
  it('errors on mutating a tracked variable in track() getter', () => {
157
157
  function Basic() @{
158
- let &[count] = track(0);
159
- const &[doubled] = track(0, (value) => {
158
+ const count = track(0);
159
+ const doubled = track(0, (value) => {
160
160
  try {
161
- count += 1;
161
+ count.value += 1;
162
162
  } catch (e) {
163
163
  error = (e as Error).message;
164
164
  }
165
165
  return value;
166
166
  });
167
- <p>{doubled}</p>
167
+ <p>{doubled.value}</p>
168
168
  }
169
169
 
170
170
  render(Basic);
@@ -4,19 +4,19 @@ import { flushSync, track } from 'ripple';
4
4
  describe('basic client > events', () => {
5
5
  it('renders with different event types', () => {
6
6
  function Basic() @{
7
- let &[focusCount] = track(0);
8
- let &[clickCount] = track(0);
7
+ const focusCount = track(0);
8
+ const clickCount = track(0);
9
9
  <>
10
10
  <button
11
11
  onFocus={() => {
12
- focusCount++;
12
+ focusCount.value++;
13
13
  }}
14
14
  onClick={() => {
15
- clickCount++;
15
+ clickCount.value++;
16
16
  }}
17
17
  >{'Test Button'}</button>
18
- <div class="focus-count">{focusCount}</div>
19
- <div class="click-count">{clickCount}</div>
18
+ <div class="focus-count">{focusCount.value}</div>
19
+ <div class="click-count">{clickCount.value}</div>
20
20
  </>
21
21
  }
22
22
 
@@ -37,24 +37,24 @@ describe('basic client > events', () => {
37
37
 
38
38
  it('renders with capture events', () => {
39
39
  function Basic() @{
40
- let &[captureClicks] = track(0);
41
- let &[bubbleClicks] = track(0);
40
+ const captureClicks = track(0);
41
+ const bubbleClicks = track(0);
42
42
  <>
43
43
  <div
44
44
  onClick={{
45
45
  handleEvent: () => {
46
- captureClicks++;
46
+ captureClicks.value++;
47
47
  },
48
48
  capture: true,
49
49
  }}
50
50
  >
51
51
  <button
52
52
  onClick={() => {
53
- bubbleClicks++;
53
+ bubbleClicks.value++;
54
54
  }}
55
55
  >{'Click me'}</button>
56
- <div class="capture-count">{captureClicks}</div>
57
- <div class="bubble-count">{bubbleClicks}</div>
56
+ <div class="capture-count">{captureClicks.value}</div>
57
+ <div class="bubble-count">{bubbleClicks.value}</div>
58
58
  </div>
59
59
  </>
60
60
  }
@@ -74,20 +74,20 @@ describe('basic client > events', () => {
74
74
 
75
75
  it('renders with event listeners in spread props', () => {
76
76
  function Basic() @{
77
- let &[count] = track(0);
77
+ const count = track(0);
78
78
  const minus = {
79
79
  onClick() {
80
- count--;
80
+ count.value--;
81
81
  },
82
82
  };
83
83
  const plus = {
84
84
  onClick() {
85
- count++;
85
+ count.value++;
86
86
  },
87
87
  };
88
88
  <div>
89
89
  <button {...minus} class="minus">{'-'}</button>
90
- <span class="count">{count}</span>
90
+ <span class="count">{count.value}</span>
91
91
  <button {...plus} class="plus">{'+'}</button>
92
92
  </div>
93
93
  }
@@ -120,15 +120,15 @@ describe('basic client > events', () => {
120
120
 
121
121
  it('removes event listeners from spread props when they are replaced by another prop', () => {
122
122
  function Basic() @{
123
- let &[enabled] = track(true);
124
- let &[count] = track(0);
123
+ const enabled = track(true);
124
+ const count = track(0);
125
125
  <>
126
126
  <button
127
127
  class="target"
128
- {...(enabled ? { onClick: () => count++ } : { title: 'disabled' })}
128
+ {...(enabled.value ? { onClick: () => count.value++ } : { title: 'disabled' })}
129
129
  >{'target'}</button>
130
- <button class="toggle" onClick={() => (enabled = false)}>{'toggle'}</button>
131
- <span class="count">{count}</span>
130
+ <button class="toggle" onClick={() => (enabled.value = false)}>{'toggle'}</button>
131
+ <span class="count">{count.value}</span>
132
132
  </>
133
133
  }
134
134
 
@@ -152,22 +152,22 @@ describe('basic client > events', () => {
152
152
 
153
153
  it('handles both delegated and non-delegated events in spread props', () => {
154
154
  function Basic() @{
155
- let &[clickCount] = track(0);
156
- let &[focusCount] = track(0);
155
+ const clickCount = track(0);
156
+ const focusCount = track(0);
157
157
  const mixedHandler = {
158
158
  onClick() {
159
159
  // Delegated event
160
- clickCount++;
160
+ clickCount.value++;
161
161
  },
162
162
  onFocus() {
163
163
  // Non-delegated event
164
- focusCount++;
164
+ focusCount.value++;
165
165
  },
166
166
  };
167
167
  <div>
168
168
  <button {...mixedHandler} class="mixed-button">{'Test'}</button>
169
- <span class="click-count">{clickCount}</span>
170
- <span class="focus-count">{focusCount}</span>
169
+ <span class="click-count">{clickCount.value}</span>
170
+ <span class="focus-count">{focusCount.value}</span>
171
171
  </div>
172
172
  }
173
173
 
@@ -193,30 +193,30 @@ describe('basic client > events', () => {
193
193
 
194
194
  it('renders with complex event handling and state updates', () => {
195
195
  function Basic() @{
196
- let &[counter] = track(0);
197
- let &[history] = track<string[]>([]);
198
- let &[isEven] = track(true);
196
+ const counter = track(0);
197
+ const history = track<string[]>([]);
198
+ const isEven = track(true);
199
199
  const handleIncrement = () => {
200
- counter++;
201
- history = [...history, `Inc to ${counter}`];
202
- isEven = counter % 2 === 0;
200
+ counter.value++;
201
+ history.value = [...history.value, `Inc to ${counter.value}`];
202
+ isEven.value = counter.value % 2 === 0;
203
203
  };
204
204
  const handleDecrement = () => {
205
- counter--;
206
- history = [...history, `Dec to ${counter}`];
207
- isEven = counter % 2 === 0;
205
+ counter.value--;
206
+ history.value = [...history.value, `Dec to ${counter.value}`];
207
+ isEven.value = counter.value % 2 === 0;
208
208
  };
209
209
  const handleReset = () => {
210
- counter = 0;
211
- history = [...history, 'Reset'];
212
- isEven = true;
210
+ counter.value = 0;
211
+ history.value = [...history.value, 'Reset'];
212
+ isEven.value = true;
213
213
  };
214
214
  <>
215
- <div class="counter">{counter}</div>
215
+ <div class="counter">{counter.value}</div>
216
216
  <div class="parity">
217
- {isEven ? 'Even' : 'Odd'}
217
+ {isEven.value ? 'Even' : 'Odd'}
218
218
  </div>
219
- <div class="history-count">{history.length}</div>
219
+ <div class="history-count">{history.value.length}</div>
220
220
  <button class="inc-btn" onClick={handleIncrement}>{'+'}</button>
221
221
  <button class="dec-btn" onClick={handleDecrement}>{'-'}</button>
222
222
  <button class="reset-btn" onClick={handleReset}>{'Reset'}</button>
@@ -15,10 +15,10 @@ describe('basic client > tracked value access', () => {
15
15
 
16
16
  it('gets tracked value after mutation', () => {
17
17
  function Test() @{
18
- let &[count] = track(0);
18
+ const count = track(0);
19
19
  <>
20
- <p>{count}</p>
21
- <button onClick={() => count++}>{'increment'}</button>
20
+ <p>{count.value}</p>
21
+ <button onClick={() => count.value++}>{'increment'}</button>
22
22
  </>
23
23
  }
24
24
 
@@ -36,14 +36,14 @@ describe('basic client > tracked value access', () => {
36
36
 
37
37
  it('gets tracked value after multiple mutations', () => {
38
38
  function Test() @{
39
- let &[count] = track(0);
39
+ const count = track(0);
40
40
  <>
41
- <p>{count}</p>
41
+ <p>{count.value}</p>
42
42
  <button
43
43
  onClick={() => {
44
- count++;
45
- count++;
46
- count++;
44
+ count.value++;
45
+ count.value++;
46
+ count.value++;
47
47
  }}
48
48
  >{'increment'}</button>
49
49
  </>