ripple 0.3.3 → 0.3.4

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 (126) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/package.json +2 -2
  3. package/src/compiler/identifier-utils.js +1 -8
  4. package/src/compiler/phases/1-parse/index.js +101 -195
  5. package/src/compiler/phases/2-analyze/index.js +82 -174
  6. package/src/compiler/phases/2-analyze/prune.js +2 -2
  7. package/src/compiler/phases/3-transform/client/index.js +169 -261
  8. package/src/compiler/phases/3-transform/server/index.js +185 -42
  9. package/src/compiler/types/index.d.ts +14 -33
  10. package/src/compiler/utils.js +32 -20
  11. package/src/runtime/index-client.js +0 -17
  12. package/src/runtime/internal/client/bindings.js +118 -7
  13. package/src/runtime/internal/client/render.js +5 -1
  14. package/src/runtime/internal/client/runtime.js +1 -1
  15. package/src/runtime/internal/client/types.d.ts +4 -0
  16. package/tests/client/array/array.copy-within.test.ripple +7 -7
  17. package/tests/client/array/array.derived.test.ripple +24 -24
  18. package/tests/client/array/array.iteration.test.ripple +7 -7
  19. package/tests/client/array/array.mutations.test.ripple +17 -17
  20. package/tests/client/array/array.to-methods.test.ripple +4 -4
  21. package/tests/client/async-suspend.test.ripple +3 -3
  22. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  23. package/tests/client/basic/basic.collections.test.ripple +6 -6
  24. package/tests/client/basic/basic.components.test.ripple +8 -8
  25. package/tests/client/basic/basic.errors.test.ripple +31 -34
  26. package/tests/client/basic/basic.events.test.ripple +11 -11
  27. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  28. package/tests/client/basic/basic.reactivity.test.ripple +36 -36
  29. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  30. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  31. package/tests/client/boundaries.test.ripple +7 -7
  32. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
  33. package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
  34. package/tests/client/compiler/compiler.basic.test.ripple +57 -58
  35. package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
  36. package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
  37. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  38. package/tests/client/composite/composite.props.test.ripple +9 -9
  39. package/tests/client/composite/composite.reactivity.test.ripple +23 -23
  40. package/tests/client/composite/composite.render.test.ripple +52 -4
  41. package/tests/client/computed-properties.test.ripple +3 -3
  42. package/tests/client/context.test.ripple +3 -3
  43. package/tests/client/css/global-additional-cases.test.ripple +5 -2
  44. package/tests/client/css/style-identifier.test.ripple +40 -49
  45. package/tests/client/date.test.ripple +39 -39
  46. package/tests/client/dynamic-elements.test.ripple +37 -37
  47. package/tests/client/events.test.ripple +25 -25
  48. package/tests/client/for.test.ripple +8 -8
  49. package/tests/client/head.test.ripple +7 -7
  50. package/tests/client/html.test.ripple +2 -2
  51. package/tests/client/input-value.test.ripple +376 -177
  52. package/tests/client/lazy-destructuring.test.ripple +185 -0
  53. package/tests/client/map.test.ripple +20 -20
  54. package/tests/client/media-query.test.ripple +4 -4
  55. package/tests/client/object.test.ripple +5 -5
  56. package/tests/client/portal.test.ripple +4 -4
  57. package/tests/client/ref.test.ripple +3 -3
  58. package/tests/client/return.test.ripple +17 -17
  59. package/tests/client/set.test.ripple +10 -10
  60. package/tests/client/svg.test.ripple +6 -5
  61. package/tests/client/switch.test.ripple +10 -10
  62. package/tests/client/tracked-expression.test.ripple +3 -1
  63. package/tests/client/try.test.ripple +4 -4
  64. package/tests/client/url/url.derived.test.ripple +6 -7
  65. package/tests/client/url/url.parsing.test.ripple +9 -9
  66. package/tests/client/url/url.partial-removal.test.ripple +9 -9
  67. package/tests/client/url/url.reactivity.test.ripple +16 -16
  68. package/tests/client/url/url.serialization.test.ripple +3 -3
  69. package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
  70. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
  71. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
  72. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
  73. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
  74. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
  75. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
  76. package/tests/hydration/build-components.js +4 -10
  77. package/tests/hydration/compiled/client/basic.js +4 -4
  78. package/tests/hydration/compiled/client/events.js +2 -0
  79. package/tests/hydration/compiled/client/for.js +2 -0
  80. package/tests/hydration/compiled/client/head.js +13 -11
  81. package/tests/hydration/compiled/client/hmr.js +4 -2
  82. package/tests/hydration/compiled/client/html.js +82 -95
  83. package/tests/hydration/compiled/client/if-children.js +8 -9
  84. package/tests/hydration/compiled/client/if.js +2 -0
  85. package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
  86. package/tests/hydration/compiled/client/portal.js +1 -1
  87. package/tests/hydration/compiled/client/reactivity.js +2 -0
  88. package/tests/hydration/compiled/client/return.js +2 -0
  89. package/tests/hydration/compiled/client/switch.js +2 -0
  90. package/tests/hydration/compiled/server/composite.js +2 -2
  91. package/tests/hydration/compiled/server/events.js +2 -0
  92. package/tests/hydration/compiled/server/for.js +2 -0
  93. package/tests/hydration/compiled/server/head.js +13 -11
  94. package/tests/hydration/compiled/server/hmr.js +2 -0
  95. package/tests/hydration/compiled/server/html.js +2 -0
  96. package/tests/hydration/compiled/server/if-children.js +2 -0
  97. package/tests/hydration/compiled/server/if.js +2 -0
  98. package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
  99. package/tests/hydration/compiled/server/portal.js +1 -1
  100. package/tests/hydration/compiled/server/reactivity.js +2 -0
  101. package/tests/hydration/compiled/server/return.js +2 -0
  102. package/tests/hydration/compiled/server/switch.js +2 -0
  103. package/tests/hydration/components/composite.ripple +1 -1
  104. package/tests/hydration/components/events.ripple +10 -8
  105. package/tests/hydration/components/for.ripple +22 -20
  106. package/tests/hydration/components/head.ripple +8 -6
  107. package/tests/hydration/components/hmr.ripple +3 -1
  108. package/tests/hydration/components/html.ripple +3 -1
  109. package/tests/hydration/components/if-children.ripple +9 -7
  110. package/tests/hydration/components/if.ripple +7 -5
  111. package/tests/hydration/components/mixed-control-flow.ripple +5 -3
  112. package/tests/hydration/components/portal.ripple +2 -2
  113. package/tests/hydration/components/reactivity.ripple +11 -9
  114. package/tests/hydration/components/return.ripple +13 -11
  115. package/tests/hydration/components/switch.ripple +6 -4
  116. package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
  117. package/tests/server/await.test.ripple +2 -2
  118. package/tests/server/basic.attributes.test.ripple +21 -19
  119. package/tests/server/basic.components.test.ripple +5 -4
  120. package/tests/server/basic.test.ripple +21 -20
  121. package/tests/server/compiler.test.ripple +36 -5
  122. package/tests/server/composite.props.test.ripple +7 -6
  123. package/tests/server/context.test.ripple +3 -1
  124. package/tests/server/dynamic-elements.test.ripple +24 -24
  125. package/tests/server/head.test.ripple +7 -5
  126. package/tests/server/style-identifier.test.ripple +95 -16
