ripple 0.3.2 → 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 (128) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/package.json +2 -2
  3. package/src/compiler/identifier-utils.js +0 -2
  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 +174 -264
  8. package/src/compiler/phases/3-transform/segments.js +0 -22
  9. package/src/compiler/phases/3-transform/server/index.js +185 -42
  10. package/src/compiler/types/index.d.ts +14 -33
  11. package/src/compiler/utils.js +32 -20
  12. package/src/runtime/index-client.js +0 -17
  13. package/src/runtime/internal/client/bindings.js +118 -7
  14. package/src/runtime/internal/client/render.js +5 -1
  15. package/src/runtime/internal/client/runtime.js +1 -1
  16. package/src/runtime/internal/client/types.d.ts +4 -0
  17. package/tests/client/array/array.copy-within.test.ripple +7 -7
  18. package/tests/client/array/array.derived.test.ripple +24 -24
  19. package/tests/client/array/array.iteration.test.ripple +7 -7
  20. package/tests/client/array/array.mutations.test.ripple +17 -17
  21. package/tests/client/array/array.to-methods.test.ripple +4 -4
  22. package/tests/client/async-suspend.test.ripple +3 -3
  23. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  24. package/tests/client/basic/basic.collections.test.ripple +6 -6
  25. package/tests/client/basic/basic.components.test.ripple +8 -8
  26. package/tests/client/basic/basic.errors.test.ripple +31 -34
  27. package/tests/client/basic/basic.events.test.ripple +11 -11
  28. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  29. package/tests/client/basic/basic.reactivity.test.ripple +36 -36
  30. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  31. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  32. package/tests/client/boundaries.test.ripple +7 -7
  33. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
  34. package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
  35. package/tests/client/compiler/compiler.basic.test.ripple +58 -60
  36. package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
  37. package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
  38. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  39. package/tests/client/composite/composite.props.test.ripple +9 -9
  40. package/tests/client/composite/composite.reactivity.test.ripple +23 -23
  41. package/tests/client/composite/composite.render.test.ripple +52 -4
  42. package/tests/client/computed-properties.test.ripple +3 -3
  43. package/tests/client/context.test.ripple +3 -3
  44. package/tests/client/css/global-additional-cases.test.ripple +5 -2
  45. package/tests/client/css/style-identifier.test.ripple +40 -49
  46. package/tests/client/date.test.ripple +39 -39
  47. package/tests/client/dynamic-elements.test.ripple +37 -37
  48. package/tests/client/events.test.ripple +25 -25
  49. package/tests/client/for.test.ripple +8 -8
  50. package/tests/client/head.test.ripple +7 -7
  51. package/tests/client/html.test.ripple +2 -2
  52. package/tests/client/input-value.test.ripple +376 -177
  53. package/tests/client/lazy-destructuring.test.ripple +185 -0
  54. package/tests/client/map.test.ripple +20 -20
  55. package/tests/client/media-query.test.ripple +4 -4
  56. package/tests/client/object.test.ripple +5 -5
  57. package/tests/client/portal.test.ripple +4 -4
  58. package/tests/client/ref.test.ripple +3 -3
  59. package/tests/client/return.test.ripple +17 -17
  60. package/tests/client/set.test.ripple +10 -10
  61. package/tests/client/svg.test.ripple +6 -5
  62. package/tests/client/switch.test.ripple +10 -10
  63. package/tests/client/tracked-expression.test.ripple +3 -1
  64. package/tests/client/try.test.ripple +4 -4
  65. package/tests/client/url/url.derived.test.ripple +6 -7
  66. package/tests/client/url/url.parsing.test.ripple +9 -9
  67. package/tests/client/url/url.partial-removal.test.ripple +9 -9
  68. package/tests/client/url/url.reactivity.test.ripple +16 -16
  69. package/tests/client/url/url.serialization.test.ripple +3 -3
  70. package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
  71. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
  72. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
  73. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
  74. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
  75. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
  76. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
  77. package/tests/hydration/build-components.js +4 -10
  78. package/tests/hydration/compiled/client/basic.js +4 -4
  79. package/tests/hydration/compiled/client/events.js +2 -0
  80. package/tests/hydration/compiled/client/for.js +2 -0
  81. package/tests/hydration/compiled/client/head.js +13 -11
  82. package/tests/hydration/compiled/client/hmr.js +4 -2
  83. package/tests/hydration/compiled/client/html.js +82 -95
  84. package/tests/hydration/compiled/client/if-children.js +8 -9
  85. package/tests/hydration/compiled/client/if.js +2 -0
  86. package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
  87. package/tests/hydration/compiled/client/portal.js +1 -1
  88. package/tests/hydration/compiled/client/reactivity.js +2 -0
  89. package/tests/hydration/compiled/client/return.js +2 -0
  90. package/tests/hydration/compiled/client/switch.js +2 -0
  91. package/tests/hydration/compiled/server/composite.js +2 -2
  92. package/tests/hydration/compiled/server/events.js +2 -0
  93. package/tests/hydration/compiled/server/for.js +2 -0
  94. package/tests/hydration/compiled/server/head.js +13 -11
  95. package/tests/hydration/compiled/server/hmr.js +2 -0
  96. package/tests/hydration/compiled/server/html.js +2 -0
  97. package/tests/hydration/compiled/server/if-children.js +2 -0
  98. package/tests/hydration/compiled/server/if.js +2 -0
  99. package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
  100. package/tests/hydration/compiled/server/portal.js +1 -1
  101. package/tests/hydration/compiled/server/reactivity.js +2 -0
  102. package/tests/hydration/compiled/server/return.js +2 -0
  103. package/tests/hydration/compiled/server/switch.js +2 -0
  104. package/tests/hydration/components/composite.ripple +1 -1
  105. package/tests/hydration/components/events.ripple +10 -8
  106. package/tests/hydration/components/for.ripple +22 -20
  107. package/tests/hydration/components/head.ripple +8 -6
  108. package/tests/hydration/components/hmr.ripple +3 -1
  109. package/tests/hydration/components/html.ripple +3 -1
  110. package/tests/hydration/components/if-children.ripple +9 -7
  111. package/tests/hydration/components/if.ripple +7 -5
  112. package/tests/hydration/components/mixed-control-flow.ripple +5 -3
  113. package/tests/hydration/components/portal.ripple +2 -2
  114. package/tests/hydration/components/reactivity.ripple +11 -9
  115. package/tests/hydration/components/return.ripple +13 -11
  116. package/tests/hydration/components/switch.ripple +6 -4
  117. package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
  118. package/tests/server/await.test.ripple +2 -2
  119. package/tests/server/basic.attributes.test.ripple +21 -19
  120. package/tests/server/basic.components.test.ripple +5 -4
  121. package/tests/server/basic.test.ripple +21 -20
  122. package/tests/server/compiler.test.ripple +36 -5
  123. package/tests/server/composite.props.test.ripple +7 -6
  124. package/tests/server/context.test.ripple +3 -1
  125. package/tests/server/dynamic-elements.test.ripple +24 -24
  126. package/tests/server/head.test.ripple +7 -5
  127. package/tests/server/style-identifier.test.ripple +95 -16
  128. package/types/index.d.ts +4 -1
