ripple 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/package.json +2 -2
  3. package/src/compiler/identifier-utils.js +1 -8
  4. package/src/compiler/phases/1-parse/index.js +101 -195
  5. package/src/compiler/phases/2-analyze/index.js +82 -174
  6. package/src/compiler/phases/2-analyze/prune.js +2 -2
  7. package/src/compiler/phases/3-transform/client/index.js +169 -261
  8. package/src/compiler/phases/3-transform/server/index.js +185 -42
  9. package/src/compiler/types/index.d.ts +14 -33
  10. package/src/compiler/utils.js +32 -20
  11. package/src/runtime/index-client.js +0 -17
  12. package/src/runtime/internal/client/bindings.js +118 -7
  13. package/src/runtime/internal/client/render.js +5 -1
  14. package/src/runtime/internal/client/runtime.js +1 -1
  15. package/src/runtime/internal/client/types.d.ts +4 -0
  16. package/tests/client/array/array.copy-within.test.ripple +7 -7
  17. package/tests/client/array/array.derived.test.ripple +24 -24
  18. package/tests/client/array/array.iteration.test.ripple +7 -7
  19. package/tests/client/array/array.mutations.test.ripple +17 -17
  20. package/tests/client/array/array.to-methods.test.ripple +4 -4
  21. package/tests/client/async-suspend.test.ripple +3 -3
  22. package/tests/client/basic/basic.attributes.test.ripple +31 -31
  23. package/tests/client/basic/basic.collections.test.ripple +6 -6
  24. package/tests/client/basic/basic.components.test.ripple +8 -8
  25. package/tests/client/basic/basic.errors.test.ripple +31 -34
  26. package/tests/client/basic/basic.events.test.ripple +11 -11
  27. package/tests/client/basic/basic.get-set.test.ripple +18 -18
  28. package/tests/client/basic/basic.reactivity.test.ripple +36 -36
  29. package/tests/client/basic/basic.rendering.test.ripple +7 -7
  30. package/tests/client/basic/basic.utilities.test.ripple +4 -4
  31. package/tests/client/boundaries.test.ripple +7 -7
  32. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
  33. package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
  34. package/tests/client/compiler/compiler.basic.test.ripple +57 -58
  35. package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
  36. package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
  37. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  38. package/tests/client/composite/composite.props.test.ripple +9 -9
  39. package/tests/client/composite/composite.reactivity.test.ripple +23 -23
  40. package/tests/client/composite/composite.render.test.ripple +52 -4
  41. package/tests/client/computed-properties.test.ripple +3 -3
  42. package/tests/client/context.test.ripple +3 -3
  43. package/tests/client/css/global-additional-cases.test.ripple +5 -2
  44. package/tests/client/css/style-identifier.test.ripple +40 -49
  45. package/tests/client/date.test.ripple +39 -39
  46. package/tests/client/dynamic-elements.test.ripple +37 -37
  47. package/tests/client/events.test.ripple +25 -25
  48. package/tests/client/for.test.ripple +8 -8
  49. package/tests/client/head.test.ripple +7 -7
  50. package/tests/client/html.test.ripple +2 -2
  51. package/tests/client/input-value.test.ripple +376 -177
  52. package/tests/client/lazy-destructuring.test.ripple +185 -0
  53. package/tests/client/map.test.ripple +20 -20
  54. package/tests/client/media-query.test.ripple +4 -4
  55. package/tests/client/object.test.ripple +5 -5
  56. package/tests/client/portal.test.ripple +4 -4
  57. package/tests/client/ref.test.ripple +3 -3
  58. package/tests/client/return.test.ripple +17 -17
  59. package/tests/client/set.test.ripple +10 -10
  60. package/tests/client/svg.test.ripple +6 -5
  61. package/tests/client/switch.test.ripple +10 -10
  62. package/tests/client/tracked-expression.test.ripple +3 -1
  63. package/tests/client/try.test.ripple +4 -4
  64. package/tests/client/url/url.derived.test.ripple +6 -7
  65. package/tests/client/url/url.parsing.test.ripple +9 -9
  66. package/tests/client/url/url.partial-removal.test.ripple +9 -9
  67. package/tests/client/url/url.reactivity.test.ripple +16 -16
  68. package/tests/client/url/url.serialization.test.ripple +3 -3
  69. package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
  70. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
  71. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
  72. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
  73. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
  74. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
  75. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
  76. package/tests/hydration/build-components.js +4 -10
  77. package/tests/hydration/compiled/client/basic.js +4 -4
  78. package/tests/hydration/compiled/client/events.js +2 -0
  79. package/tests/hydration/compiled/client/for.js +2 -0
  80. package/tests/hydration/compiled/client/head.js +13 -11
  81. package/tests/hydration/compiled/client/hmr.js +4 -2
  82. package/tests/hydration/compiled/client/html.js +82 -95
  83. package/tests/hydration/compiled/client/if-children.js +8 -9
  84. package/tests/hydration/compiled/client/if.js +2 -0
  85. package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
  86. package/tests/hydration/compiled/client/portal.js +1 -1
  87. package/tests/hydration/compiled/client/reactivity.js +2 -0
  88. package/tests/hydration/compiled/client/return.js +2 -0
  89. package/tests/hydration/compiled/client/switch.js +2 -0
  90. package/tests/hydration/compiled/server/composite.js +2 -2
  91. package/tests/hydration/compiled/server/events.js +2 -0
  92. package/tests/hydration/compiled/server/for.js +2 -0
  93. package/tests/hydration/compiled/server/head.js +13 -11
  94. package/tests/hydration/compiled/server/hmr.js +2 -0
  95. package/tests/hydration/compiled/server/html.js +2 -0
  96. package/tests/hydration/compiled/server/if-children.js +2 -0
  97. package/tests/hydration/compiled/server/if.js +2 -0
  98. package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
  99. package/tests/hydration/compiled/server/portal.js +1 -1
  100. package/tests/hydration/compiled/server/reactivity.js +2 -0
  101. package/tests/hydration/compiled/server/return.js +2 -0
  102. package/tests/hydration/compiled/server/switch.js +2 -0
  103. package/tests/hydration/components/composite.ripple +1 -1
  104. package/tests/hydration/components/events.ripple +10 -8
  105. package/tests/hydration/components/for.ripple +22 -20
  106. package/tests/hydration/components/head.ripple +8 -6
  107. package/tests/hydration/components/hmr.ripple +3 -1
  108. package/tests/hydration/components/html.ripple +3 -1
  109. package/tests/hydration/components/if-children.ripple +9 -7
  110. package/tests/hydration/components/if.ripple +7 -5
  111. package/tests/hydration/components/mixed-control-flow.ripple +5 -3
  112. package/tests/hydration/components/portal.ripple +2 -2
  113. package/tests/hydration/components/reactivity.ripple +11 -9
  114. package/tests/hydration/components/return.ripple +13 -11
  115. package/tests/hydration/components/switch.ripple +6 -4
  116. package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
  117. package/tests/server/await.test.ripple +2 -2
  118. package/tests/server/basic.attributes.test.ripple +21 -19
  119. package/tests/server/basic.components.test.ripple +5 -4
  120. package/tests/server/basic.test.ripple +21 -20
  121. package/tests/server/compiler.test.ripple +36 -5
  122. package/tests/server/composite.props.test.ripple +7 -6
  123. package/tests/server/context.test.ripple +3 -1
  124. package/tests/server/dynamic-elements.test.ripple +24 -24
  125. package/tests/server/head.test.ripple +7 -5
  126. package/tests/server/style-identifier.test.ripple +95 -16
