ripple 0.2.45 → 0.2.47

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/compiler/phases/1-parse/index.js +8 -1
  3. package/src/compiler/phases/2-analyze/index.js +640 -650
  4. package/src/compiler/phases/3-transform/index.js +1877 -1813
  5. package/src/compiler/phases/3-transform/segments.js +2 -2
  6. package/src/compiler/utils.js +600 -523
  7. package/src/jsx-runtime.js +12 -12
  8. package/src/runtime/array.js +611 -609
  9. package/src/runtime/index.js +29 -17
  10. package/src/runtime/internal/client/array.js +128 -128
  11. package/src/runtime/internal/client/blocks.js +206 -207
  12. package/src/runtime/internal/client/constants.js +2 -2
  13. package/src/runtime/internal/client/context.js +40 -40
  14. package/src/runtime/internal/client/events.js +191 -191
  15. package/src/runtime/internal/client/for.js +355 -355
  16. package/src/runtime/internal/client/if.js +25 -25
  17. package/src/runtime/internal/client/index.js +57 -52
  18. package/src/runtime/internal/client/operations.js +32 -32
  19. package/src/runtime/internal/client/portal.js +20 -20
  20. package/src/runtime/internal/client/render.js +132 -132
  21. package/src/runtime/internal/client/runtime.js +858 -824
  22. package/src/runtime/internal/client/template.js +36 -36
  23. package/src/runtime/internal/client/try.js +113 -113
  24. package/src/runtime/internal/client/types.d.ts +10 -10
  25. package/src/runtime/internal/client/utils.js +5 -5
  26. package/src/runtime/map.js +139 -139
  27. package/src/runtime/set.js +130 -130
  28. package/src/utils/ast.js +189 -189
  29. package/src/utils/builders.js +244 -244
  30. package/src/utils/sanitize_template_string.js +1 -1
  31. package/tests/__snapshots__/composite.test.ripple.snap +1 -1
  32. package/tests/accessors-props.test.ripple +9 -9
  33. package/tests/basic.test.ripple +4 -4
  34. package/tests/boundaries.test.ripple +17 -17
  35. package/tests/composite.test.ripple +43 -72
  36. package/types/index.d.ts +6 -2
@@ -3,5 +3,5 @@
3
3
  * @returns {string}
4
4
  */
5
5
  export function sanitize_template_string(str) {
6
- return str.replace(/(`|\${|\\)/g, '\\$1');
6
+ return str.replace(/(`|\${|\\)/g, '\\$1');
7
7
  }
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`composite components > correct handles passing through component props and $children 1`] = `
3
+ exports[`composite components > correct handles passing through component props and children 1`] = `
4
4
  <div>
5
5
  <!---->
6
6
  <div>