@@ -1,10 +1,10 @@
1
1
  import type { PropsWithExtras } from 'ripple';
2
- import { flushSync, createRefKey } from 'ripple';
2
+ import { createRefKey, flushSync, track, trackSplit } from 'ripple';
3
3
 
4
4
  describe('dynamic DOM elements', () => {
5
5
  it('renders static dynamic element', () => {
6
6
  component App() {
7
- let tag = #ripple.track('div');
7
+ let tag = track('div');
8
8
 
9
9
  <@tag>{'Hello World'}</@tag>
10
10
  }
@@ -19,7 +19,7 @@ describe('dynamic DOM elements', () => {
19
19
  // They can be ignored for now. But we'll fix them via jsx() vs <jsx>
20
20
  it('renders static dynamic element from a plain object with a tracked property', () => {
21
21
  component App() {
22
- let obj = { tag: #ripple.track('div') };
22
+ let obj = { tag: track('div') };
23
23
 
24
24
  <obj.@tag>{'Hello World'}</obj.@tag>
25
25
  }
@@ -32,7 +32,7 @@ describe('dynamic DOM elements', () => {
32
32
 
33
33
  it('renders static dynamic element from a tracked object with a tracked property', () => {
34
34
  component App() {
35
- let obj = #ripple.track({ tag: #ripple.track('div') });
35
+ let obj = track({ tag: track('div') });
36
36
 
37
37
  <@obj.@tag>{'Hello World'}</@obj.@tag>
38
38
  }
@@ -47,7 +47,7 @@ describe('dynamic DOM elements', () => {
47
47
  'renders static dynamic element from a tracked object with a computed tracked property',
48
48
  () => {
49
49
  component App() {
50
- let obj = #ripple.track({ tag: #ripple.track('div') });
50
+ let obj = track({ tag: track('div') });
51
51
 
52
52
  <@obj.@['tag']>{'Hello World'}</@obj.@['tag']>
53
53
  }
@@ -61,7 +61,7 @@ describe('dynamic DOM elements', () => {
61
61
 
62
62
  it('renders reactive dynamic element', () => {
63
63
  component App() {
64
- let tag = #ripple.track('div');
64
+ let tag = track('div');
65
65
 
66
66
  <button
67
67
  onClick={() => {
@@ -92,7 +92,7 @@ describe('dynamic DOM elements', () => {
92
92
 
93
93
  it('renders self-closing dynamic element', () => {
94
94
  component App() {
95
- let tag = #ripple.track('input');
95
+ let tag = track('input');
96
96
 
97
97
  <@tag type="text" value="test" />
98
98
  }
@@ -106,8 +106,8 @@ describe('dynamic DOM elements', () => {
106
106
 
107
107
  it('handles dynamic element with attributes', () => {
108
108
  component App() {
109
- let tag = #ripple.track('div');
110
- let className = #ripple.track('test-class');
109
+ let tag = track('div');
110
+ let className = track('test-class');
111
111
 
112
112
  <@tag class={@className} id="test" data-testid="dynamic-element">{'Content'}</@tag>
113
113
  }
@@ -122,8 +122,8 @@ describe('dynamic DOM elements', () => {
122
122
 
123
123
  it('handles nested dynamic elements', () => {
124
124
  component App() {
125
- let outerTag = #ripple.track('div');
126
- let innerTag = #ripple.track('span');
125
+ let outerTag = track('div');
126
+ let innerTag = track('span');
127
127
 
128
128
  <@outerTag class="outer">
129
129
  <@innerTag class="inner">{'Nested content'}</@innerTag>
@@ -142,8 +142,8 @@ describe('dynamic DOM elements', () => {
142
142
 
143
143
  it('handles dynamic element with class object', () => {
144
144
  component App() {
145
- let tag = #ripple.track('div');
146
- let active = #ripple.track(true);
145
+ let tag = track('div');
146
+ let active = track(true);
147
147
 
148
148
  <@tag class={{ active: @active, 'dynamic-element': true }}>
149
149
  {'Element with class object'}
@@ -159,7 +159,7 @@ describe('dynamic DOM elements', () => {
159
159
 
160
160
  it('handles dynamic element with style object', () => {
161
161
  component App() {
162
- let tag = #ripple.track('span');
162
+ let tag = track('span');
163
163
 
164
164
  <@tag
165
165
  style={{
@@ -182,7 +182,7 @@ describe('dynamic DOM elements', () => {
182
182
 
183
183
  it('handles dynamic element with spread attributes', () => {
184
184
  component App() {
185
- let tag = #ripple.track('section');
185
+ let tag = track('section');
186
186
  const attrs = {
187
187
  id: 'spread-section',
188
188
  'data-testid': 'spread-test',
@@ -205,7 +205,7 @@ describe('dynamic DOM elements', () => {
205
205
  let capturedElement: HTMLElement | null = null;
206
206
 
207
207
  component App() {
208
- let tag = #ripple.track('article');
208
+ let tag = track('article');
209
209
 
210
210
  <@tag
211
211
  {ref (node: HTMLElement) => {
@@ -227,7 +227,7 @@ describe('dynamic DOM elements', () => {
227
227
 
228
228
  it('handles dynamic element with createRefKey in spread', () => {
229
229
  component App() {
230
- let tag = #ripple.track('header');
230
+ let tag = track('header');
231
231
 
232
232
  function elementRef(node: HTMLElement) {
233
233
  // Set an attribute on the element to prove ref was called
@@ -257,8 +257,8 @@ describe('dynamic DOM elements', () => {
257
257
 
258
258
  it('has reactive attributes on dynamic elements', () => {
259
259
  component App() {
260
- let tag = #ripple.track('div');
261
- let count = #ripple.track(0);
260
+ let tag = track('div');
261
+ let count = track(0);
262
262
 
263
263
  <button
264
264
  onClick={() => {
@@ -311,7 +311,7 @@ describe('dynamic DOM elements', () => {
311
311
 
312
312
  it('applies scoped CSS to dynamic elements', () => {
313
313
  component App() {
314
- let tag = #ripple.track('div');
314
+ let tag = track('div');
315
315
 
316
316
  <@tag class="test-class">{'Dynamic element'}</@tag>
317
317
 
@@ -336,8 +336,8 @@ describe('dynamic DOM elements', () => {
336
336
 
337
337
  it('applies scoped CSS to dynamic elements with reactive classes', () => {
338
338
  component App() {
339
- let tag = #ripple.track('button');
340
- let count = #ripple.track(0);
339
+ let tag = track('button');
340
+ let count = track(0);
341
341
 
342
342
  <@tag
343
343
  class={@count % 2 ? 'even' : 'odd'}
@@ -410,8 +410,8 @@ describe('dynamic DOM elements', () => {
410
410
  id: string;
411
411
  onClick: EventListener;
412
412
  }>) {
413
- const tag = #ripple.track('button');
414
- const [rest] = #ripple.trackSplit(props, []);
413
+ const tag = track('button');
414
+ const [rest] = trackSplit(props, []);
415
415
  <@tag {...@rest}>{@rest.class}</@tag>
416
416
 
417
417
  <style>
@@ -425,7 +425,7 @@ describe('dynamic DOM elements', () => {
425
425
  }
426
426
 
427
427
  component App() {
428
- const count = #ripple.track(0);
428
+ const count = track(0);
429
429
  <DynamicButton
430
430
  class={@count % 2 ? 'even' : 'odd'}
431
431
  id={@count % 2 ? 'even' : 'odd'}
@@ -468,7 +468,7 @@ describe('dynamic DOM elements', () => {
468
468
 
469
469
  it('adds scoping class to dynamic elements', () => {
470
470
  component App() {
471
- let tag = #ripple.track('div');
471
+ let tag = track('div');
472
472
 
473
473
  <@tag class="scoped">
474
474
  <p>{'Scoped dynamic element'}</p>
@@ -491,7 +491,7 @@ describe('dynamic DOM elements', () => {
491
491
 
492
492
  it('adds scoping class to dynamic elements when selector targets by tag name', () => {
493
493
  component App() {
494
- let tag = #ripple.track('div');
494
+ let tag = track('div');
495
495
 
496
496
  <@tag class="scoped">
497
497
  <p>{'Scoped dynamic element'}</p>
@@ -526,7 +526,7 @@ describe('dynamic DOM elements', () => {
526
526
  }
527
527
 
528
528
  component App() {
529
- let tag = #ripple.track('div');
529
+ let tag = track('div');
530
530
 
531
531
  <@tag class="scoped">
532
532
  <p>{'Scoped dynamic element'}</p>
@@ -571,7 +571,7 @@ describe('dynamic DOM elements', () => {
571
571
  }
572
572
 
573
573
  component App() {
574
- let tag = #ripple.track(() => Child);
574
+ let tag = track(() => Child);
575
575
 
576
576
  <@tag />
577
577
 
@@ -598,12 +598,12 @@ describe('dynamic DOM elements', () => {
598
598
  let refCallCount = 0;
599
599
 
600
600
  component Button(props: any) {
601
- const el = #ripple.track('button');
601
+ const el = track('button');
602
602
  <@el {...props} />
603
603
  }
604
604
 
605
605
  component App() {
606
- let active = #ripple.track(false);
606
+ let active = track(false);
607
607
 
608
608
  <Button
609
609
  data-active={String(@active)}
@@ -641,14 +641,14 @@ describe('dynamic DOM elements', () => {
641
641
  let capturedElement: HTMLElement | null = null;
642
642
 
643
643
  component Button(props: any) {
644
- const el = #ripple.track('button');
644
+ const el = track('button');
645
645
  <@el {...props} />
646
646
  }
647
647
 
648
648
  component App() {
649
- let active = #ripple.track(false);
649
+ let active = track(false);
650
650
 
651
- let buttonProps = #ripple.track(
651
+ let buttonProps = track(
652
652
  () => ({
653
653
  'data-active': @active,
654
654
  }),
@@ -688,12 +688,12 @@ describe('dynamic DOM elements', () => {
688
688
  let capturedElement: HTMLElement | null = null;
689
689
 
690
690
  component Button(props: any) {
691
- const el = #ripple.track('button');
691
+ const el = track('button');
692
692
  <@el {...props} />
693
693
  }
694
694
 
695
695
  component App() {
696
- let active = #ripple.track(false);
696
+ let active = track(false);
697
697
 
698
698
  <Button
699
699
  data-active={String(@active)}
@@ -730,7 +730,7 @@ describe('dynamic DOM elements', () => {
730
730
 
731
731
  it('should remove and add back a text node in a conditional statement with a tracked', () => {
732
732
  component App() {
733
- let b = #ripple.track(true);
733
+ let b = track(true);
734
734
  <div>
735
735
  if (@b) {
736
736
  {'Inside if'}
@@ -1,11 +1,11 @@
1
1
  import type { OnEventListenerRemover } from 'ripple';
2
- import { flushSync, on } from 'ripple';
2
+ import { effect, flushSync, on, track } from 'ripple';
3
3
 
4
4
  describe('on() event handler', () => {
5
5
  it('should attach multiple handlers via onClick attribute (delegated)', () => {
6
6
  component Basic() {
7
- let count1 = #ripple.track(0);
8
- let count2 = #ripple.track(0);
7
+ let count1 = track(0);
8
+ let count2 = track(0);
9
9
 
10
10
  <button
11
11
  onClick={() => {
@@ -36,7 +36,7 @@ describe('on() event handler', () => {
36
36
 
37
37
  it('should attach and remove a single event handler', () => {
38
38
  component Basic() {
39
- let count = #ripple.track(0);
39
+ let count = track(0);
40
40
 
41
41
  const setupListener = (node: HTMLButtonElement) => {
42
42
  const remove = on(node, 'click', () => {
@@ -67,8 +67,8 @@ describe('on() event handler', () => {
67
67
 
68
68
  it('should handle multiple different event types on same element', () => {
69
69
  component Basic() {
70
- let clickCount = #ripple.track(0);
71
- let mousedownCount = #ripple.track(0);
70
+ let clickCount = track(0);
71
+ let mousedownCount = track(0);
72
72
 
73
73
  const setupListeners = (node: HTMLButtonElement) => {
74
74
  const remove1 = on(node, 'click', () => {
@@ -116,7 +116,7 @@ describe('on() event handler', () => {
116
116
 
117
117
  it('should handle multiple handlers for same event type on same element', () => {
118
118
  component Basic() {
119
- let callOrder = #ripple.track<number[]>([]);
119
+ let callOrder = track<number[]>([]);
120
120
 
121
121
  const setupListeners = (node: HTMLButtonElement) => {
122
122
  const remove1 = on(node, 'click', () => {
@@ -158,9 +158,9 @@ describe('on() event handler', () => {
158
158
 
159
159
  it('should remove specific handler without affecting others', () => {
160
160
  component Basic() {
161
- let handler1Called = #ripple.track(0);
162
- let handler2Called = #ripple.track(0);
163
- let handler3Called = #ripple.track(0);
161
+ let handler1Called = track(0);
162
+ let handler2Called = track(0);
163
+ let handler3Called = track(0);
164
164
  let removeHandler2: OnEventListenerRemover | undefined;
165
165
 
166
166
  const setupListeners = (node: HTMLButtonElement) => {
@@ -235,8 +235,8 @@ describe('on() event handler', () => {
235
235
  'should handle change event with multiple handlers (like bindChecked and bindIndeterminate)',
236
236
  () => {
237
237
  component Basic() {
238
- let checked = #ripple.track(false);
239
- let indeterminate = #ripple.track(true);
238
+ let checked = track(false);
239
+ let indeterminate = track(true);
240
240
 
241
241
  const setupListeners = (node: HTMLInputElement) => {
242
242
  node.indeterminate = @indeterminate;
@@ -283,7 +283,7 @@ describe('on() event handler', () => {
283
283
 
284
284
  it('should support non-delegated events', () => {
285
285
  component Basic() {
286
- let focusCount = #ripple.track(0);
286
+ let focusCount = track(0);
287
287
 
288
288
  const setupListener = (node: HTMLInputElement) => {
289
289
  const remove = on(node, 'focus', () => {
@@ -315,7 +315,7 @@ describe('on() event handler', () => {
315
315
 
316
316
  it('should handle removal of all handlers for same event type', () => {
317
317
  component Basic() {
318
- let count = #ripple.track(0);
318
+ let count = track(0);
319
319
  let remove1: OnEventListenerRemover | undefined;
320
320
  let remove2: OnEventListenerRemover | undefined;
321
321
  let remove3: OnEventListenerRemover | undefined;
@@ -379,7 +379,7 @@ describe('on() event handler', () => {
379
379
 
380
380
  it('should not add duplicate handlers when same handler is attached multiple times', () => {
381
381
  component Basic() {
382
- let count = #ripple.track(0);
382
+ let count = track(0);
383
383
 
384
384
  const sharedHandler = () => {
385
385
  @count++;
@@ -422,7 +422,7 @@ describe('on() event handler', () => {
422
422
 
423
423
  it('should allow duplicate handlers when delegated is false (no deduplication)', () => {
424
424
  component Basic() {
425
- let count = #ripple.track(0);
425
+ let count = track(0);
426
426
 
427
427
  const sharedHandler = () => {
428
428
  @count++;
@@ -466,7 +466,7 @@ describe('on() event handler', () => {
466
466
 
467
467
  it('should fire capture event on parent before bubbling event on child', () => {
468
468
  component Basic() {
469
- let callOrder = #ripple.track<string[]>([]);
469
+ let callOrder = track<string[]>([]);
470
470
 
471
471
  const parentCaptureHandler = () => {
472
472
  @callOrder = [...@callOrder, 'parent-capture'];
@@ -511,8 +511,8 @@ describe('on() event handler', () => {
511
511
 
512
512
  it('should fire handler only once when once option is true', () => {
513
513
  component Basic() {
514
- let count = #ripple.track(0);
515
- let permanentCount = #ripple.track(0);
514
+ let count = track(0);
515
+ let permanentCount = track(0);
516
516
 
517
517
  const setupListeners = (node: HTMLButtonElement) => {
518
518
  const onceHandler = on(node, 'click', () => {
@@ -565,9 +565,9 @@ describe('on() event handler', () => {
565
565
 
566
566
  it('should handle click events on window', () => {
567
567
  component Basic() {
568
- let windowClickCount = #ripple.track(0);
568
+ let windowClickCount = track(0);
569
569
 
570
- #ripple.effect(() => {
570
+ effect(() => {
571
571
  const removeWindowListener = on(window, 'click', () => {
572
572
  @windowClickCount++;
573
573
  });
@@ -601,9 +601,9 @@ describe('on() event handler', () => {
601
601
 
602
602
  it('should handle click events on document', () => {
603
603
  component Basic() {
604
- let documentClickCount = #ripple.track(0);
604
+ let documentClickCount = track(0);
605
605
 
606
- #ripple.effect(() => {
606
+ effect(() => {
607
607
  const removeDocumentListener = on(document, 'click', () => {
608
608
  @documentClickCount++;
609
609
  });
@@ -637,9 +637,9 @@ describe('on() event handler', () => {
637
637
 
638
638
  it('should handle click events on body', () => {
639
639
  component Basic() {
640
- let bodyClickCount = #ripple.track(0);
640
+ let bodyClickCount = track(0);
641
641
 
642
- #ripple.effect(() => {
642
+ effect(() => {
643
643
  const removeBodyListener = on(document.body, 'click', () => {
644
644
  @bodyClickCount++;
645
645
  });
@@ -1,4 +1,4 @@
1
- import { flushSync, RippleArray } from 'ripple';
1
+ import { RippleArray, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('for statements', () => {
4
4
  it('renders a simple static array', () => {
@@ -17,7 +17,7 @@ describe('for statements', () => {
17
17
 
18
18
  it('renders a simple dynamic array', () => {
19
19
  component App() {
20
- const items = #ripple['Item 1', 'Item 2', 'Item 3'];
20
+ const items = new RippleArray('Item 1', 'Item 2', 'Item 3');
21
21
 
22
22
  for (const item of items) {
23
23
  <div class={item}>{item}</div>
@@ -39,7 +39,7 @@ describe('for statements', () => {
39
39
 
40
40
  it('correctly handles intermediate statements in for block', () => {
41
41
  component App() {
42
- const items = #ripple[1, 2, 3];
42
+ const items = new RippleArray(1, 2, 3);
43
43
 
44
44
  <div>
45
45
  for (const item of items) {
@@ -68,7 +68,7 @@ describe('for statements', () => {
68
68
 
69
69
  it('correctly handles the index in a for...of loop', () => {
70
70
  component App() {
71
- const items = #ripple['a', 'b', 'c'];
71
+ const items = new RippleArray('a', 'b', 'c');
72
72
 
73
73
  <div>
74
74
  for (let item of items; index i) {
@@ -101,7 +101,7 @@ describe('for statements', () => {
101
101
 
102
102
  it('correctly handles keyed for...of loops', () => {
103
103
  component App() {
104
- let items = #ripple.track([
104
+ let items = track([
105
105
  { id: 1, text: 'Item 1' },
106
106
  { id: 2, text: 'Item 2' },
107
107
  { id: 3, text: 'Item 3' },
@@ -134,9 +134,9 @@ describe('for statements', () => {
134
134
 
135
135
  it('keyed for over derived updates sibling text nodes', () => {
136
136
  component App() {
137
- let count = #ripple.track(0);
137
+ let count = track(0);
138
138
 
139
- const items = #ripple.track(
139
+ const items = track(
140
140
  () => Array.from({ length: @count }).map((_, id) => ({ id, label: `Item ${id}` })),
141
141
  );
142
142
 
@@ -208,7 +208,7 @@ describe('for statements', () => {
208
208
 
209
209
  it('handles updating with new objects with same key', () => {
210
210
  component App() {
211
- let items = #ripple.track([
211
+ let items = track([
212
212
  { id: 1, text: 'Item 1' },
213
213
  { id: 2, text: 'Item 2' },
214
214
  { id: 3, text: 'Item 3' },
@@ -1,4 +1,4 @@
1
- import { flushSync } from 'ripple';
1
+ import { flushSync, track } from 'ripple';
2
2
 
3
3
  describe('head elements', () => {
4
4
  let originalTitle: string;
@@ -29,7 +29,7 @@ describe('head elements', () => {
29
29
 
30
30
  it('renders reactive title element', () => {
31
31
  component App() {
32
- let title = #ripple.track('Initial Title');
32
+ let title = track('Initial Title');
33
33
 
34
34
  <head>
35
35
  <title>{@title}</title>
@@ -61,7 +61,7 @@ describe('head elements', () => {
61
61
 
62
62
  it('renders title with template literal', () => {
63
63
  component App() {
64
- let name = #ripple.track('World');
64
+ let name = track('World');
65
65
 
66
66
  <head>
67
67
  <title>{`Hello ${@name}!`}</title>
@@ -90,7 +90,7 @@ describe('head elements', () => {
90
90
 
91
91
  it('renders title with computed value', () => {
92
92
  component App() {
93
- let count = #ripple.track(0);
93
+ let count = track(0);
94
94
  let prefix = 'Count: ';
95
95
 
96
96
  <head>
@@ -122,7 +122,7 @@ describe('head elements', () => {
122
122
 
123
123
  it('handles multiple title updates', () => {
124
124
  component App() {
125
- let step = #ripple.track(1);
125
+ let step = track(1);
126
126
 
127
127
  <head>
128
128
  <title>{`Step ${@step} of 3`}</title>
@@ -172,8 +172,8 @@ describe('head elements', () => {
172
172
 
173
173
  it('renders title with conditional content', () => {
174
174
  component App() {
175
- let showPrefix = #ripple.track(true);
176
- let title = #ripple.track('Main Page');
175
+ let showPrefix = track(true);
176
+ let title = track('Main Page');
177
177
 
178
178
  <head>
179
179
  <title>{@showPrefix ? 'App - ' + @title : @title}</title>
@@ -1,4 +1,4 @@
1
- import { flushSync } from 'ripple';
1
+ import { flushSync, track } from 'ripple';
2
2
 
3
3
  describe('html directive', () => {
4
4
  it('renders static html', () => {
@@ -14,7 +14,7 @@ describe('html directive', () => {
14
14
 
15
15
  it('renders dynamic html', () => {
16
16
  component App() {
17
- let str = #ripple.track('<div>Test</div>');
17
+ let str = track('<div>Test</div>');
18
18
 
19
19
  {html @str}
20
20