@@ -1,9 +1,9 @@
1
- import { flushSync } from 'ripple';
1
+ import { flushSync, track } from 'ripple';
2
2
 
3
3
  describe('switch statements', () => {
4
4
  it('renders simple switch with literal cases', () => {
5
5
  component App() {
6
- let value = #ripple.track('b');
6
+ let value = track('b');
7
7
 
8
8
  <button onClick={() => (@value = 'c')}>{'Change to C'}</button>
9
9
  <button onClick={() => (@value = 'a')}>{'Change to A'}</button>
@@ -38,7 +38,7 @@ describe('switch statements', () => {
38
38
 
39
39
  it('renders switch with reactive discriminant', () => {
40
40
  component App() {
41
- let count = #ripple.track(1);
41
+ let count = track(1);
42
42
 
43
43
  <button onClick={() => @count++}>{'Increment'}</button>
44
44
 
@@ -70,7 +70,7 @@ describe('switch statements', () => {
70
70
 
71
71
  it('renders switch with default clause only', () => {
72
72
  component App() {
73
- let value = #ripple.track('x');
73
+ let value = track('x');
74
74
 
75
75
  <button onClick={() => (@value = 'y')}>{'Change Value'}</button>
76
76
 
@@ -91,7 +91,7 @@ describe('switch statements', () => {
91
91
 
92
92
  it('renders switch using empty case fall-through', () => {
93
93
  component App() {
94
- let value = #ripple.track('a');
94
+ let value = track('a');
95
95
 
96
96
  <button onClick={() => (@value = 'b')}>{'Change to B'}</button>
97
97
  <button onClick={() => (@value = 'c')}>{'Change to C'}</button>
@@ -133,8 +133,8 @@ describe('switch statements', () => {
133
133
 
134
134
  it('renders switch with template content and reacts to tracked changes', () => {
135
135
  component App() {
136
- let status = #ripple.track('active');
137
- let message = #ripple.track('');
136
+ let status = track('active');
137
+ let message = track('');
138
138
 
139
139
  <button onClick={() => (@status = 'pending')}>{'Pending'}</button>
140
140
  <button onClick={() => (@status = 'completed')}>{'Completed'}</button>
@@ -185,7 +185,7 @@ describe('switch statements', () => {
185
185
  'renders switch with multiple non-empty fall-through cases and reacts to tracked changes without recreating DOM unnecessarily',
186
186
  () => {
187
187
  component App() {
188
- let status = #ripple.track(0);
188
+ let status = track(0);
189
189
  <div>
190
190
  switch (@status) {
191
191
  case -1:
@@ -253,7 +253,7 @@ describe('switch statements', () => {
253
253
  'renders a fall-through default in the middle of switch cases and reacts to changes without recreating DOM unnecessarily',
254
254
  () => {
255
255
  component App() {
256
- let value = #ripple.track('x');
256
+ let value = track('x');
257
257
 
258
258
  <button onClick={() => (@value = 'a')}>{'Set A'}</button>
259
259
  <button onClick={() => (@value = 'b')}>{'Set B'}</button>
@@ -359,7 +359,7 @@ describe('switch statements', () => {
359
359
 
360
360
  it('renders switch with block-scoped cases and break inside blocks', () => {
361
361
  component App() {
362
- let level = #ripple.track(1);
362
+ let level = track(1);
363
363
 
364
364
  <button
365
365
  onClick={() => {
@@ -1,7 +1,9 @@
1
+ import { track } from 'ripple';
2
+
1
3
  describe('TrackedExpression tests', () => {
2
4
  it('should handle the syntax correctly', () => {
3
5
  component App() {
4
- let count = #ripple.track(0);
6
+ let count = track(0);
5
7
 
6
8
  function get_count() {
7
9
  return count;
@@ -1,4 +1,4 @@
1
- import { bindValue, flushSync, RippleArray } from 'ripple';
1
+ import { RippleArray, bindValue, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('try block with catch and pending', () => {
4
4
  it('catch block works when component throws before await with pending block', async () => {
@@ -88,7 +88,7 @@ describe('try block', () => {
88
88
  }
89
89
 
90
90
  component Child() {
91
- let value = #ripple.track(1);
91
+ let value = track(1);
92
92
  await Promise.resolve(@value + 1);
93
93
 
94
94
  <input type="number" {ref bindValue(value)} />
@@ -140,7 +140,7 @@ describe('try block', () => {
140
140
  'does not crash when async component with tracked state is used inside try/pending',
141
141
  async () => {
142
142
  component App() {
143
- let query = #ripple.track('');
143
+ let query = track('');
144
144
 
145
145
  try {
146
146
  <FilteredList {query} />
@@ -152,7 +152,7 @@ describe('try block', () => {
152
152
  component FilteredList({ query }: { query: any }) {
153
153
  let items = await Promise.resolve(['apple', 'banana', 'cherry']);
154
154
  let list = RippleArray.from(items);
155
- let filtered = #ripple.track(() => list.filter((item: string) => item.includes(@query)));
155
+ let filtered = track(() => list.filter((item: string) => item.includes(@query)));
156
156
 
157
157
  <ul>
158
158
  for (let item of @filtered) {
@@ -1,12 +1,11 @@
1
- import type { RippleURL } from 'ripple';
2
- import { flushSync } from 'ripple';
1
+ import { RippleURL, flushSync, track } from 'ripple';
3
2
 
4
3
  describe('RippleURL > derived', () => {
5
4
  it('handles reactive computed properties based on URL', () => {
6
5
  component URLTest() {
7
- const url = #ripple.url('https://example.com/users/123?tab=profile');
8
- let userId = #ripple.track(() => url.pathname.split('/').pop());
9
- let activeTab = #ripple.track(() => url.searchParams.get('tab'));
6
+ const url = RippleURL('https://example.com/users/123?tab=profile');
7
+ let userId = track(() => url.pathname.split('/').pop());
8
+ let activeTab = track(() => url.searchParams.get('tab'));
10
9
 
11
10
  <button onClick={() => (url.pathname = '/users/456')}>{'Change User'}</button>
12
11
  <button onClick={() => url.searchParams.set('tab', 'settings')}>{'Change Tab'}</button>
@@ -40,7 +39,7 @@ describe('RippleURL > derived', () => {
40
39
 
41
40
  it('maintains reactivity across multiple components', () => {
42
41
  component ParentTest() {
43
- const url = #ripple.url('https://example.com/path?count=0');
42
+ const url = RippleURL('https://example.com/path?count=0');
44
43
 
45
44
  <ChildA {url} />
46
45
  <ChildB {url} />
@@ -58,7 +57,7 @@ describe('RippleURL > derived', () => {
58
57
  }
59
58
 
60
59
  component ChildB({ url }: { url: RippleURL }) {
61
- let count = #ripple.track(() => url.searchParams.get('count'));
60
+ let count = track(() => url.searchParams.get('count'));
62
61
 
63
62
  <pre>{url.href}</pre>
64
63
  <pre>{@count}</pre>
@@ -1,9 +1,9 @@
1
- import { flushSync } from 'ripple';
1
+ import { RippleURL, flushSync } from 'ripple';
2
2
 
3
3
  describe('RippleURL > parsing', () => {
4
4
  it('creates URL from string with reactivity', () => {
5
5
  component URLTest() {
6
- const url = #ripple.url('https://example.com:8080/path?foo=bar#section');
6
+ const url = RippleURL('https://example.com:8080/path?foo=bar#section');
7
7
 
8
8
  <pre>{url.href}</pre>
9
9
  <pre>{url.protocol}</pre>
@@ -29,7 +29,7 @@ describe('RippleURL > parsing', () => {
29
29
 
30
30
  it('creates URL from string with base URL', () => {
31
31
  component URLTest() {
32
- const url = #ripple.url('/path?query=value', 'https://example.com');
32
+ const url = RippleURL('/path?query=value', 'https://example.com');
33
33
 
34
34
  <pre>{url.href}</pre>
35
35
  <pre>{url.origin}</pre>
@@ -45,7 +45,7 @@ describe('RippleURL > parsing', () => {
45
45
 
46
46
  it('handles URL encoding correctly', () => {
47
47
  component URLTest() {
48
- const url = #ripple.url('https://example.com/path with spaces?key=value with spaces');
48
+ const url = RippleURL('https://example.com/path with spaces?key=value with spaces');
49
49
 
50
50
  <pre>{url.pathname}</pre>
51
51
  <pre>{url.search}</pre>
@@ -63,7 +63,7 @@ describe('RippleURL > parsing', () => {
63
63
 
64
64
  it('handles URL with file protocol', () => {
65
65
  component URLTest() {
66
- const url = #ripple.url('file:///Users/username/documents/file.txt');
66
+ const url = RippleURL('file:///Users/username/documents/file.txt');
67
67
 
68
68
  <pre>{url.protocol}</pre>
69
69
  <pre>{url.pathname}</pre>
@@ -83,7 +83,7 @@ describe('RippleURL > parsing', () => {
83
83
 
84
84
  it('handles URL with IPv4 address', () => {
85
85
  component URLTest() {
86
- const url = #ripple.url('https://192.168.1.1:8080/path');
86
+ const url = RippleURL('https://192.168.1.1:8080/path');
87
87
 
88
88
  <button onClick={() => (url.hostname = '10.0.0.1')}>{'Change IP'}</button>
89
89
  <pre>{url.href}</pre>
@@ -108,7 +108,7 @@ describe('RippleURL > parsing', () => {
108
108
 
109
109
  it('handles URL with localhost', () => {
110
110
  component URLTest() {
111
- const url = #ripple.url('http://localhost:3000/api/data');
111
+ const url = RippleURL('http://localhost:3000/api/data');
112
112
 
113
113
  <button onClick={() => (url.port = '8080')}>{'Change Port'}</button>
114
114
  <pre>{url.href}</pre>
@@ -136,7 +136,7 @@ describe('RippleURL > parsing', () => {
136
136
 
137
137
  it('handles URL with multiple path segments', () => {
138
138
  component URLTest() {
139
- const url = #ripple.url('https://example.com/api/v1/users/123/profile');
139
+ const url = RippleURL('https://example.com/api/v1/users/123/profile');
140
140
 
141
141
  <button onClick={() => (url.pathname = '/api/v2/users/456/settings')}>{'Change Path'}</button>
142
142
  <pre>{url.pathname}</pre>
@@ -165,7 +165,7 @@ describe('RippleURL > parsing', () => {
165
165
 
166
166
  it('handles relative URL paths correctly', () => {
167
167
  component URLTest() {
168
- const url = #ripple.url('../sibling/path', 'https://example.com/parent/current');
168
+ const url = RippleURL('../sibling/path', 'https://example.com/parent/current');
169
169
 
170
170
  <pre>{url.href}</pre>
171
171
  <pre>{url.pathname}</pre>
@@ -1,9 +1,9 @@
1
- import { flushSync } from 'ripple';
1
+ import { RippleURL, flushSync } from 'ripple';
2
2
 
3
3
  describe('RippleURL > partials/removal', () => {
4
4
  it('handles URL with no port specified', () => {
5
5
  component URLTest() {
6
- const url = #ripple.url('https://example.com/path');
6
+ const url = RippleURL('https://example.com/path');
7
7
 
8
8
  <pre>{url.port}</pre>
9
9
  <pre>{url.host}</pre>
@@ -28,7 +28,7 @@ describe('RippleURL > partials/removal', () => {
28
28
 
29
29
  it('handles URL with no search params', () => {
30
30
  component URLTest() {
31
- const url = #ripple.url('https://example.com/path');
31
+ const url = RippleURL('https://example.com/path');
32
32
 
33
33
  <pre>{url.search}</pre>
34
34
  <pre>{url.searchParams.size}</pre>
@@ -53,7 +53,7 @@ describe('RippleURL > partials/removal', () => {
53
53
 
54
54
  it('handles URL with no hash', () => {
55
55
  component URLTest() {
56
- const url = #ripple.url('https://example.com/path');
56
+ const url = RippleURL('https://example.com/path');
57
57
 
58
58
  <pre>{url.hash}</pre>
59
59
  <button onClick={() => (url.hash = '#section')}>{'Add Hash'}</button>
@@ -75,7 +75,7 @@ describe('RippleURL > partials/removal', () => {
75
75
 
76
76
  it('handles removing port by setting empty string', () => {
77
77
  component URLTest() {
78
- const url = #ripple.url('https://example.com:8080/path');
78
+ const url = RippleURL('https://example.com:8080/path');
79
79
 
80
80
  <button onClick={() => (url.port = '')}>{'Remove Port'}</button>
81
81
  <pre>{url.href}</pre>
@@ -100,7 +100,7 @@ describe('RippleURL > partials/removal', () => {
100
100
 
101
101
  it('handles removing hash by setting empty string', () => {
102
102
  component URLTest() {
103
- const url = #ripple.url('https://example.com/path#section');
103
+ const url = RippleURL('https://example.com/path#section');
104
104
 
105
105
  <button onClick={() => (url.hash = '')}>{'Remove Hash'}</button>
106
106
  <pre>{url.href}</pre>
@@ -127,7 +127,7 @@ describe('RippleURL > partials/removal', () => {
127
127
 
128
128
  it('handles removing search by setting empty string', () => {
129
129
  component URLTest() {
130
- const url = #ripple.url('https://example.com/path?foo=bar');
130
+ const url = RippleURL('https://example.com/path?foo=bar');
131
131
 
132
132
  <button onClick={() => (url.search = '')}>{'Remove Search'}</button>
133
133
  <pre>{url.href}</pre>
@@ -157,7 +157,7 @@ describe('RippleURL > partials/removal', () => {
157
157
 
158
158
  it('handles hash without leading # character', () => {
159
159
  component URLTest() {
160
- const url = #ripple.url('https://example.com/path');
160
+ const url = RippleURL('https://example.com/path');
161
161
 
162
162
  <button onClick={() => (url.hash = 'section')}>{'Set Hash'}</button>
163
163
  <pre>{url.hash}</pre>
@@ -183,7 +183,7 @@ describe('RippleURL > partials/removal', () => {
183
183
 
184
184
  it('handles search without leading ? character', () => {
185
185
  component URLTest() {
186
- const url = #ripple.url('https://example.com/path');
186
+ const url = RippleURL('https://example.com/path');
187
187
 
188
188
  <button onClick={() => (url.search = 'foo=bar')}>{'Set Search'}</button>
189
189
  <pre>{url.search}</pre>
@@ -1,9 +1,9 @@
1
- import { flushSync } from 'ripple';
1
+ import { RippleURL, flushSync } from 'ripple';
2
2
 
3
3
  describe('RippleURL > reactivity', () => {
4
4
  it('handles protocol changes with reactivity', () => {
5
5
  component URLTest() {
6
- const url = #ripple.url('https://example.com/path');
6
+ const url = RippleURL('https://example.com/path');
7
7
 
8
8
  <button onClick={() => (url.protocol = 'http:')}>{'Change Protocol'}</button>
9
9
  <pre>{url.href}</pre>
@@ -31,7 +31,7 @@ describe('RippleURL > reactivity', () => {
31
31
 
32
32
  it('handles hostname changes with reactivity', () => {
33
33
  component URLTest() {
34
- const url = #ripple.url('https://example.com/path');
34
+ const url = RippleURL('https://example.com/path');
35
35
 
36
36
  <button onClick={() => (url.hostname = 'newdomain.com')}>{'Change Hostname'}</button>
37
37
  <pre>{url.href}</pre>
@@ -59,7 +59,7 @@ describe('RippleURL > reactivity', () => {
59
59
 
60
60
  it('handles port changes with reactivity', () => {
61
61
  component URLTest() {
62
- const url = #ripple.url('https://example.com:8080/path');
62
+ const url = RippleURL('https://example.com:8080/path');
63
63
 
64
64
  <button onClick={() => (url.port = '9090')}>{'Change Port'}</button>
65
65
  <pre>{url.href}</pre>
@@ -87,7 +87,7 @@ describe('RippleURL > reactivity', () => {
87
87
 
88
88
  it('handles host changes with reactivity', () => {
89
89
  component URLTest() {
90
- const url = #ripple.url('https://example.com:8080/path');
90
+ const url = RippleURL('https://example.com:8080/path');
91
91
 
92
92
  <button onClick={() => (url.host = 'newdomain.com:9090')}>{'Change Host'}</button>
93
93
  <pre>{url.href}</pre>
@@ -120,7 +120,7 @@ describe('RippleURL > reactivity', () => {
120
120
 
121
121
  it('handles pathname changes with reactivity', () => {
122
122
  component URLTest() {
123
- const url = #ripple.url('https://example.com/old-path');
123
+ const url = RippleURL('https://example.com/old-path');
124
124
 
125
125
  <button onClick={() => (url.pathname = '/new-path')}>{'Change Pathname'}</button>
126
126
  <pre>{url.href}</pre>
@@ -145,7 +145,7 @@ describe('RippleURL > reactivity', () => {
145
145
 
146
146
  it('handles search changes with reactivity', () => {
147
147
  component URLTest() {
148
- const url = #ripple.url('https://example.com/path?foo=bar');
148
+ const url = RippleURL('https://example.com/path?foo=bar');
149
149
 
150
150
  <button onClick={() => (url.search = '?baz=qux')}>{'Change Search'}</button>
151
151
  <pre>{url.href}</pre>
@@ -174,7 +174,7 @@ describe('RippleURL > reactivity', () => {
174
174
 
175
175
  it('handles hash changes with reactivity', () => {
176
176
  component URLTest() {
177
- const url = #ripple.url('https://example.com/path#section1');
177
+ const url = RippleURL('https://example.com/path#section1');
178
178
 
179
179
  <button onClick={() => (url.hash = '#section2')}>{'Change Hash'}</button>
180
180
  <pre>{url.href}</pre>
@@ -203,7 +203,7 @@ describe('RippleURL > reactivity', () => {
203
203
 
204
204
  it('handles username changes with reactivity', () => {
205
205
  component URLTest() {
206
- const url = #ripple.url('https://user:pass@example.com/path');
206
+ const url = RippleURL('https://user:pass@example.com/path');
207
207
 
208
208
  <button onClick={() => (url.username = 'newuser')}>{'Change Username'}</button>
209
209
  <pre>{url.href}</pre>
@@ -232,7 +232,7 @@ describe('RippleURL > reactivity', () => {
232
232
 
233
233
  it('handles password changes with reactivity', () => {
234
234
  component URLTest() {
235
- const url = #ripple.url('https://user:pass@example.com/path');
235
+ const url = RippleURL('https://user:pass@example.com/path');
236
236
 
237
237
  <button onClick={() => (url.password = 'newpass')}>{'Change Password'}</button>
238
238
  <pre>{url.href}</pre>
@@ -261,7 +261,7 @@ describe('RippleURL > reactivity', () => {
261
261
 
262
262
  it('handles href changes with reactivity', () => {
263
263
  component URLTest() {
264
- const url = #ripple.url('https://example.com/path?foo=bar#section');
264
+ const url = RippleURL('https://example.com/path?foo=bar#section');
265
265
 
266
266
  <button onClick={() => (url.href = 'https://newdomain.com:9090/newpath?baz=qux#newsection')}>
267
267
  {'Change Href'}
@@ -307,7 +307,7 @@ describe('RippleURL > reactivity', () => {
307
307
 
308
308
  it('handles origin property reactivity', () => {
309
309
  component URLTest() {
310
- const url = #ripple.url('https://example.com:8080/path');
310
+ const url = RippleURL('https://example.com:8080/path');
311
311
 
312
312
  <button onClick={() => (url.protocol = 'http:')}>{'Change Protocol'}</button>
313
313
  <button onClick={() => (url.hostname = 'newdomain.com')}>{'Change Hostname'}</button>
@@ -339,7 +339,7 @@ describe('RippleURL > reactivity', () => {
339
339
  });
340
340
  it('handles searchParams changes with reactivity', () => {
341
341
  component URLTest() {
342
- const url = #ripple.url('https://example.com/path?foo=bar');
342
+ const url = RippleURL('https://example.com/path?foo=bar');
343
343
  const params = url.searchParams;
344
344
 
345
345
  <button onClick={() => params.set('foo', 'updated')}>{'Update Foo'}</button>
@@ -383,7 +383,7 @@ describe('RippleURL > reactivity', () => {
383
383
 
384
384
  it('handles search property updates reflected in searchParams', () => {
385
385
  component URLTest() {
386
- const url = #ripple.url('https://example.com/path?foo=bar');
386
+ const url = RippleURL('https://example.com/path?foo=bar');
387
387
  const params = url.searchParams;
388
388
 
389
389
  <button onClick={() => (url.search = '?baz=qux&test=value')}>{'Change Search'}</button>
@@ -418,7 +418,7 @@ describe('RippleURL > reactivity', () => {
418
418
 
419
419
  it('handles multiple URL property changes in sequence', () => {
420
420
  component URLTest() {
421
- const url = #ripple.url('https://example.com/path');
421
+ const url = RippleURL('https://example.com/path');
422
422
 
423
423
  <button
424
424
  onClick={() => {
@@ -453,7 +453,7 @@ describe('RippleURL > reactivity', () => {
453
453
 
454
454
  it('handles href change updates all properties and searchParams', () => {
455
455
  component URLTest() {
456
- const url = #ripple.url('https://old.com/old?foo=bar#old');
456
+ const url = RippleURL('https://old.com/old?foo=bar#old');
457
457
  const params = url.searchParams;
458
458
 
459
459
  <button onClick={() => (url.href = 'https://new.com:9090/new?baz=qux#new')}>
@@ -1,9 +1,9 @@
1
- import { flushSync } from 'ripple';
1
+ import { RippleURL, flushSync } from 'ripple';
2
2
 
3
3
  describe('RippleURL > serialization', () => {
4
4
  it('handles toString method', () => {
5
5
  component URLTest() {
6
- const url = #ripple.url('https://example.com/path?foo=bar#section');
6
+ const url = RippleURL('https://example.com/path?foo=bar#section');
7
7
 
8
8
  <button onClick={() => (url.pathname = '/newpath')}>{'Change Pathname'}</button>
9
9
  <pre>{url.toString()}</pre>
@@ -29,7 +29,7 @@ describe('RippleURL > serialization', () => {
29
29
 
30
30
  it('handles toJSON method', () => {
31
31
  component URLTest() {
32
- const url = #ripple.url('https://example.com/path?foo=bar');
32
+ const url = RippleURL('https://example.com/path?foo=bar');
33
33
 
34
34
  <button onClick={() => (url.pathname = '/api')}>{'Change Pathname'}</button>
35
35
  <pre>{url.toJSON()}</pre>
@@ -1,13 +1,12 @@
1
- import type { RippleURLSearchParams } from 'ripple';
2
- import { flushSync } from 'ripple';
1
+ import { RippleURL, RippleURLSearchParams, flushSync, track } from 'ripple';
3
2
 
4
3
  describe('RippleURLSearchParams > derived', () => {
5
4
  it('handles reactive computed properties based on search params', () => {
6
5
  component URLTest() {
7
- const params = #ripple.urlSearchParams('page=1&limit=10');
8
- let page = #ripple.track(() => parseInt(params.get('page') || '1', 10));
9
- let limit = #ripple.track(() => parseInt(params.get('limit') || '10', 10));
10
- let offset = #ripple.track(() => (@page - 1) * @limit);
6
+ const params = RippleURLSearchParams('page=1&limit=10');
7
+ let page = track(() => parseInt(params.get('page') || '1', 10));
8
+ let limit = track(() => parseInt(params.get('limit') || '10', 10));
9
+ let offset = track(() => (@page - 1) * @limit);
11
10
 
12
11
  <button onClick={() => params.set('page', '2')}>{'next page'}</button>
13
12
  <button onClick={() => params.set('page', '1')}>{'first page'}</button>
@@ -45,7 +44,7 @@ describe('RippleURLSearchParams > derived', () => {
45
44
 
46
45
  it('maintains reactivity across multiple components', () => {
47
46
  component ParentTest() {
48
- const params = #ripple.urlSearchParams('count=0');
47
+ const params = RippleURLSearchParams('count=0');
49
48
 
50
49
  <ChildA {params} />
51
50
  <ChildB {params} />
@@ -63,7 +62,7 @@ describe('RippleURLSearchParams > derived', () => {
63
62
  }
64
63
 
65
64
  component ChildB({ params }: { params: RippleURLSearchParams }) {
66
- let count = #ripple.track(() => params.get('count'));
65
+ let count = track(() => params.get('count'));
67
66
 
68
67
  <pre>{@count}</pre>
69
68
  }
@@ -1,7 +1,9 @@
1
+ import { RippleURL, RippleURLSearchParams } from 'ripple';
2
+
1
3
  describe('RippleURLSearchParams > initialization', () => {
2
4
  it('creates empty URLSearchParams with reactivity', () => {
3
5
  component URLTest() {
4
- const params = #ripple.urlSearchParams();
6
+ const params = RippleURLSearchParams();
5
7
 
6
8
  <pre>{params.toString()}</pre>
7
9
  <pre>{params.size}</pre>
@@ -15,7 +17,7 @@ describe('RippleURLSearchParams > initialization', () => {
15
17
 
16
18
  it('creates URLSearchParams from string with reactivity', () => {
17
19
  component URLTest() {
18
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
20
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
19
21
 
20
22
  <pre>{params.toString()}</pre>
21
23
  <pre>{params.size}</pre>
@@ -31,7 +33,7 @@ describe('RippleURLSearchParams > initialization', () => {
31
33
 
32
34
  it('creates URLSearchParams from object with reactivity', () => {
33
35
  component URLTest() {
34
- const params = #ripple.urlSearchParams({ foo: 'bar', baz: 'qux' });
36
+ const params = RippleURLSearchParams({ foo: 'bar', baz: 'qux' });
35
37
 
36
38
  <pre>{params.toString()}</pre>
37
39
  <pre>{params.size}</pre>
@@ -45,7 +47,7 @@ describe('RippleURLSearchParams > initialization', () => {
45
47
 
46
48
  it('handles URL-encoded characters correctly', () => {
47
49
  component URLTest() {
48
- const params = #ripple.urlSearchParams('name=John+Doe&email=john%40example.com');
50
+ const params = RippleURLSearchParams('name=John+Doe&email=john%40example.com');
49
51
 
50
52
  <pre>{params.get('name')}</pre>
51
53
  <pre>{params.get('email')}</pre>
@@ -1,10 +1,10 @@
1
- import { flushSync } from 'ripple';
1
+ import { RippleURL, RippleURLSearchParams, flushSync, track } from 'ripple';
2
2
 
3
3
  describe('RippleURLSearchParams > iteration', () => {
4
4
  it('handles keys method with reactivity', () => {
5
5
  component URLTest() {
6
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
7
- let keys = #ripple.track(() => Array.from(params.keys()));
6
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
7
+ let keys = track(() => Array.from(params.keys()));
8
8
 
9
9
  <button onClick={() => params.append('new', 'value')}>{'add param'}</button>
10
10
  <pre>{JSON.stringify(@keys)}</pre>
@@ -26,8 +26,8 @@ describe('RippleURLSearchParams > iteration', () => {
26
26
 
27
27
  it('handles values method with reactivity', () => {
28
28
  component URLTest() {
29
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
30
- let values = #ripple.track(() => Array.from(params.values()));
29
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
30
+ let values = track(() => Array.from(params.values()));
31
31
 
32
32
  <button onClick={() => params.set('foo', 'updated')}>{'update foo'}</button>
33
33
  <pre>{JSON.stringify(@values)}</pre>
@@ -49,8 +49,8 @@ describe('RippleURLSearchParams > iteration', () => {
49
49
 
50
50
  it('handles entries method with reactivity', () => {
51
51
  component URLTest() {
52
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
53
- let entries = #ripple.track(() => Array.from(params.entries()));
52
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
53
+ let entries = track(() => Array.from(params.entries()));
54
54
 
55
55
  <button onClick={() => params.append('new', 'value')}>{'add param'}</button>
56
56
  <pre>{JSON.stringify(@entries)}</pre>
@@ -74,8 +74,8 @@ describe('RippleURLSearchParams > iteration', () => {
74
74
 
75
75
  it('handles Symbol.iterator with reactivity', () => {
76
76
  component URLTest() {
77
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
78
- let entries = #ripple.track(() => Array.from(params));
77
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
78
+ let entries = track(() => Array.from(params));
79
79
 
80
80
  <button onClick={() => params.delete('foo')}>{'delete foo'}</button>
81
81
  <pre>{JSON.stringify(@entries)}</pre>
@@ -97,7 +97,7 @@ describe('RippleURLSearchParams > iteration', () => {
97
97
 
98
98
  it('handles iteration with for...of', () => {
99
99
  component URLTest() {
100
- const params = #ripple.urlSearchParams('foo=bar&baz=qux');
100
+ const params = RippleURLSearchParams('foo=bar&baz=qux');
101
101
 
102
102
  <button onClick={() => params.append('new', 'value')}>{'add param'}</button>
103
103
 
@@ -125,8 +125,8 @@ describe('RippleURLSearchParams > iteration', () => {
125
125
 
126
126
  it('handles forEach iteration', () => {
127
127
  component URLTest() {
128
- const params = #ripple.urlSearchParams('a=1&b=2&c=3');
129
- let sum = #ripple.track(() => {
128
+ const params = RippleURLSearchParams('a=1&b=2&c=3');
129
+ let sum = track(() => {
130
130
  let total = 0;
131
131
  // Access the params reactively through entries
132
132
  for (const [key, value] of params.entries()) {