@@ -71,16 +71,16 @@ describe('prop accessors', () => {
71
71
 
72
72
  component Child(props) {
73
73
  effect(() => {
74
- logs.push('App effect', props.$foo);
74
+ logs.push('App effect', props.foo);
75
75
  });
76
76
 
77
- <button onClick={() => props.$foo++}>{"Increment foo"}</button>
77
+ <button onClick={() => props.foo++}>{"Increment foo"}</button>
78
78
  }
79
79
 
80
80
  component App(props) {
81
81
  let $foo = 0;
82
82
 
83
- <Child $foo:={() => {
83
+ <Child foo:={() => {
84
84
  return $foo;
85
85
  }, v => {
86
86
  // do not update parent
@@ -103,19 +103,19 @@ describe('prop accessors', () => {
103
103
  flushSync();
104
104
 
105
105
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 0');
106
- expect(logs).toEqual(['App effect', 0, 'App effect', 1]);
106
+ expect(logs).toEqual(['App effect', 0]);
107
107
 
108
108
  button2.click();
109
109
  flushSync();
110
110
 
111
111
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 1');
112
- expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 1]);
112
+ expect(logs).toEqual(['App effect', 0, 'App effect', 1]);
113
113
 
114
114
  button2.click();
115
115
  flushSync();
116
116
 
117
117
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 2');
118
- expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 1, 'App effect', 2]);
118
+ expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 2]);
119
119
  });
120
120
 
121
121
 
@@ -123,13 +123,13 @@ describe('prop accessors', () => {
123
123
  component Parent() {
124
124
  let $value = 123;
125
125
 
126
- <Child $value:={() => $value} />
126
+ <Child value:={() => $value} />
127
127
 
128
128
  <button onClick={() => $value++}>{"Increment value"}</button>
129
129
  }
130
130
 
131
- component Child({ $value }) {
132
- <div>{$value}</div>
131
+ component Child({ value }) {
132
+ <div>{value}</div>
133
133
  }
134
134
 
135
135
  render(Parent);
@@ -89,15 +89,15 @@ describe('basic', () => {
89
89
  });
90
90
 
91
91
  it('render tick template literal for nested children', () => {
92
- component Child({ $level, $children }) {
92
+ component Child({ $level, children }) {
93
93
  if($level == 1) {
94
- <h1><$children /></h1>
94
+ <h1><children /></h1>
95
95
  }
96
96
  if($level == 2) {
97
- <h2><$children /></h2>
97
+ <h2><children /></h2>
98
98
  }
99
99
  if($level == 3) {
100
- <h3><$children /></h3>
100
+ <h3><children /></h3>
101
101
  }
102
102
  }
103
103
 
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, flushSync, effect } from 'ripple';
2
+ import { mount, flushSync, effect, track } from 'ripple';
3
3
 
4
4
  describe('passing reactivity between boundaries tests', () => {
5
5
  let container;
@@ -23,23 +23,23 @@ describe('passing reactivity between boundaries tests', () => {
23
23
  it('can pass reactivity between functions with simple arrays and destructuring', () => {
24
24
  let log: string[] = [];
25
25
 
26
- function createDouble([ $count ]) {
27
- const $double = $count * 2;
26
+ function createDouble([ count ]) {
27
+ const double = track(() => @count * 2);
28
28
 
29
29
  effect(() => {
30
- log.push('Count:' + $count);
30
+ log.push('Count:' + @count);
31
31
  });
32
32
 
33
- return [ $double ];
33
+ return [ double ];
34
34
  }
35
35
 
36
36
  component App() {
37
- let $count = 0;
37
+ let count = track(0);
38
38
 
39
- const [ $double ] = createDouble([ $count ]);
39
+ const [ double ] = createDouble([ count ]);
40
40
 
41
- <div>{'Double: ' + $double}</div>
42
- <button onClick={() => { $count++; }}>{'Increment'}</button>
41
+ <div>{'Double: ' + @double}</div>
42
+ <button onClick={() => { @count++; }}>{'Increment'}</button>
43
43
  }
44
44
 
45
45
  render(App);
@@ -66,23 +66,23 @@ describe('passing reactivity between boundaries tests', () => {
66
66
  it('can pass reactivity between functions with simple objects and destructuring', () => {
67
67
  let log: string[] = [];
68
68
 
69
- function createDouble({ $count }) {
70
- const $double = $count * 2;
69
+ function createDouble({ count }) {
70
+ const double = track(() => @count * 2);
71
71
 
72
72
  effect(() => {
73
- log.push('Count:' + $count);
73
+ log.push('Count:' + @count);
74
74
  });
75
75
 
76
- return { $double };
76
+ return { double };
77
77
  }
78
78
 
79
79
  component App() {
80
- let $count = 0;
80
+ let count = track(0);
81
81
 
82
- const { $double } = createDouble({ $count });
82
+ const { double } = createDouble({ count });
83
83
 
84
- <div>{'Double: ' + $double}</div>
85
- <button onClick={() => { $count++; }}>{'Increment'}</button>
84
+ <div>{'Double: ' + @double}</div>
85
+ <button onClick={() => { @count++; }}>{'Increment'}</button>
86
86
  }
87
87
 
88
88
  render(App);
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, flushSync } from 'ripple';
2
+ import { mount, flushSync, track } from 'ripple';
3
3
 
4
4
  describe('composite components', () => {
5
5
  let container;
@@ -21,15 +21,15 @@ describe('composite components', () => {
21
21
  });
22
22
 
23
23
  it('renders composite components', () => {
24
- component Button({ $count }) {
25
- <div>{$count}</div>
24
+ component Button({ count }) {
25
+ <div>{count}</div>
26
26
  }
27
27
 
28
28
  component App() {
29
- let $count = 0;
29
+ let count = track(0);
30
30
 
31
- <button onClick={() => $count++}>{'Increment'}</button>
32
- <Button $count={$count} />
31
+ <button onClick={() => @count++}>{'Increment'}</button>
32
+ <Button {@count} />
33
33
  }
34
34
 
35
35
  render(App);
@@ -50,48 +50,17 @@ describe('composite components', () => {
50
50
  it('renders composite components with object state', () => {
51
51
  component Button({ obj }) {
52
52
  <button class='count2' onClick={() => {
53
- obj.$count++;
54
- }}>{obj.$count}</button>
53
+ obj.@count++;
54
+ }}>{obj.@count}</button>
55
55
  }
56
56
 
57
57
  component App() {
58
58
  <div>
59
59
  let obj = {
60
- $count: 0
60
+ count: track(0)
61
61
  };
62
- let $button = true;
63
62
 
64
- <span class='count'>{obj.$count}</span>
65
- <span>{' '}</span>
66
- <Button obj={obj} />
67
- </div>
68
- }
69
-
70
- render(App);
71
-
72
- const button = container.querySelector('button');
73
-
74
- button.click();
75
- flushSync();
76
-
77
- expect(container.querySelector('.count').textContent).toBe('1');
78
- expect(container.querySelector('.count2').textContent).toBe('1');
79
- });
80
-
81
- it('renders composite components with object state', () => {
82
- component Button({ obj }) {
83
- <button class='count2' onClick={() => {
84
- obj.$count++;
85
- }}>{obj.$count}</button>
86
- }
87
-
88
- component App() {
89
- <div>
90
- let obj = {
91
- $count: 0
92
- };
93
-
94
- <span class='count'>{obj.$count}</span>
63
+ <span class='count'>{obj.@count}</span>
95
64
  <Button obj={obj} />
96
65
  </div>
97
66
  }
@@ -110,21 +79,21 @@ describe('composite components', () => {
110
79
  it('renders composite components with object state wrapped in an if statement', () => {
111
80
  component Button({ obj }) {
112
81
  <button class='count2' onClick={() => {
113
- obj.$count++;
114
- }}>{obj.$count}</button>
82
+ obj.@count++;
83
+ }}>{obj.@count}</button>
115
84
  }
116
85
 
117
86
  component OtherComponent({ obj }) {
118
- <div class='count3'>{obj.$count}</div>
87
+ <div class='count3'>{obj.@count}</div>
119
88
  }
120
89
 
121
90
  component App() {
122
91
  <div>
123
92
  let obj = {
124
- $count: 0
93
+ count: track(0)
125
94
  };
126
95
 
127
- <span class='count'>{obj.$count}</span>
96
+ <span class='count'>{obj.@count}</span>
128
97
  <span>{' '}</span>
129
98
  if (obj) {
130
99
  <Button obj={obj} />
@@ -148,17 +117,18 @@ describe('composite components', () => {
148
117
  expect(container.querySelector('.count3').textContent).toBe('1');
149
118
  });
150
119
 
151
- it('parents and children have isolated but connected state', () => {
120
+ it('parents and children have isolated state', () => {
152
121
  component Button(props) {
153
- <button onClick={() => { props.$count++; } }>{"child: " + props.$count}</button>
122
+ let count = track(() => props.count);
123
+ <button onClick={() => { @count++; } }>{"child: " + @count}</button>
154
124
  }
155
125
 
156
126
  component App() {
157
127
  <div>
158
- let $count = 0;
128
+ let count = track(0);
159
129
 
160
- <button onClick={() => { $count++; } }>{"parent: " + $count}</button>
161
- <Button {$count} />
130
+ <button onClick={() => { @count++; } }>{"parent: " + @count}</button>
131
+ <Button {@count} />
162
132
  </div>
163
133
  }
164
134
 
@@ -182,17 +152,18 @@ describe('composite components', () => {
182
152
  expect(buttons[1].textContent).toBe('child: 2');
183
153
  });
184
154
 
185
- it('parents and children have isolated but connected state (destructured props)', () => {
186
- component Button({$count}) {
187
- <button onClick={() => { $count++; } }>{"child: " + $count}</button>
155
+ it('parents and children have isolated connected state (destructured props)', () => {
156
+ component Button({count}) {
157
+ let local_count = track(() => count);
158
+ <button onClick={() => { @local_count++; } }>{"child: " + @local_count}</button>
188
159
  }
189
160
 
190
161
  component App() {
191
162
  <div>
192
- let $count = 0;
163
+ let count = track(0);
193
164
 
194
- <button onClick={() => { $count++; } }>{"parent: " + $count}</button>
195
- <Button {$count} />
165
+ <button onClick={() => { @count++; } }>{"parent: " + @count}</button>
166
+ <Button {@count} />
196
167
  </div>
197
168
  }
198
169
 
@@ -216,11 +187,11 @@ describe('composite components', () => {
216
187
  expect(buttons[1].textContent).toBe('child: 2');
217
188
  });
218
189
 
219
- it('correct handles passing through component props and $children', () => {
220
- component Button({ A, B, $children }) {
190
+ it('correct handles passing through component props and children', () => {
191
+ component Button({ A, B, children }) {
221
192
  <div>
222
193
  <A />
223
- <$children />
194
+ <children />
224
195
  <B />
225
196
  </div>
226
197
  }
@@ -243,15 +214,15 @@ describe('composite components', () => {
243
214
  });
244
215
 
245
216
  it('correctly handles default prop values', () => {
246
- component Child({ $foo = 456 }) {
247
- <div>{$foo}</div>
217
+ component Child({ foo = 456 }) {
218
+ <div>{foo}</div>
248
219
  }
249
220
 
250
221
  component App(props) {
251
- let $foo = 123;
222
+ let foo = track(123);
252
223
 
253
224
  <Child />
254
- <Child {$foo} />
225
+ <Child {@foo} />
255
226
  }
256
227
 
257
228
  render(App);
@@ -260,7 +231,7 @@ describe('composite components', () => {
260
231
  expect(container.querySelectorAll('div')[1].textContent).toBe('123');
261
232
  });
262
233
 
263
- it('correctly handles default prop values #2', () => {
234
+ it('correctly handles default prop values #2', () => {
264
235
  component Child({ foo = 456 }) {
265
236
  <div>{foo}</div>
266
237
  }
@@ -280,14 +251,14 @@ describe('composite components', () => {
280
251
 
281
252
  it('correctly handles no props', () => {
282
253
  component Child(props) {
283
- <div>{props.$foo}</div>
254
+ <div>{props.@foo}</div>
284
255
  }
285
256
 
286
257
  component App(props) {
287
- let $foo = 123;
258
+ let foo = track(123);
288
259
 
289
260
  <Child />
290
- <Child {$foo} />
261
+ <Child {foo} />
291
262
  }
292
263
 
293
264
  render(App);
@@ -297,15 +268,15 @@ describe('composite components', () => {
297
268
  });
298
269
 
299
270
  it('correctly handles no props #2', () => {
300
- component Child({ $foo }) {
301
- <div>{$foo}</div>
271
+ component Child({ foo }) {
272
+ <div>{foo}</div>
302
273
  }
303
274
 
304
275
  component App(props) {
305
- let $foo = 123;
276
+ let foo = track(123);
306
277
 
307
278
  <Child />
308
- <Child {$foo} />
279
+ <Child {@foo} />
309
280
  }
310
281
 
311
282
  render(App);
package/types/index.d.ts CHANGED
@@ -74,10 +74,14 @@ declare global {
74
74
  computed<T>(fn: () => T, block?: any): T;
75
75
  scope(): any;
76
76
  get_tracked(node: any): any;
77
- get_computed(node: any): any;
77
+ get_derived(node: any): any;
78
78
  set(node: any, value: any, block?: any): any;
79
79
  // Add other runtime functions as needed for TypeScript analysis
80
80
  };
81
81
  }
82
82
 
83
- export declare function createRefKey(): symbol;
83
+ export declare function createRefKey(): symbol;
84
+
85
+ type Tracked<V> = {};
86
+
87
+ export declare function track<V>(value: V): Tracked<V>;