ripple 0.2.216 → 0.3.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 (155) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/package.json +16 -7
  3. package/src/compiler/errors.js +1 -1
  4. package/src/compiler/identifier-utils.js +2 -0
  5. package/src/compiler/index.d.ts +2 -6
  6. package/src/compiler/phases/1-parse/index.js +171 -233
  7. package/src/compiler/phases/2-analyze/index.js +192 -16
  8. package/src/compiler/phases/2-analyze/prune.js +2 -2
  9. package/src/compiler/phases/3-transform/client/index.js +308 -91
  10. package/src/compiler/phases/3-transform/segments.js +43 -15
  11. package/src/compiler/phases/3-transform/server/index.js +71 -21
  12. package/src/compiler/scope.js +31 -12
  13. package/src/compiler/source-map-utils.js +4 -6
  14. package/src/compiler/types/acorn.d.ts +11 -0
  15. package/src/compiler/types/estree-jsx.d.ts +11 -0
  16. package/src/compiler/types/estree.d.ts +11 -0
  17. package/src/compiler/types/import.d.ts +32 -18
  18. package/src/compiler/types/index.d.ts +75 -23
  19. package/src/compiler/types/parse.d.ts +7 -10
  20. package/src/compiler/utils.js +48 -0
  21. package/src/runtime/array.js +53 -22
  22. package/src/runtime/date.js +15 -5
  23. package/src/runtime/index-client.js +41 -7
  24. package/src/runtime/index-server.js +7 -7
  25. package/src/runtime/internal/client/bindings.js +2 -2
  26. package/src/runtime/internal/client/blocks.js +40 -1
  27. package/src/runtime/internal/client/context.js +8 -0
  28. package/src/runtime/internal/client/for.js +3 -3
  29. package/src/runtime/internal/client/index.js +32 -5
  30. package/src/runtime/internal/client/render.js +20 -8
  31. package/src/runtime/internal/client/runtime.js +9 -7
  32. package/src/runtime/internal/client/try.js +15 -22
  33. package/src/runtime/internal/client/utils.js +1 -1
  34. package/src/runtime/internal/server/context.js +8 -0
  35. package/src/runtime/internal/server/index.js +99 -6
  36. package/src/runtime/map.js +7 -7
  37. package/src/runtime/media-query.js +10 -1
  38. package/src/runtime/object.js +6 -6
  39. package/src/runtime/proxy.js +6 -6
  40. package/src/runtime/set.js +11 -11
  41. package/src/runtime/url-search-params.js +13 -2
  42. package/src/runtime/url.js +15 -5
  43. package/src/utils/builders.js +13 -3
  44. package/tests/client/array/array.copy-within.test.ripple +11 -11
  45. package/tests/client/array/array.derived.test.ripple +42 -42
  46. package/tests/client/array/array.iteration.test.ripple +12 -12
  47. package/tests/client/array/array.mutations.test.ripple +25 -25
  48. package/tests/client/array/array.static.test.ripple +103 -106
  49. package/tests/client/array/array.to-methods.test.ripple +8 -8
  50. package/tests/client/async-suspend.test.ripple +94 -0
  51. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  52. package/tests/client/basic/basic.collections.test.ripple +7 -7
  53. package/tests/client/basic/basic.components.test.ripple +48 -10
  54. package/tests/client/basic/basic.errors.test.ripple +46 -31
  55. package/tests/client/basic/basic.events.test.ripple +11 -11
  56. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  57. package/tests/client/basic/basic.reactivity.test.ripple +47 -42
  58. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  59. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  60. package/tests/client/boundaries.test.ripple +7 -7
  61. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +2 -2
  62. package/tests/client/compiler/compiler.assignments.test.ripple +21 -21
  63. package/tests/client/compiler/compiler.basic.test.ripple +223 -82
  64. package/tests/client/compiler/compiler.tracked-access.test.ripple +8 -9
  65. package/tests/client/composite/composite.dynamic-components.test.ripple +8 -8
  66. package/tests/client/composite/composite.generics.test.ripple +4 -4
  67. package/tests/client/composite/composite.props.test.ripple +9 -9
  68. package/tests/client/composite/composite.reactivity.test.ripple +32 -26
  69. package/tests/client/composite/composite.render.test.ripple +13 -4
  70. package/tests/client/computed-properties.test.ripple +3 -3
  71. package/tests/client/context.test.ripple +3 -3
  72. package/tests/client/css/global-additional-cases.test.ripple +4 -4
  73. package/tests/client/css/style-identifier.test.ripple +49 -41
  74. package/tests/client/date.test.ripple +40 -40
  75. package/tests/client/dynamic-elements.test.ripple +165 -30
  76. package/tests/client/events.test.ripple +25 -25
  77. package/tests/client/for.test.ripple +76 -8
  78. package/tests/client/function-overload.test.ripple +0 -1
  79. package/tests/client/head.test.ripple +7 -7
  80. package/tests/client/html.test.ripple +2 -2
  81. package/tests/client/input-value.test.ripple +174 -176
  82. package/tests/client/map.test.ripple +21 -21
  83. package/tests/client/media-query.test.ripple +4 -4
  84. package/tests/client/object.test.ripple +12 -12
  85. package/tests/client/portal.test.ripple +4 -4
  86. package/tests/client/ref.test.ripple +5 -5
  87. package/tests/client/return.test.ripple +17 -17
  88. package/tests/client/set.test.ripple +16 -16
  89. package/tests/client/svg.test.ripple +6 -7
  90. package/tests/client/switch.test.ripple +10 -10
  91. package/tests/client/tracked-expression.test.ripple +1 -3
  92. package/tests/client/try.test.ripple +33 -4
  93. package/tests/client/url/url.derived.test.ripple +10 -9
  94. package/tests/client/url/url.parsing.test.ripple +10 -10
  95. package/tests/client/url/url.partial-removal.test.ripple +10 -10
  96. package/tests/client/url/url.reactivity.test.ripple +17 -17
  97. package/tests/client/url/url.serialization.test.ripple +4 -4
  98. package/tests/client/url-search-params/url-search-params.derived.test.ripple +11 -10
  99. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +5 -7
  100. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +13 -13
  101. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +19 -19
  102. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +17 -17
  103. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +5 -5
  104. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +5 -5
  105. package/tests/hydration/compiled/client/events.js +8 -11
  106. package/tests/hydration/compiled/client/for.js +20 -23
  107. package/tests/hydration/compiled/client/head.js +17 -19
  108. package/tests/hydration/compiled/client/hmr.js +1 -3
  109. package/tests/hydration/compiled/client/html.js +1 -15
  110. package/tests/hydration/compiled/client/if-children.js +7 -9
  111. package/tests/hydration/compiled/client/if.js +5 -7
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +3 -5
  113. package/tests/hydration/compiled/client/portal.js +1 -1
  114. package/tests/hydration/compiled/client/reactivity.js +9 -11
  115. package/tests/hydration/compiled/client/return.js +11 -13
  116. package/tests/hydration/compiled/client/switch.js +4 -6
  117. package/tests/hydration/compiled/server/basic.js +0 -1
  118. package/tests/hydration/compiled/server/composite.js +0 -3
  119. package/tests/hydration/compiled/server/events.js +8 -12
  120. package/tests/hydration/compiled/server/for.js +20 -23
  121. package/tests/hydration/compiled/server/head.js +17 -19
  122. package/tests/hydration/compiled/server/hmr.js +1 -4
  123. package/tests/hydration/compiled/server/html.js +1 -35
  124. package/tests/hydration/compiled/server/if-children.js +7 -11
  125. package/tests/hydration/compiled/server/if.js +5 -7
  126. package/tests/hydration/compiled/server/mixed-control-flow.js +3 -5
  127. package/tests/hydration/compiled/server/portal.js +1 -9
  128. package/tests/hydration/compiled/server/reactivity.js +9 -11
  129. package/tests/hydration/compiled/server/return.js +11 -13
  130. package/tests/hydration/compiled/server/switch.js +4 -6
  131. package/tests/hydration/components/events.ripple +8 -9
  132. package/tests/hydration/components/for.ripple +20 -21
  133. package/tests/hydration/components/head.ripple +6 -8
  134. package/tests/hydration/components/hmr.ripple +1 -2
  135. package/tests/hydration/components/html.ripple +1 -3
  136. package/tests/hydration/components/if-children.ripple +7 -8
  137. package/tests/hydration/components/if.ripple +5 -6
  138. package/tests/hydration/components/mixed-control-flow.ripple +4 -6
  139. package/tests/hydration/components/portal.ripple +1 -1
  140. package/tests/hydration/components/reactivity.ripple +9 -10
  141. package/tests/hydration/components/return.ripple +11 -12
  142. package/tests/hydration/components/switch.ripple +6 -8
  143. package/tests/server/await.test.ripple +2 -2
  144. package/tests/server/basic.attributes.test.ripple +19 -21
  145. package/tests/server/basic.components.test.ripple +13 -7
  146. package/tests/server/basic.test.ripple +20 -21
  147. package/tests/server/compiler.test.ripple +5 -5
  148. package/tests/server/composite.props.test.ripple +6 -7
  149. package/tests/server/composite.test.ripple +4 -4
  150. package/tests/server/context.test.ripple +1 -3
  151. package/tests/server/dynamic-elements.test.ripple +24 -24
  152. package/tests/server/head.test.ripple +5 -7
  153. package/tests/server/style-identifier.test.ripple +16 -17
  154. package/types/index.d.ts +266 -62
  155. package/types/server.d.ts +6 -6
