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
@@ -3,8 +3,9 @@ import { compile } from 'ripple/compiler';
3
3
  describe('Compiler: Tracked Object Direct Access Checks', () => {
4
4
  it('should error on direct access to __v of a tracked object', () => {
5
5
  const code = `
6
+ import { track } from 'ripple';
6
7
  export default component App() {
7
- let count = #ripple.track(0);
8
+ let count = track(0);
8
9
  console.log(count.__v);
9
10
  }
10
11
  `;
@@ -15,8 +16,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
15
16
 
16
17
  it('should error on direct access to "a" (get/set config) of a tracked object', () => {
17
18
  const code = `
19
+ import { track } from 'ripple';
18
20
  export default component App() {
19
- let myTracked = #ripple.track(0);
21
+ let myTracked = track(0);
20
22
  console.log(myTracked.a);
21
23
  }
22
24
  `;
@@ -27,8 +29,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
27
29
 
28
30
  it('should error on direct access to "b" (block) of a tracked object', () => {
29
31
  const code = `
32
+ import { track } from 'ripple';
30
33
  export default component App() {
31
- let myTracked = #ripple.track(0);
34
+ let myTracked = track(0);
32
35
  console.log(myTracked.b);
33
36
  }
34
37
  `;
@@ -39,8 +42,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
39
42
 
40
43
  it('should error on direct access to "c" (clock) of a tracked object', () => {
41
44
  const code = `
45
+ import { track } from 'ripple';
42
46
  export default component App() {
43
- let myTracked = #ripple.track(0);
47
+ let myTracked = track(0);
44
48
  console.log(myTracked.c);
45
49
  }
46
50
  `;
@@ -51,8 +55,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
51
55
 
52
56
  it('should error on direct access to "f" (flags) of a tracked object', () => {
53
57
  const code = `
58
+ import { track } from 'ripple';
54
59
  export default component App() {
55
- let myTracked = #ripple.track(0);
60
+ let myTracked = track(0);
56
61
  console.log(myTracked.f);
57
62
  }
58
63
  `;
@@ -63,8 +68,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
63
68
 
64
69
  it('should compile successfully with correct @ syntax access', () => {
65
70
  const code = `
71
+ import { track } from 'ripple';
66
72
  export default component App() {
67
- let count = #ripple.track(0);
73
+ let count = track(0);
68
74
  console.log(@count);
69
75
  }
70
76
  `;
@@ -73,9 +79,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
73
79
 
74
80
  it('should compile successfully with correct get() function access', () => {
75
81
  const code = `
76
- import { get } from 'ripple';
82
+ import { get, track } from 'ripple';
77
83
  export default component App() {
78
- let count = #ripple.track(0);
84
+ let count = track(0);
79
85
  console.log(get(count));
80
86
  }
81
87
  `;
@@ -25,4 +25,35 @@ function getString(e: string = 'test') {
25
25
 
26
26
  expect(result.js.code).toMatchSnapshot();
27
27
  });
28
+
29
+ it('removes class TypeScript syntax from JS output', () => {
30
+ const source = `interface BaseEvent {}
31
+
32
+ class PrintEvent implements BaseEvent {
33
+ text: string;
34
+
35
+ constructor(text: string) {
36
+ this.text = text;
37
+ }
38
+ }`;
39
+
40
+ const result = compile(source, 'test.ripple', { mode: 'client' });
41
+
42
+ expect(result.js.code).not.toContain('implements');
43
+ expect(result.js.code).toMatchSnapshot();
44
+ });
45
+
46
+ it('removes class extends type arguments from JS output', () => {
47
+ const source = `class StringMap extends Map<string, string> {
48
+ constructor() {
49
+ super();
50
+ }
51
+ }`;
52
+
53
+ const result = compile(source, 'test.ripple', { mode: 'client' });
54
+
55
+ expect(result.js.code).not.toContain('Map<string, string>');
56
+ expect(result.js.code).toContain('class StringMap extends Map');
57
+ expect(result.js.code).toMatchSnapshot();
58
+ });
28
59
  });
@@ -1,4 +1,4 @@
1
- import { flushSync } from 'ripple';
1
+ import { flushSync, track } from 'ripple';
2
2
 
3
3
  describe('composite > dynamic components', () => {
4
4
  it('supports rendering composite components using <@component> syntax', () => {
@@ -7,7 +7,7 @@ describe('composite > dynamic components', () => {
7
7
  <div>{'Basic Component'}</div>
8
8
  }
9
9
 
10
- const tracked_basic = #ripple.track(() => basic);
10
+ const tracked_basic = track(() => basic);
11
11
 
12
12
  <@tracked_basic />
13
13
  }
@@ -24,7 +24,7 @@ describe('composite > dynamic components', () => {
24
24
  <div>{'Basic Component'}</div>
25
25
  }
26
26
 
27
- const tracked_basic = #ripple.track(() => basic);
27
+ const tracked_basic = track(() => basic);
28
28
 
29
29
  const obj = {
30
30
  tracked_basic,
@@ -45,13 +45,13 @@ describe('composite > dynamic components', () => {
45
45
  <div>{'Basic Component'}</div>
46
46
  }
47
47
 
48
- const tracked_basic = #ripple.track(() => basic);
48
+ const tracked_basic = track(() => basic);
49
49
 
50
50
  const obj = {
51
51
  tracked_basic,
52
52
  };
53
53
 
54
- const ripple_object = #ripple.track(obj);
54
+ const ripple_object = track(obj);
55
55
 
56
56
  <@ripple_object.@tracked_basic />
57
57
  }
@@ -72,7 +72,7 @@ describe('composite > dynamic components', () => {
72
72
  }
73
73
 
74
74
  component App() {
75
- let thing = #ripple.track(() => Child1);
75
+ let thing = track(() => Child1);
76
76
 
77
77
  <div id="container">
78
78
  <@thing />
@@ -1,5 +1,5 @@
1
1
  import type { Tracked, Props } from 'ripple';
2
- import { flushSync } from 'ripple';
2
+ import { effect, flushSync, track, trackSplit } from 'ripple';
3
3
 
4
4
  describe('composite > props', () => {
5
5
  it('correctly handles default prop values', () => {
@@ -8,7 +8,7 @@ describe('composite > props', () => {
8
8
  }
9
9
 
10
10
  component App() {
11
- let foo = #ripple.track(123);
11
+ let foo = track(123);
12
12
 
13
13
  <Child />
14
14
  <Child {@foo} />
@@ -44,7 +44,7 @@ describe('composite > props', () => {
44
44
  }
45
45
 
46
46
  component App() {
47
- let foo = #ripple.track(123);
47
+ let foo = track(123);
48
48
 
49
49
  <Child />
50
50
  <Child {foo} />
@@ -62,7 +62,7 @@ describe('composite > props', () => {
62
62
  }
63
63
 
64
64
  component App() {
65
- let foo = #ripple.track(123);
65
+ let foo = track(123);
66
66
 
67
67
  <Child />
68
68
  <Child {@foo} />
@@ -78,7 +78,7 @@ describe('composite > props', () => {
78
78
  const logs: number[] = [];
79
79
 
80
80
  component Counter({ count }: { count: Tracked<number> }) {
81
- #ripple.effect(() => {
81
+ effect(() => {
82
82
  logs.push(@count);
83
83
  });
84
84
 
@@ -86,7 +86,7 @@ describe('composite > props', () => {
86
86
  }
87
87
 
88
88
  component App() {
89
- const count = #ripple.track(0);
89
+ const count = track(0);
90
90
 
91
91
  <div>
92
92
  <Counter {count} />
@@ -107,7 +107,7 @@ describe('composite > props', () => {
107
107
 
108
108
  it('correctly retains prop accessors and reactivity when using rest props', () => {
109
109
  component Button(props: Props) {
110
- const [children, rest] = #ripple.trackSplit(props, ['children']);
110
+ const [children, rest] = trackSplit(props, ['children']);
111
111
  <button {...@rest}>
112
112
  <@children />
113
113
  </button>
@@ -122,14 +122,14 @@ describe('composite > props', () => {
122
122
  }
123
123
 
124
124
  component Toggle(props: { pressed: Tracked<boolean> }) {
125
- const [pressed, rest] = #ripple.trackSplit(props, ['pressed']);
125
+ const [pressed, rest] = trackSplit(props, ['pressed']);
126
126
  const onClick = () => (@pressed = !@pressed);
127
127
  <Button {...@rest} class={@pressed ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
128
128
  <Button class={@pressed ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
129
129
  }
130
130
 
131
131
  component App() {
132
- const pressed = #ripple.track(true);
132
+ const pressed = track(true);
133
133
  <Toggle {pressed} />
134
134
  }
135
135
 
@@ -1,5 +1,5 @@
1
1
  import type { Props, Tracked } from 'ripple';
2
- import { flushSync } from 'ripple';
2
+ import { RippleObject, effect, flushSync, track, trackSplit } from 'ripple';
3
3
 
4
4
  describe('composite > reactivity', () => {
5
5
  it('renders composite components with object state', () => {
@@ -17,7 +17,7 @@ describe('composite > reactivity', () => {
17
17
  component App() {
18
18
  <div>
19
19
  let obj = {
20
- count: #ripple.track(0),
20
+ count: track(0),
21
21
  };
22
22
 
23
23
  <span class="count">{obj.@count}</span>
@@ -55,7 +55,7 @@ describe('composite > reactivity', () => {
55
55
  component App() {
56
56
  <div>
57
57
  let obj = {
58
- count: #ripple.track(0),
58
+ count: track(0),
59
59
  };
60
60
 
61
61
  <span class="count">{obj.@count}</span>
@@ -84,7 +84,7 @@ describe('composite > reactivity', () => {
84
84
 
85
85
  it('parents and children have isolated state', () => {
86
86
  component Button(props: { count: number }) {
87
- let count = #ripple.track(() => props.count);
87
+ let count = track(() => props.count);
88
88
  <button
89
89
  onClick={() => {
90
90
  @count++;
@@ -96,7 +96,7 @@ describe('composite > reactivity', () => {
96
96
 
97
97
  component App() {
98
98
  <div>
99
- let count = #ripple.track(0);
99
+ let count = track(0);
100
100
 
101
101
  <button
102
102
  onClick={() => {
@@ -130,8 +130,8 @@ describe('composite > reactivity', () => {
130
130
  });
131
131
 
132
132
  it('parents and children have isolated connected state (destructured props)', () => {
133
- component Button({ count }: { count: number }) {
134
- let local_count = #ripple.track(() => count);
133
+ component Button(&{ count }: { count: number }) {
134
+ let local_count = track(() => count);
135
135
  <button
136
136
  onClick={() => {
137
137
  @local_count++;
@@ -143,7 +143,7 @@ describe('composite > reactivity', () => {
143
143
 
144
144
  component App() {
145
145
  <div>
146
- let count = #ripple.track(0);
146
+ let count = track(0);
147
147
 
148
148
  <button
149
149
  onClick={() => {
@@ -180,11 +180,11 @@ describe('composite > reactivity', () => {
180
180
  let logs: string[] = [];
181
181
 
182
182
  component App() {
183
- const a = #ripple.track(1);
184
- const b = #ripple.track(2);
185
- const c = #ripple.track(3);
183
+ const a = track(1);
184
+ const b = track(2);
185
+ const c = track(3);
186
186
 
187
- const obj = #ripple.track(
187
+ const obj = track(
188
188
  () => ({
189
189
  @a,
190
190
  @b,
@@ -205,8 +205,8 @@ describe('composite > reactivity', () => {
205
205
  </button>
206
206
  }
207
207
 
208
- component Child({ a, b, c }: { a: number; b: number; c: number }) {
209
- #ripple.effect(() => {
208
+ component Child(&{ a, b, c }: { a: number; b: number; c: number }) {
209
+ effect(() => {
210
210
  logs.push(`Child effect: ${a}, ${b}, ${c}`);
211
211
  });
212
212
 
@@ -228,10 +228,10 @@ describe('composite > reactivity', () => {
228
228
  });
229
229
 
230
230
  it(
231
- 'keeps reactivity for spread props via intermediate components and usage of #ripple.trackSplit()',
231
+ 'keeps reactivity for spread props via intermediate components and usage of trackSplit()',
232
232
  () => {
233
233
  component App() {
234
- const count = #ripple.track(0);
234
+ const count = track(0);
235
235
  <CounterWrapper {@count} up={() => @count++} down={() => @count--} />
236
236
  }
237
237
 
@@ -242,7 +242,7 @@ describe('composite > reactivity', () => {
242
242
  }
243
243
 
244
244
  component Counter(props: Props) {
245
- const [count, up, down, rest] = #ripple.trackSplit(props, ['count', 'up', 'down']);
245
+ const [count, up, down, rest] = trackSplit(props, ['count', 'up', 'down']);
246
246
  <button onClick={() => @up()}>{'UP'}</button>
247
247
  <button onClick={() => @down()}>{'DOWN'}</button>
248
248
  <span {...@rest}>{`Counter: ${@count}`}</span>
@@ -270,18 +270,18 @@ describe('composite > reactivity', () => {
270
270
 
271
271
  it('keeps reactivity on elements for element spreads and adds / removes dynamic props', () => {
272
272
  component App() {
273
- const count = #ripple.track(0);
273
+ const count = track(0);
274
274
  <CounterWrapper {@count} up={() => @count++} />
275
275
  }
276
276
 
277
277
  component CounterWrapper(props: { count: number; up: () => void }) {
278
- const more: { double: Tracked<number>; another?: number; extra: number } = #ripple{
279
- double: #ripple.track(() => props.count * 2),
278
+ const more: { double: Tracked<number>; another?: number; extra: number } = new RippleObject({
279
+ double: track(() => props.count * 2),
280
280
  another: 0,
281
281
  extra: 100,
282
- };
282
+ });
283
283
 
284
- #ripple.effect(() => {
284
+ effect(() => {
285
285
  props.count;
286
286
  if (props.count === 1) {
287
287
  delete more.another;
@@ -302,7 +302,7 @@ describe('composite > reactivity', () => {
302
302
  another?: number;
303
303
  extra: number;
304
304
  }) {
305
- const [count, up, rest] = #ripple.trackSplit(props, ['count', 'up']);
305
+ const [count, up, rest] = trackSplit(props, ['count', 'up']);
306
306
  <div {...@rest}>{`Counter: ${@count} Double: ${props.@double}`}</div>
307
307
  <button onClick={() => @up()}>{'UP'}</button>
308
308
  }
@@ -1,13 +1,13 @@
1
- import { flushSync, RippleArray, type Component } from 'ripple';
1
+ import { RippleArray, flushSync, track, type Component } from 'ripple';
2
2
 
3
3
  describe('composite > render', () => {
4
4
  it('renders composite components', () => {
5
- component Button({ count }: { count: number }) {
5
+ component Button(&{ count }: { count: number }) {
6
6
  <div>{count}</div>
7
7
  }
8
8
 
9
9
  component App() {
10
- let count = #ripple.track(0);
10
+ let count = track(0);
11
11
 
12
12
  <button onClick={() => @count++}>{'Increment'}</button>
13
13
  <Button {@count} />
@@ -71,6 +71,54 @@ describe('composite > render', () => {
71
71
  expect(container).toMatchSnapshot();
72
72
  });
73
73
 
74
+ it('preserves distinct scoped ripple hashes for wrapper and child content', () => {
75
+ component App() {
76
+ component Wrapper({ children }) {
77
+ <div class="green">
78
+ {'Wrapper'}
79
+ <children />
80
+ </div>
81
+
82
+ <style>
83
+ .green {
84
+ color: green;
85
+ }
86
+ </style>
87
+ }
88
+
89
+ component Child() {
90
+ <div class="red">{'Child'}</div>
91
+
92
+ <style>
93
+ .red {
94
+ color: red;
95
+ }
96
+ </style>
97
+ }
98
+
99
+ <Wrapper>
100
+ <Child />
101
+ </Wrapper>
102
+ }
103
+
104
+ render(App);
105
+
106
+ const wrapper = container.querySelector('.green');
107
+ const child = container.querySelector('.red');
108
+ const wrapper_scopes = Array.from(wrapper.classList).filter(
109
+ (name) => name.startsWith('ripple-'),
110
+ );
111
+ const child_scopes = Array.from(child.classList).filter((name) => name.startsWith('ripple-'));
112
+
113
+ expect(wrapper_scopes).toHaveLength(1);
114
+ expect(child_scopes).toHaveLength(1);
115
+
116
+ const wrapper_scope = wrapper_scopes[0];
117
+ const child_scope = child_scopes.find((name) => name !== wrapper_scope) || child_scopes[0];
118
+
119
+ expect(wrapper_scope).not.toBe(child_scope);
120
+ });
121
+
74
122
  it('handles generics', () => {
75
123
  component ArrayTest() {
76
124
  let items = new RippleArray<number>();
@@ -83,7 +131,7 @@ describe('composite > render', () => {
83
131
  });
84
132
 
85
133
  it('should not render <undefined> tag when a passed in component is undefined', () => {
86
- component Child({
134
+ component Child(&{
87
135
  children,
88
136
  NonExistent,
89
137
  ...props
@@ -1,10 +1,10 @@
1
- import { flushSync } from 'ripple';
1
+ import { flushSync, track } from 'ripple';
2
2
 
3
3
  describe('computed tracked properties', () => {
4
4
  it('should update a property using assignment', () => {
5
5
  component App() {
6
6
  let obj = {
7
- [0]: #ripple.track(0),
7
+ [0]: track(0),
8
8
  };
9
9
 
10
10
  <div>{obj.@[0]}</div>
@@ -31,7 +31,7 @@ describe('computed tracked properties', () => {
31
31
  it('should update a property using update expressions', () => {
32
32
  component App() {
33
33
  let obj = {
34
- [0]: #ripple.track(0),
34
+ [0]: track(0),
35
35
  };
36
36
 
37
37
  <div>{obj.@[0]}</div>
@@ -1,9 +1,9 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { flushSync } from 'ripple';
2
+ import { Context, flushSync } from 'ripple';
3
3
 
4
4
  describe('context', () => {
5
5
  it('creates a reactive ref with initial value', () => {
6
- const MyContext = #ripple.context<string | null>(null);
6
+ const MyContext = Context<string | null>(null);
7
7
 
8
8
  component Child() {
9
9
  const value = MyContext.get();
@@ -25,7 +25,7 @@ describe('context', () => {
25
25
  });
26
26
 
27
27
  it('handles context captured inside a computed tracked', () => {
28
- const MyContext = #ripple.context<number | null>(null);
28
+ const MyContext = Context<number | null>(null);
29
29
 
30
30
  const doubleContext = () => {
31
31
  const value = MyContext.get() as number;
@@ -1,3 +1,4 @@
1
+ import { track } from 'ripple';
1
2
  import { compile } from 'ripple/compiler';
2
3
 
3
4
  describe('CSS :global additional use cases', () => {
@@ -428,9 +429,10 @@ component Child1() {
428
429
  'handles sibling combinators with dynamic component and :global before scoped elements',
429
430
  () => {
430
431
  const source = `
432
+ import { track } from 'ripple';
431
433
 
432
434
  export component Test({ children }) {
433
- const DynamicComponent = #ripple.track(() => Child1);
435
+ const DynamicComponent = track(() => Child1);
434
436
  <div>
435
437
  <p class="before">{'before'}</p>
436
438
 
@@ -474,9 +476,10 @@ component Child1() {
474
476
  'handles sibling combinators with dynamic element or regular element and :global before scoped elements',
475
477
  () => {
476
478
  const source = `
479
+ import { track } from 'ripple';
477
480
 
478
481
  export component Test({ children, classes }) {
479
- const dynamicElement = #ripple.track('div');
482
+ const dynamicElement = track('div');
480
483
  <div>
481
484
  <p class="before">{'before'}</p>
482
485
  // Use Dynamic Element but it's the same with a regular one