@@ -0,0 +1,185 @@
1
+ import { flushSync, track } from 'ripple';
2
+
3
+ describe('lazy destructuring', () => {
4
+ it('lazily accesses object properties with const', () => {
5
+ component Inner(&{ a, b }: { a: number; b: string }) {
6
+ <pre>{`${a}-${b}`}</pre>
7
+ }
8
+
9
+ component Test() {
10
+ let a = track(1);
11
+ let b = track('hello');
12
+
13
+ <Inner {@a} {@b} />
14
+ <button
15
+ onClick={() => {
16
+ @a = 2;
17
+ @b = 'world';
18
+ }}
19
+ >
20
+ {'update'}
21
+ </button>
22
+ }
23
+
24
+ render(Test);
25
+ expect(container.querySelector('pre')!.textContent).toBe('1-hello');
26
+ container.querySelector('button')!.click();
27
+ flushSync();
28
+ expect(container.querySelector('pre')!.textContent).toBe('2-world');
29
+ });
30
+
31
+ it('lazily accesses array elements with const', () => {
32
+ component Inner(&{ first, second }: { first: number; second: number }) {
33
+ <pre>{`${first}-${second}`}</pre>
34
+ }
35
+
36
+ component Test() {
37
+ let first = track(10);
38
+ let second = track(20);
39
+
40
+ <Inner {@first} {@second} />
41
+ <button
42
+ onClick={() => {
43
+ @first = 30;
44
+ @second = 40;
45
+ }}
46
+ >
47
+ {'update'}
48
+ </button>
49
+ }
50
+
51
+ render(Test);
52
+ expect(container.querySelector('pre')!.textContent).toBe('10-20');
53
+ container.querySelector('button')!.click();
54
+ flushSync();
55
+ expect(container.querySelector('pre')!.textContent).toBe('30-40');
56
+ });
57
+
58
+ it('supports default values in lazy object destructuring', () => {
59
+ component Test() {
60
+ const obj = { a: 5 };
61
+ const &{ a, b = 99 } = obj;
62
+ <pre>{`${a}-${b}`}</pre>
63
+ }
64
+
65
+ render(Test);
66
+ expect(container.querySelector('pre')!.textContent).toBe('5-99');
67
+ });
68
+
69
+ it('supports lazy destructuring in component params', () => {
70
+ component Inner(&{ name, age }: { name: string; age: number }) {
71
+ <pre>{`${name}-${age}`}</pre>
72
+ }
73
+
74
+ component Test() {
75
+ <Inner name="Alice" age={30} />
76
+ }
77
+
78
+ render(Test);
79
+ expect(container.querySelector('pre')!.textContent).toBe('Alice-30');
80
+ });
81
+
82
+ it('supports lazy destructuring in component params with reactivity', () => {
83
+ component Inner(&{ count }: { count: number }) {
84
+ <pre>{count}</pre>
85
+ }
86
+
87
+ component Test() {
88
+ let count = track(0);
89
+
90
+ <Inner {@count} />
91
+ <button
92
+ onClick={() => {
93
+ @count++;
94
+ }}
95
+ >
96
+ {'increment'}
97
+ </button>
98
+ }
99
+
100
+ render(Test);
101
+ expect(container.querySelector('pre')!.textContent).toBe('0');
102
+ container.querySelector('button')!.click();
103
+ flushSync();
104
+ expect(container.querySelector('pre')!.textContent).toBe('1');
105
+ });
106
+
107
+ it('supports lazy destructuring in function params', () => {
108
+ component Test() {
109
+ function getInfo(&{ x, y }: { x: number; y: number }) {
110
+ return x + y;
111
+ }
112
+ const result = getInfo({ x: 3, y: 7 });
113
+ <pre>{result}</pre>
114
+ }
115
+
116
+ render(Test);
117
+ expect(container.querySelector('pre')!.textContent).toBe('10');
118
+ });
119
+
120
+ it('supports let lazy destructuring with assignment writeback', () => {
121
+ component Test() {
122
+ const obj = { a: 1, b: 2 };
123
+ let &{ a, b } = obj;
124
+ a = 10;
125
+ b = 20;
126
+ <pre>{`${obj.a}-${obj.b}`}</pre>
127
+ }
128
+
129
+ render(Test);
130
+ expect(container.querySelector('pre')!.textContent).toBe('10-20');
131
+ });
132
+
133
+ it('supports compound assignment operators on lazy bindings', () => {
134
+ component Test() {
135
+ const obj = { a: 5, b: 10 };
136
+ let &{ a, b } = obj;
137
+ a += 3;
138
+ b *= 2;
139
+ <pre>{`${obj.a}-${obj.b}`}</pre>
140
+ }
141
+
142
+ render(Test);
143
+ expect(container.querySelector('pre')!.textContent).toBe('8-20');
144
+ });
145
+
146
+ it('supports update expressions on lazy bindings', () => {
147
+ component Test() {
148
+ const obj = { count: 0 };
149
+ let &{ count } = obj;
150
+ count++;
151
+ count++;
152
+ count--;
153
+ <pre>{obj.count}</pre>
154
+ }
155
+
156
+ render(Test);
157
+ expect(container.querySelector('pre')!.textContent).toBe('1');
158
+ });
159
+
160
+ it('supports function params with lazy destructuring and default values', () => {
161
+ component Test() {
162
+ function calc(&{ x, y = 100 }: { x: number; y?: number }) {
163
+ return x + y;
164
+ }
165
+ const a = calc({ x: 5, y: 10 });
166
+ const b = calc({ x: 5 });
167
+ <pre>{`${a}-${b}`}</pre>
168
+ }
169
+
170
+ render(Test);
171
+ expect(container.querySelector('pre')!.textContent).toBe('15-105');
172
+ });
173
+
174
+ it('supports lazy destructuring with default value writeback', () => {
175
+ component Test() {
176
+ const obj: { a: number; b?: number } = { a: 1 };
177
+ let &{ a, b = 50 } = obj;
178
+ b = 99;
179
+ <pre>{`${a}-${obj.b}`}</pre>
180
+ }
181
+
182
+ render(Test);
183
+ expect(container.querySelector('pre')!.textContent).toBe('1-99');
184
+ });
185
+ });
@@ -1,11 +1,11 @@
1
- import { flushSync, RippleMap } from 'ripple';
1
+ import { RippleMap, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('RippleMap', () => {
4
4
  it('handles set with update and delete operations with a reactive size var', () => {
5
5
  component MapTest() {
6
- let map = #ripple.map([['a', 1], ['b', 2], ['c', 3]]);
7
- let value = #ripple.track(() => map.get('a'));
8
- let size = #ripple.track(() => map.size);
6
+ let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
7
+ let value = track(() => map.get('a'));
8
+ let size = track(() => map.size);
9
9
 
10
10
  <button onClick={() => map.set('d', 4)}>{'set'}</button>
11
11
  <button onClick={() => map.delete('b')}>{'delete'}</button>
@@ -42,7 +42,7 @@ describe('RippleMap', () => {
42
42
 
43
43
  it('handles clear operation', () => {
44
44
  component MapTest() {
45
- let map = #ripple.map([['a', 1], ['b', 2], ['c', 3]]);
45
+ let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
46
46
 
47
47
  <button onClick={() => map.clear()}>{'clear'}</button>
48
48
  <pre>{map.size}</pre>
@@ -60,8 +60,8 @@ describe('RippleMap', () => {
60
60
 
61
61
  it('handles has operation and tracks reactive $has', () => {
62
62
  component MapTest() {
63
- let map = #ripple.map([['a', 1], ['b', 2], ['c', 3]]);
64
- let has = #ripple.track(() => map.has('b'));
63
+ let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
64
+ let has = track(() => map.has('b'));
65
65
 
66
66
  <button onClick={() => map.delete('b')}>{'delete'}</button>
67
67
  <pre>{@has}</pre>
@@ -80,10 +80,10 @@ describe('RippleMap', () => {
80
80
 
81
81
  it('handles reactivity of keys, values, and entries', () => {
82
82
  component MapTest() {
83
- let map = #ripple.map([['x', 10], ['y', 20]]);
84
- let keys = #ripple.track(() => Array.from(map.keys()));
85
- let values = #ripple.track(() => Array.from(map.values()));
86
- let entries = #ripple.track(() => Array.from(map.entries()));
83
+ let map = RippleMap([['x', 10], ['y', 20]]);
84
+ let keys = track(() => Array.from(map.keys()));
85
+ let values = track(() => Array.from(map.values()));
86
+ let entries = track(() => Array.from(map.entries()));
87
87
 
88
88
  <button onClick={() => map.delete('x')}>{'delete'}</button>
89
89
 
@@ -110,7 +110,7 @@ describe('RippleMap', () => {
110
110
 
111
111
  it('toJSON returns correct object', () => {
112
112
  component MapTest() {
113
- let map = #ripple.map([['foo', 1], ['bar', 2]]);
113
+ let map = RippleMap([['foo', 1], ['bar', 2]]);
114
114
 
115
115
  <pre>{JSON.stringify(map)}</pre>
116
116
  }
@@ -120,9 +120,9 @@ describe('RippleMap', () => {
120
120
  expect(container.querySelectorAll('pre')[0].textContent).toBe('[["foo",1],["bar",2]]');
121
121
  });
122
122
 
123
- it('creates empty RippleMap using #ripple.map() shorthand syntax', () => {
123
+ it('creates empty RippleMap using RippleMap() shorthand syntax', () => {
124
124
  component MapTest() {
125
- let map = #ripple.map();
125
+ let map = RippleMap();
126
126
 
127
127
  <button onClick={() => map.set('a', 1)}>{'add'}</button>
128
128
  <pre>{map.size}</pre>
@@ -139,10 +139,10 @@ describe('RippleMap', () => {
139
139
  expect(container.querySelector('pre').textContent).toBe('1');
140
140
  });
141
141
 
142
- it('creates RippleMap with initial entries using #ripple.map() shorthand syntax', () => {
142
+ it('creates RippleMap with initial entries using RippleMap() shorthand syntax', () => {
143
143
  component MapTest() {
144
- let map = #ripple.map([['a', 1], ['b', 2], ['c', 3]]);
145
- let value = #ripple.track(() => map.get('b'));
144
+ let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
145
+ let value = track(() => map.get('b'));
146
146
 
147
147
  <button onClick={() => map.set('b', 10)}>{'update'}</button>
148
148
  <pre>{map.size}</pre>
@@ -161,10 +161,10 @@ describe('RippleMap', () => {
161
161
  expect(container.querySelectorAll('pre')[1].textContent).toBe('10');
162
162
  });
163
163
 
164
- it('handles all operations with #ripple.map() shorthand syntax', () => {
164
+ it('handles all operations with RippleMap() shorthand syntax', () => {
165
165
  component MapTest() {
166
- let map = #ripple.map([['x', 100], ['y', 200]]);
167
- let keys = #ripple.track(() => Array.from(map.keys()));
166
+ let map = RippleMap([['x', 100], ['y', 200]]);
167
+ let keys = track(() => Array.from(map.keys()));
168
168
 
169
169
  <button onClick={() => map.set('z', 300)}>{'add'}</button>
170
170
  <button onClick={() => map.delete('x')}>{'delete'}</button>
@@ -1,4 +1,4 @@
1
- import { flushSync } from 'ripple';
1
+ import { MediaQuery, flushSync, track } from 'ripple';
2
2
 
3
3
  type Callback = (event: MediaQueryListEvent) => void;
4
4
 
@@ -51,7 +51,7 @@ describe('MediaQuery', () => {
51
51
  const media = '(min-width: 600px)';
52
52
 
53
53
  component App() {
54
- const medium = #ripple.mediaQuery(media);
54
+ const medium = MediaQuery(media);
55
55
 
56
56
  <div>
57
57
  <p>{@medium}</p>
@@ -86,7 +86,7 @@ describe('MediaQuery', () => {
86
86
  const media = '(min-width: 600px)';
87
87
 
88
88
  component App() {
89
- let show = #ripple.track(true);
89
+ let show = track(true);
90
90
 
91
91
  if (@show) {
92
92
  <Child />
@@ -96,7 +96,7 @@ describe('MediaQuery', () => {
96
96
  }
97
97
 
98
98
  component Child() {
99
- const medium = #ripple.mediaQuery(media);
99
+ const medium = MediaQuery(media);
100
100
 
101
101
  <div>
102
102
  <p>{@medium}</p>
@@ -1,10 +1,10 @@
1
- import { flushSync, RippleObject } from 'ripple';
1
+ import { RippleObject, flushSync } from 'ripple';
2
2
  import { TRACKED_OBJECT } from '../../src/runtime/internal/client/constants.js';
3
3
 
4
4
  describe('RippleObject', () => {
5
5
  it('makes new properties reactive', () => {
6
6
  component ObjectTest() {
7
- const obj = #ripple{ a: -1 };
7
+ const obj = new RippleObject({ a: -1 });
8
8
 
9
9
  obj.a = 0;
10
10
 
@@ -33,7 +33,7 @@ describe('RippleObject', () => {
33
33
 
34
34
  it('makes existing object properties reactive', () => {
35
35
  component ObjectTest() {
36
- const obj = #ripple{ a: 0 };
36
+ const obj = new RippleObject({ a: 0 });
37
37
 
38
38
  <pre>{obj.a}</pre>
39
39
  <button
@@ -60,7 +60,7 @@ describe('RippleObject', () => {
60
60
 
61
61
  it('checks if property exists via the has trap', () => {
62
62
  component ObjectTest() {
63
- const obj = #ripple{ a: -1, b: 1 };
63
+ const obj = new RippleObject({ a: -1, b: 1 });
64
64
 
65
65
  obj.a = 0;
66
66
 
@@ -167,7 +167,7 @@ describe('RippleObject', () => {
167
167
 
168
168
  it('uses the hash syntax for creating RippleObject', () => {
169
169
  component ObjectTest() {
170
- const obj = #ripple{ a: 0, b: 1, c: { d: { e: 8 } } };
170
+ const obj = new RippleObject({ a: 0, b: 1, c: { d: { e: 8 } } });
171
171
 
172
172
  <pre>{obj.a}</pre>
173
173
  <pre>{TRACKED_OBJECT in obj}</pre>
@@ -1,4 +1,4 @@
1
- import { Portal, flushSync } from 'ripple';
1
+ import { Portal, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('Portal', () => {
4
4
  afterEach(() => {
@@ -46,7 +46,7 @@ describe('Portal', () => {
46
46
 
47
47
  it('cleans up portal content when destroyed via conditional rendering', () => {
48
48
  component TestPortal() {
49
- let open = #ripple.track(true);
49
+ let open = track(true);
50
50
 
51
51
  if (@open) {
52
52
  <Portal target={document.body}>
@@ -72,7 +72,7 @@ describe('Portal', () => {
72
72
 
73
73
  it('opens and closes portal via conditional rendering', () => {
74
74
  component TestPortal() {
75
- let open = #ripple.track(false);
75
+ let open = track(false);
76
76
 
77
77
  if (@open) {
78
78
  <Portal target={document.body}>
@@ -138,7 +138,7 @@ describe('Portal', () => {
138
138
 
139
139
  it('handles portal with reactive content', () => {
140
140
  component TestReactivePortal() {
141
- let count = #ripple.track(0);
141
+ let count = track(0);
142
142
 
143
143
  <Portal target={document.body}>
144
144
  <div class="test-portal">
@@ -1,6 +1,6 @@
1
1
  import type { PropsWithExtras } from 'ripple';
2
2
  import { describe, it, expect } from 'vitest';
3
- import { flushSync, RippleArray, createRefKey } from 'ripple';
3
+ import { RippleArray, createRefKey, flushSync, track } from 'ripple';
4
4
 
5
5
  describe('refs', () => {
6
6
  it('capture a <div>', () => {
@@ -50,7 +50,7 @@ describe('refs', () => {
50
50
  let logs: string[] = [];
51
51
 
52
52
  component App() {
53
- let value = #ripple.track('test');
53
+ let value = track('test');
54
54
 
55
55
  function inputRef(node: HTMLInputElement) {
56
56
  logs.push('ref called');
@@ -81,7 +81,7 @@ describe('refs', () => {
81
81
  let logs: string[] = [];
82
82
 
83
83
  component App() {
84
- let value = #ripple.track('test');
84
+ let value = track('test');
85
85
 
86
86
  function inputRef(node: HTMLInputElement) {
87
87
  logs.push('ref called');
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { flushSync } from 'ripple';
2
+ import { flushSync, track } from 'ripple';
3
3
  import { compile } from 'ripple/compiler';
4
4
 
5
5
  describe('returns in prohibited scopes', () => {
@@ -64,7 +64,7 @@ describe('early return in client components', () => {
64
64
 
65
65
  it('reactive: condition changes from false to true hides rest', () => {
66
66
  component App() {
67
- let condition = #ripple.track(false);
67
+ let condition = track(false);
68
68
 
69
69
  <button
70
70
  onClick={() => {
@@ -93,7 +93,7 @@ describe('early return in client components', () => {
93
93
 
94
94
  it('reactive: condition changes from true to false shows rest', () => {
95
95
  component App() {
96
- let condition = #ripple.track(true);
96
+ let condition = track(true);
97
97
 
98
98
  <button
99
99
  onClick={() => {
@@ -905,8 +905,8 @@ describe('early return in client components', () => {
905
905
 
906
906
  it('reactive: nested return condition changes', () => {
907
907
  component App() {
908
- let a = #ripple.track(true);
909
- let b = #ripple.track(true);
908
+ let a = track(true);
909
+ let b = track(true);
910
910
 
911
911
  <button
912
912
  onClick={() => {
@@ -940,7 +940,7 @@ describe('early return in client components', () => {
940
940
 
941
941
  it('reactive: return in nested element scope', () => {
942
942
  component App() {
943
- let show = #ripple.track(true);
943
+ let show = track(true);
944
944
 
945
945
  <button
946
946
  onClick={() => {
@@ -1214,7 +1214,7 @@ describe('early return in client components', () => {
1214
1214
 
1215
1215
  it('reactive: nested return - outer condition changes to false shows rest', () => {
1216
1216
  component App() {
1217
- let a = #ripple.track(true);
1217
+ let a = track(true);
1218
1218
  let b = true;
1219
1219
 
1220
1220
  <button
@@ -1251,7 +1251,7 @@ describe('early return in client components', () => {
1251
1251
  component App() {
1252
1252
  let a = true;
1253
1253
  let b = true;
1254
- let c = #ripple.track(true);
1254
+ let c = track(true);
1255
1255
 
1256
1256
  <button
1257
1257
  onClick={() => {
@@ -2208,10 +2208,10 @@ describe('early return in client components', () => {
2208
2208
 
2209
2209
  it('nested reactive: toggling conditions updates DOM', () => {
2210
2210
  component App() {
2211
- let a = #ripple.track(false);
2212
- let b = #ripple.track(false);
2213
- let c = #ripple.track(false);
2214
- let d = #ripple.track(false);
2211
+ let a = track(false);
2212
+ let b = track(false);
2213
+ let c = track(false);
2214
+ let d = track(false);
2215
2215
 
2216
2216
  <button
2217
2217
  class="toggle-c"
@@ -2279,7 +2279,7 @@ describe('early return in client components', () => {
2279
2279
  () => {
2280
2280
  component App() {
2281
2281
  let a = true;
2282
- let b = #ripple.track(true);
2282
+ let b = track(true);
2283
2283
 
2284
2284
  <button
2285
2285
  class="toggle"
@@ -2326,7 +2326,7 @@ describe('early return in client components', () => {
2326
2326
 
2327
2327
  it('reactive sibling returns cycle through first, second, and fallback branches', () => {
2328
2328
  component App() {
2329
- let mode = #ripple.track('first');
2329
+ let mode = track('first');
2330
2330
 
2331
2331
  <button
2332
2332
  class="toggle"
@@ -2382,8 +2382,8 @@ describe('early return in client components', () => {
2382
2382
 
2383
2383
  it('reactive nested returns with tracked outer and inner flags transition correctly', () => {
2384
2384
  component App() {
2385
- let a = #ripple.track(true);
2386
- let b = #ripple.track(true);
2385
+ let a = track(true);
2386
+ let b = track(true);
2387
2387
 
2388
2388
  <button
2389
2389
  class="toggle-a"
@@ -2446,7 +2446,7 @@ describe('early return in client components', () => {
2446
2446
 
2447
2447
  it('reactive else-if return chain transitions between return and non-return states', () => {
2448
2448
  component App() {
2449
- let status = #ripple.track(0);
2449
+ let status = track(0);
2450
2450
 
2451
2451
  <button
2452
2452
  class="toggle"
@@ -1,4 +1,4 @@
1
- import { flushSync, RippleSet } from 'ripple';
1
+ import { RippleSet, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('RippleSet', () => {
4
4
  it('handles add and delete operations', () => {
@@ -60,7 +60,7 @@ describe('RippleSet', () => {
60
60
  it('handles has operation', () => {
61
61
  component SetTest() {
62
62
  let items = new RippleSet([1, 2, 3]);
63
- let hasValue = #ripple.track(() => items.has(2));
63
+ let hasValue = track(() => items.has(2));
64
64
 
65
65
  <button onClick={() => items.delete(2)}>{'delete'}</button>
66
66
  <pre>{@hasValue}</pre>
@@ -78,9 +78,9 @@ describe('RippleSet', () => {
78
78
  expect(container.querySelectorAll('pre')[0].textContent).toBe('false');
79
79
  });
80
80
 
81
- it('creates empty RippleSet using #ripple.set() shorthand syntax', () => {
81
+ it('creates empty RippleSet using RippleSet() shorthand syntax', () => {
82
82
  component SetTest() {
83
- let items = #ripple.set();
83
+ let items = RippleSet();
84
84
 
85
85
  <button onClick={() => items.add(1)}>{'add'}</button>
86
86
  <pre>{items.size}</pre>
@@ -97,10 +97,10 @@ describe('RippleSet', () => {
97
97
  expect(container.querySelector('pre').textContent).toBe('1');
98
98
  });
99
99
 
100
- it('creates RippleSet with initial values using #ripple.set() shorthand syntax', () => {
100
+ it('creates RippleSet with initial values using RippleSet() shorthand syntax', () => {
101
101
  component SetTest() {
102
- let items = #ripple.set([1, 2, 3, 4]);
103
- let hasValue = #ripple.track(() => items.has(3));
102
+ let items = RippleSet([1, 2, 3, 4]);
103
+ let hasValue = track(() => items.has(3));
104
104
 
105
105
  <button onClick={() => items.delete(3)}>{'delete'}</button>
106
106
  <pre>{items.size}</pre>
@@ -120,10 +120,10 @@ describe('RippleSet', () => {
120
120
  expect(container.querySelectorAll('pre')[1].textContent).toBe('false');
121
121
  });
122
122
 
123
- it('handles all operations with #ripple.set() shorthand syntax', () => {
123
+ it('handles all operations with RippleSet() shorthand syntax', () => {
124
124
  component SetTest() {
125
- let items = #ripple.set([10, 20, 30]);
126
- let values = #ripple.track(() => Array.from(items.values()));
125
+ let items = RippleSet([10, 20, 30]);
126
+ let values = track(() => Array.from(items.values()));
127
127
 
128
128
  <button onClick={() => items.add(40)}>{'add'}</button>
129
129
  <button onClick={() => items.delete(20)}>{'delete'}</button>
@@ -1,3 +1,4 @@
1
+ import { track } from 'ripple';
1
2
  import type { Component, PropsWithChildren, PropsWithExtras } from 'ripple';
2
3
 
3
4
  describe('SVG namespace handling', () => {
@@ -289,7 +290,7 @@ describe('SVG namespace handling', () => {
289
290
  }
290
291
 
291
292
  component App() {
292
- let dynTag = #ripple.track('polygon');
293
+ let dynTag = track('polygon');
293
294
  <SVG>
294
295
  <@dynTag points="0,0 30,0 15,10" />
295
296
  </SVG>
@@ -316,7 +317,7 @@ describe('SVG namespace handling', () => {
316
317
  }
317
318
 
318
319
  component App() {
319
- let Component = #ripple.track(() => Polygon);
320
+ let Component = track(() => Polygon);
320
321
  <SVG>
321
322
  <@Component points="0,0 30,0 15,10" />
322
323
  </SVG>
@@ -333,19 +334,19 @@ describe('SVG namespace handling', () => {
333
334
 
334
335
  it('should render SVG as a dynamic top element with any dynamic children elements', () => {
335
336
  component SVG({ children }: PropsWithChildren<{}>) {
336
- const tag = #ripple.track('svg');
337
+ const tag = track('svg');
337
338
  <@tag width={100} height={50} fill="red" viewBox="0 0 30 10" preserveAspectRatio="none">
338
339
  <children />
339
340
  </@tag>
340
341
  }
341
342
 
342
343
  component Polygon({ points }: PropsWithExtras<{ points: string }>) {
343
- let dynTag = #ripple.track('polygon');
344
+ let dynTag = track('polygon');
344
345
  <@dynTag {points} />
345
346
  }
346
347
 
347
348
  component App() {
348
- let Component = #ripple.track(() => Polygon);
349
+ let Component = track(() => Polygon);
349
350
  <SVG>
350
351
  <@Component points="0,0 30,0 15,10" />
351
352
  </SVG>