@@ -1,5 +1,12 @@
1
- import type { Tracked, Props, PropsWithChildren, PropsWithExtras } from 'ripple';
2
- import { track, flushSync } from 'ripple';
1
+ import type {
2
+ Tracked,
3
+ Props,
4
+ PropsWithChildren,
5
+ PropsWithExtras,
6
+ Component,
7
+ PropsWithChildrenOptional,
8
+ } from 'ripple';
9
+ import { flushSync } from 'ripple';
3
10
 
4
11
  describe('basic client > components & composition', () => {
5
12
  it('renders with component composition and children', () => {
@@ -27,18 +34,48 @@ describe('basic client > components & composition', () => {
27
34
  });
28
35
 
29
36
  it('does not render a falsy component call', () => {
30
- component Card(props: PropsWithChildren<{}>) {
37
+ component Card(props: PropsWithChildrenOptional<{ test?: Component }>) {
31
38
  <div class="card">
32
- <props.children />
39
+ if (props.children) {
40
+ <props.children />
41
+ }
42
+ </div>
43
+ }
44
+
45
+ component Basic() {
46
+ <Card>
47
+ component test() {
48
+ <p>{'Card content here'}</p>
49
+ }
50
+ </Card>
51
+ }
52
+
53
+ render(Basic);
54
+
55
+ const card = container.querySelector('.card');
56
+ const paragraph = card.querySelector('p');
57
+
58
+ expect(card).toBeTruthy();
59
+ expect(paragraph).toBeFalsy();
60
+ });
61
+
62
+ it('allows tracked variable and slot component with same name in nested scope', () => {
63
+ component Card(props: PropsWithChildrenOptional<{ test?: Component }>) {
64
+ <div class="card">
65
+ if (props.children) {
66
+ <props.children />
67
+ }
33
68
  </div>
34
69
  }
35
70
 
36
71
  component Basic() {
72
+ let test = #ripple.track(false);
37
73
  <Card>
38
74
  component test() {
39
75
  <p>{'Card content here'}</p>
40
76
  }
41
77
  </Card>
78
+ <div>{@test ? 'yes' : 'no'}</div>
42
79
  }
43
80
 
44
81
  render(Basic);
@@ -48,6 +85,7 @@ describe('basic client > components & composition', () => {
48
85
 
49
86
  expect(card).toBeTruthy();
50
87
  expect(paragraph).toBeFalsy();
88
+ expect(container.textContent).toContain('no');
51
89
  });
52
90
 
53
91
  it('renders a component when children is set a component prop', () => {
@@ -96,7 +134,7 @@ describe('basic client > components & composition', () => {
96
134
  }
97
135
 
98
136
  component Basic() {
99
- let clicked = track(false);
137
+ let clicked = #ripple.track(false);
100
138
 
101
139
  <Card
102
140
  title="Test Card"
@@ -137,8 +175,8 @@ describe('basic client > components & composition', () => {
137
175
  }
138
176
 
139
177
  component Basic() {
140
- let message = track('Hello');
141
- let number = track(1);
178
+ let message = #ripple.track('Hello');
179
+ let number = #ripple.track(1);
142
180
 
143
181
  <ChildComponent text={message} count={number} />
144
182
  <button
@@ -176,14 +214,14 @@ describe('basic client > components & composition', () => {
176
214
  it('it retains this context with bracketed prop functions and keeps original chaining', () => {
177
215
  component App() {
178
216
  const SYMBOL_PROP = Symbol();
179
- let hasError = track(false);
217
+ let hasError = #ripple.track(false);
180
218
  const obj: {
181
219
  count: Tracked<number>;
182
220
  increment: () => void;
183
221
  [key: symbol]: () => void;
184
222
  arr: Array<() => void>;
185
223
  } = {
186
- count: track(0),
224
+ count: #ripple.track(0),
187
225
  increment() {
188
226
  this.@count++;
189
227
  },
@@ -364,7 +402,7 @@ describe('basic client > components & composition', () => {
364
402
  }
365
403
 
366
404
  component App() {
367
- let Content = track(() => Noop);
405
+ let Content = #ripple.track(() => Noop);
368
406
  <@Content />
369
407
 
370
408
  <button onClick={() => (@Content = Op)}>{'Show Op'}</button>
@@ -1,11 +1,11 @@
1
- import { track, flushSync, untrack } from 'ripple';
1
+ import { flushSync } from 'ripple';
2
2
  import { compile } from 'ripple/compiler';
3
3
 
4
4
  describe('basic client > errors', () => {
5
5
  it('renders with error handling simulation', () => {
6
6
  component Basic() {
7
- let hasError = track(false);
8
- let errorMessage = track('');
7
+ let hasError = #ripple.track(false);
8
+ let errorMessage = #ripple.track('');
9
9
 
10
10
  const triggerError = () => {
11
11
  try {
@@ -89,11 +89,11 @@ describe('basic client > errors', () => {
89
89
  );
90
90
  });
91
91
 
92
- it('errors on mutating tracked value inside computed track() evaluation', () => {
92
+ it('errors on mutating tracked value inside computed #ripple.track() evaluation', () => {
93
93
  component Basic() {
94
- let count = track(0);
94
+ let count = #ripple.track(0);
95
95
 
96
- const doubled = track(() => {
96
+ const doubled = #ripple.track(() => {
97
97
  try {
98
98
  @count *= 2;
99
99
  } catch (e) {
@@ -107,39 +107,42 @@ describe('basic client > errors', () => {
107
107
  render(Basic);
108
108
 
109
109
  expect(error).toBe(
110
- 'Assignments or updates to tracked values are not allowed during computed "track(() => ...)" evaluation',
110
+ 'Assignments or updates to tracked values are not allowed during computed "#ripple.track(() => ...)" evaluation',
111
111
  );
112
112
  });
113
113
 
114
- it('errors on mutating tracked value inside untrack() in computed track() evaluation', () => {
115
- component Basic() {
116
- let count = track(0);
114
+ it(
115
+ 'errors on mutating tracked value inside #ripple.untrack() in computed #ripple.track() evaluation',
116
+ () => {
117
+ component Basic() {
118
+ let count = #ripple.track(0);
119
+
120
+ const doubled = #ripple.track(() => {
121
+ try {
122
+ #ripple.untrack(() => {
123
+ @count *= 2;
124
+ });
125
+ } catch (e) {
126
+ error = (e as Error).message;
127
+ }
128
+ });
117
129
 
118
- const doubled = track(() => {
119
- try {
120
- untrack(() => {
121
- @count *= 2;
122
- });
123
- } catch (e) {
124
- error = (e as Error).message;
125
- }
126
- });
130
+ <p>{@doubled}</p>
131
+ }
127
132
 
128
- <p>{@doubled}</p>
129
- }
133
+ render(Basic);
130
134
 
131
- render(Basic);
135
+ expect(error).toBe(
136
+ 'Assignments or updates to tracked values are not allowed during computed "#ripple.track(() => ...)" evaluation',
137
+ );
138
+ },
139
+ );
132
140
 
133
- expect(error).toBe(
134
- 'Assignments or updates to tracked values are not allowed during computed "track(() => ...)" evaluation',
135
- );
136
- });
137
-
138
- it('errors on mutating a tracked variable in track() getter', () => {
141
+ it('errors on mutating a tracked variable in #ripple.track() getter', () => {
139
142
  component Basic() {
140
- let count = track(0);
143
+ let count = #ripple.track(0);
141
144
 
142
- const doubled = track(0, (value) => {
145
+ const doubled = #ripple.track(0, (value) => {
143
146
  try {
144
147
  @count += 1;
145
148
  } catch (e) {
@@ -154,7 +157,7 @@ describe('basic client > errors', () => {
154
157
  render(Basic);
155
158
 
156
159
  expect(error).toBe(
157
- 'Assignments or updates to tracked values are not allowed during computed "track(() => ...)" evaluation',
160
+ 'Assignments or updates to tracked values are not allowed during computed "#ripple.track(() => ...)" evaluation',
158
161
  );
159
162
  });
160
163
 
@@ -239,4 +242,16 @@ describe('basic client > errors', () => {
239
242
  compile(code, 'test.ripple');
240
243
  }).not.toThrow();
241
244
  });
245
+
246
+ it('should throw error for variables using the reserved _$_ prefix', () => {
247
+ const code = `
248
+ export default component App() {
249
+ const _$_test = 'hello';
250
+ <div>{_$_test}</div>
251
+ }
252
+ `;
253
+ expect(() => {
254
+ compile(code, 'test.ripple');
255
+ }).toThrow('identifiers starting with "_$_" are reserved');
256
+ });
242
257
  });
@@ -1,11 +1,11 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { track, flushSync } from 'ripple';
2
+ import { flushSync } from 'ripple';
3
3
 
4
4
  describe('basic client > events', () => {
5
5
  it('renders with different event types', () => {
6
6
  component Basic() {
7
- let focusCount = track(0);
8
- let clickCount = track(0);
7
+ let focusCount = #ripple.track(0);
8
+ let clickCount = #ripple.track(0);
9
9
 
10
10
  <button
11
11
  onFocus={() => {
@@ -38,8 +38,8 @@ describe('basic client > events', () => {
38
38
 
39
39
  it('renders with capture events', () => {
40
40
  component Basic() {
41
- let captureClicks = track(0);
42
- let bubbleClicks = track(0);
41
+ let captureClicks = #ripple.track(0);
42
+ let bubbleClicks = #ripple.track(0);
43
43
 
44
44
  <div
45
45
  onClick={{
@@ -76,7 +76,7 @@ describe('basic client > events', () => {
76
76
 
77
77
  it('renders with event listeners in spread props', () => {
78
78
  component Basic() {
79
- let count = track(0);
79
+ let count = #ripple.track(0);
80
80
 
81
81
  const minus = {
82
82
  onClick() {
@@ -125,8 +125,8 @@ describe('basic client > events', () => {
125
125
 
126
126
  it('handles both delegated and non-delegated events in spread props', () => {
127
127
  component Basic() {
128
- let clickCount = track(0);
129
- let focusCount = track(0);
128
+ let clickCount = #ripple.track(0);
129
+ let focusCount = #ripple.track(0);
130
130
 
131
131
  const mixedHandler = {
132
132
  onClick() {
@@ -168,9 +168,9 @@ describe('basic client > events', () => {
168
168
 
169
169
  it('renders with complex event handling and state updates', () => {
170
170
  component Basic() {
171
- let counter = track(0);
172
- let history = track<string[]>([]);
173
- let isEven = track(true);
171
+ let counter = #ripple.track(0);
172
+ let history = #ripple.track<string[]>([]);
173
+ let isEven = #ripple.track(true);
174
174
 
175
175
  const handleIncrement = () => {
176
176
  @counter++;
@@ -1,9 +1,9 @@
1
- import { track, flushSync, get, set, effect, untrack } from 'ripple';
1
+ import { flushSync, get, set } from 'ripple';
2
2
 
3
3
  describe('basic client > get/set functions', () => {
4
4
  it('gets tracked value', () => {
5
5
  component Test() {
6
- let count = track(0);
6
+ let count = #ripple.track(0);
7
7
 
8
8
  <div>{get(count)}</div>
9
9
  }
@@ -16,7 +16,7 @@ describe('basic client > get/set functions', () => {
16
16
 
17
17
  it('gets tracked value after mutation', () => {
18
18
  component Test() {
19
- let count = track(0);
19
+ let count = #ripple.track(0);
20
20
 
21
21
  <p>{get(count)}</p>
22
22
  <button onClick={() => @count++}>{'increment'}</button>
@@ -36,7 +36,7 @@ describe('basic client > get/set functions', () => {
36
36
 
37
37
  it('gets tracked value after multiple mutations', () => {
38
38
  component Test() {
39
- let count = track(0);
39
+ let count = #ripple.track(0);
40
40
 
41
41
  <p>{get(count)}</p>
42
42
  <button
@@ -64,7 +64,7 @@ describe('basic client > get/set functions', () => {
64
64
 
65
65
  it('sets tracked value', () => {
66
66
  component Test() {
67
- let count = track(0);
67
+ let count = #ripple.track(0);
68
68
 
69
69
  <p>{get(count)}</p>
70
70
  <button onClick={() => set(count, 10)}>{'set to 10'}</button>
@@ -84,7 +84,7 @@ describe('basic client > get/set functions', () => {
84
84
 
85
85
  it('sets tracked value multiple times', () => {
86
86
  component Test() {
87
- let count = track(0);
87
+ let count = #ripple.track(0);
88
88
 
89
89
  <p>{get(count)}</p>
90
90
  <button
@@ -112,7 +112,7 @@ describe('basic client > get/set functions', () => {
112
112
 
113
113
  it('sets tracked value based on previous value', () => {
114
114
  component Test() {
115
- let count = track(0);
115
+ let count = #ripple.track(0);
116
116
 
117
117
  <p>{get(count)}</p>
118
118
  <button onClick={() => set(count, get(count) + 10)}>{'add 10'}</button>
@@ -138,7 +138,7 @@ describe('basic client > get/set functions', () => {
138
138
 
139
139
  it('sets tracked value multiple times based on previous value', () => {
140
140
  component Test() {
141
- let count = track(0);
141
+ let count = #ripple.track(0);
142
142
 
143
143
  <p>{get(count)}</p>
144
144
  <button
@@ -172,7 +172,7 @@ describe('basic client > get/set functions', () => {
172
172
 
173
173
  it('gets value declared outside Ripple component', () => {
174
174
  function store() {
175
- return track(0);
175
+ return #ripple.track(0);
176
176
  }
177
177
 
178
178
  component Test() {
@@ -188,7 +188,7 @@ describe('basic client > get/set functions', () => {
188
188
 
189
189
  it('sets value declared outside Ripple component', () => {
190
190
  function store() {
191
- return track(0);
191
+ return #ripple.track(0);
192
192
  }
193
193
 
194
194
  component Test() {
@@ -212,10 +212,10 @@ describe('basic client > get/set functions', () => {
212
212
 
213
213
  it('works with effects', () => {
214
214
  component Test() {
215
- let count = track(0);
216
- let double = track(0);
215
+ let count = #ripple.track(0);
216
+ let double = #ripple.track(0);
217
217
 
218
- effect(() => {
218
+ #ripple.effect(() => {
219
219
  set(double, get(count) * 2);
220
220
  });
221
221
 
@@ -242,11 +242,11 @@ describe('basic client > get/set functions', () => {
242
242
 
243
243
  it('works with effects and untrack', () => {
244
244
  component Test() {
245
- let count = track(0);
246
- let double = track(0);
245
+ let count = #ripple.track(0);
246
+ let double = #ripple.track(0);
247
247
 
248
- effect(() => {
249
- untrack(() => {
248
+ #ripple.effect(() => {
249
+ #ripple.untrack(() => {
250
250
  set(double, get(count) * 2);
251
251
  });
252
252
  });
@@ -274,6 +274,6 @@ describe('basic client > get/set functions', () => {
274
274
  });
275
275
 
276
276
  it('throws on trying to create tracked Ripple component', () => {
277
- expect(() => track(0)).toThrow();
277
+ expect(() => #ripple.track(0)).toThrow();
278
278
  });
279
279
  });
@@ -1,18 +1,19 @@
1
- import { track, trackSplit, flushSync, effect, untrack } from 'ripple';
1
+ import type { PropsWithChildren, Tracked } from 'ripple';
2
+ import { flushSync } from 'ripple';
2
3
 
3
4
  describe('basic client > reactivity', () => {
4
5
  it('renders multiple reactive lexical blocks', () => {
5
6
  component Basic() {
6
7
  <div>
7
8
  let obj = {
8
- count: track(0),
9
+ count: #ripple.track(0),
9
10
  };
10
11
 
11
12
  <span>{obj.@count}</span>
12
13
  </div>
13
14
  <div>
14
15
  let b = {
15
- count: track(0),
16
+ count: #ripple.track(0),
16
17
  };
17
18
 
18
19
  <button
@@ -53,27 +54,27 @@ describe('basic client > reactivity', () => {
53
54
 
54
55
  <div>
55
56
  let obj = {
56
- count: track(0),
57
+ count: #ripple.track(0),
57
58
  };
58
59
 
59
- <span>{obj[@count]}</span>
60
+ <span>{obj.@[count]}</span>
60
61
  </div>
61
62
  <div>
62
63
  let b = {
63
- count: track(0),
64
+ count: #ripple.track(0),
64
65
  };
65
66
 
66
67
  <button
67
68
  onClick={() => {
68
- b[@count]--;
69
+ b.@[count]--;
69
70
  }}
70
71
  >
71
72
  {'-'}
72
73
  </button>
73
- <span class="count">{b[@count]}</span>
74
+ <span class="count">{b.@[count]}</span>
74
75
  <button
75
76
  onClick={() => {
76
- b[@count]++;
77
+ b.@[count]++;
77
78
  }}
78
79
  >
79
80
  {'+'}
@@ -97,7 +98,7 @@ describe('basic client > reactivity', () => {
97
98
 
98
99
  it('renders with computed reactive state', () => {
99
100
  component Basic() {
100
- let count = track(5);
101
+ let count = #ripple.track(5);
101
102
 
102
103
  <div class="count">{@count}</div>
103
104
  <div class="doubled">{@count * 2}</div>
@@ -134,11 +135,11 @@ describe('basic client > reactivity', () => {
134
135
  let logs: string[] = [];
135
136
 
136
137
  component App() {
137
- let first = track(0);
138
- let second = track(0);
138
+ let first = #ripple.track(0);
139
+ let second = #ripple.track(0);
139
140
  const arr = [first, second];
140
141
 
141
- const total = track(() => arr.reduce((a, b) => a + @b, 0));
142
+ const total = #ripple.track(() => arr.reduce((a, b) => a + @b, 0));
142
143
 
143
144
  <button
144
145
  onClick={() => {
@@ -155,7 +156,7 @@ describe('basic client > reactivity', () => {
155
156
  {'second: ' + @second}
156
157
  </button>
157
158
 
158
- effect(() => {
159
+ #ripple.effect(() => {
159
160
  let _arr: number[] = [];
160
161
 
161
162
  arr.forEach((item) => {
@@ -165,7 +166,7 @@ describe('basic client > reactivity', () => {
165
166
  logs.push(_arr.join(', '));
166
167
  });
167
168
 
168
- effect(() => {
169
+ #ripple.effect(() => {
169
170
  if (arr.map((a) => @a).includes(1)) {
170
171
  logs.push('arr includes 1');
171
172
  }
@@ -210,7 +211,7 @@ describe('basic client > reactivity', () => {
210
211
 
211
212
  it('uses track get and set where both mutate value', () => {
212
213
  component App() {
213
- let count = track(0, (v) => v + 1, (v) => v * 2);
214
+ let count = #ripple.track(0, (v) => v + 1, (v) => v * 2);
214
215
 
215
216
  <div class="count">{@count}</div>
216
217
  <button
@@ -236,7 +237,7 @@ describe('basic client > reactivity', () => {
236
237
 
237
238
  it('uses track get and set where set only mutates value', () => {
238
239
  component App() {
239
- let count = track(1, (v) => v, (v) => v * 2);
240
+ let count = #ripple.track(1, (v) => v, (v) => v * 2);
240
241
 
241
242
  <div class="count">{@count}</div>
242
243
  <button
@@ -262,7 +263,7 @@ describe('basic client > reactivity', () => {
262
263
 
263
264
  it('uses track get and set where get only mutates value', () => {
264
265
  component App() {
265
- let count = track(0, (v) => v + 1, (v) => v);
266
+ let count = #ripple.track(0, (v) => v + 1, (v) => v);
266
267
 
267
268
  <div class="count">{@count}</div>
268
269
  <button
@@ -290,7 +291,7 @@ describe('basic client > reactivity', () => {
290
291
  let logs: number[] = [];
291
292
 
292
293
  component App() {
293
- let count = track(0, (v) => v, (next, prev) => {
294
+ let count = #ripple.track(0, (v) => v, (next, prev) => {
294
295
  logs.push(prev, next);
295
296
  return next;
296
297
  });
@@ -313,11 +314,11 @@ describe('basic client > reactivity', () => {
313
314
  expect(logs).toEqual([0, 1]);
314
315
  });
315
316
 
316
- it('doesn\'t error on mutating a tracked variable in track() setter', () => {
317
+ it('doesn\'t error on mutating a tracked variable in #ripple.track() setter', () => {
317
318
  component Basic() {
318
- let count = track(0);
319
+ let count = #ripple.track(0);
319
320
 
320
- const doubled = track(0, undefined, (value) => {
321
+ const doubled = #ripple.track(0, undefined, (value) => {
321
322
  @count += value;
322
323
  return value;
323
324
  });
@@ -334,9 +335,9 @@ describe('basic client > reactivity', () => {
334
335
  let state: { count?: number } = {};
335
336
 
336
337
  component Basic() {
337
- let count = track(0);
338
+ let count = #ripple.track(0);
338
339
 
339
- effect(() => {
340
+ #ripple.effect(() => {
340
341
  state.count = @count;
341
342
  });
342
343
  }
@@ -358,10 +359,10 @@ describe('basic client > reactivity', () => {
358
359
  } = {};
359
360
 
360
361
  component Basic() {
361
- let count = track(5);
362
+ let count = #ripple.track(5);
362
363
 
363
- effect(() => {
364
- untrack(() => {
364
+ #ripple.effect(() => {
365
+ #ripple.untrack(() => {
365
366
  state.initialValue = @count;
366
367
  state.preIncrement = ++@count;
367
368
  state.postIncrement = @count++;
@@ -386,10 +387,10 @@ describe('basic client > reactivity', () => {
386
387
  describe('track/trackSplit APIs', () => {
387
388
  it('errors on invalid value as null for track with trackSplit', () => {
388
389
  component App() {
389
- let message = track('');
390
+ let message = #ripple.track('');
390
391
 
391
392
  try {
392
- const [a, b, rest] = trackSplit(null, ['a', 'b']);
393
+ const [a, b, rest] = #ripple.trackSplit(null, ['a', 'b']);
393
394
  } catch (e) {
394
395
  @message = (e as Error).message;
395
396
  }
@@ -405,10 +406,10 @@ describe('basic client > reactivity', () => {
405
406
 
406
407
  it('errors on invalid value as array for track with trackSplit', () => {
407
408
  component App() {
408
- let message = track('');
409
+ let message = #ripple.track('');
409
410
 
410
411
  try {
411
- const [a, b, rest] = trackSplit([1, 2, 3], ['a', 'b']);
412
+ const [a, b, rest] = #ripple.trackSplit([1, 2, 3], ['a', 'b']);
412
413
  } catch (e) {
413
414
  @message = (e as Error).message;
414
415
  }
@@ -424,11 +425,11 @@ describe('basic client > reactivity', () => {
424
425
 
425
426
  it('errors on invalid value as tracked for track with trackSplit', () => {
426
427
  component App() {
427
- const t = track({ a: 1, b: 2, c: 3 });
428
- let message = track('');
428
+ const t = #ripple.track({ a: 1, b: 2, c: 3 });
429
+ let message = #ripple.track('');
429
430
 
430
431
  try {
431
- const [a, b, rest] = trackSplit(t, ['a', 'b']);
432
+ const [a, b, rest] = #ripple.trackSplit(t, ['a', 'b']);
432
433
  } catch (e) {
433
434
  @message = (e as Error).message;
434
435
  }
@@ -444,7 +445,7 @@ describe('basic client > reactivity', () => {
444
445
 
445
446
  it('returns undefined for non-existent props in track with trackSplit', () => {
446
447
  component App() {
447
- const [a, b, rest] = trackSplit({ a: 1, c: 1 }, ['a', 'b']);
448
+ const [a, b, rest] = #ripple.trackSplit({ a: 1, c: 1 }, ['a', 'b']);
448
449
 
449
450
  <pre>{@a}</pre>
450
451
  <pre>{String(@b)}</pre>
@@ -464,8 +465,8 @@ describe('basic client > reactivity', () => {
464
465
 
465
466
  it('returns the same tracked object if plain track is called with a tracked object', () => {
466
467
  component App() {
467
- const t = track({ a: 1, b: 2, c: 3 });
468
- const doublet = track(t);
468
+ const t = #ripple.track({ a: 1, b: 2, c: 3 });
469
+ const doublet = #ripple.track(t);
469
470
 
470
471
  <pre>{t === doublet}</pre>
471
472
  }
@@ -480,8 +481,8 @@ describe('basic client > reactivity', () => {
480
481
  let logs: string[] = [];
481
482
 
482
483
  component App() {
483
- let count = track(0);
484
- let name = track('Click Me');
484
+ let count = #ripple.track(0);
485
+ let name = #ripple.track('Click Me');
485
486
 
486
487
  function buttonRef(el: HTMLButtonElement) {
487
488
  logs.push('ref called');
@@ -493,7 +494,7 @@ describe('basic client > reactivity', () => {
493
494
  <Child
494
495
  class="my-button"
495
496
  onClick={() => @name === 'Click Me' ? @name = 'Clicked' : @name = 'Click Me'}
496
- {@count}
497
+ {count}
497
498
  {ref buttonRef}
498
499
  >
499
500
  {@name}
@@ -502,8 +503,12 @@ describe('basic client > reactivity', () => {
502
503
  <button onClick={() => @count++}>{'Increment Count'}</button>
503
504
  }
504
505
 
505
- component Child(props: PropsWithChildren<{ count: Tracked<number> }>) {
506
- const [children, count, rest] = trackSplit(props, ['children', 'count']);
506
+ component Child(props: PropsWithChildren<{
507
+ count: Tracked<number>;
508
+ class: string;
509
+ onClick: () => void;
510
+ }>) {
511
+ const [children, count, rest] = #ripple.trackSplit(props, ['children', 'count']);
507
512
 
508
513
  if (@count < 2) {
509
514
  <button {...@rest}>