ripple 0.3.7 → 0.3.9
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.
- package/CHANGELOG.md +14 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +48 -349
- package/src/compiler/phases/2-analyze/index.js +343 -52
- package/src/compiler/phases/3-transform/client/index.js +28 -160
- package/src/compiler/phases/3-transform/segments.js +0 -7
- package/src/compiler/phases/3-transform/server/index.js +31 -154
- package/src/compiler/types/acorn.d.ts +1 -1
- package/src/compiler/types/estree.d.ts +1 -1
- package/src/compiler/types/import.d.ts +0 -2
- package/src/compiler/types/index.d.ts +5 -17
- package/src/compiler/types/parse.d.ts +1 -17
- package/src/compiler/utils.js +53 -20
- package/src/runtime/index-client.js +2 -13
- package/src/runtime/index-server.js +2 -2
- package/src/runtime/internal/client/bindings.js +3 -1
- package/src/runtime/internal/client/composite.js +3 -2
- package/src/runtime/internal/client/events.js +1 -1
- package/src/runtime/internal/client/head.js +3 -4
- package/src/runtime/internal/client/index.js +0 -1
- package/src/runtime/internal/client/runtime.js +0 -52
- package/src/runtime/internal/server/index.js +31 -55
- package/tests/client/array/array.copy-within.test.ripple +12 -12
- package/tests/client/array/array.derived.test.ripple +46 -46
- package/tests/client/array/array.iteration.test.ripple +10 -10
- package/tests/client/array/array.mutations.test.ripple +20 -20
- package/tests/client/array/array.to-methods.test.ripple +6 -6
- package/tests/client/async-suspend.test.ripple +5 -5
- package/tests/client/basic/basic.attributes.test.ripple +81 -81
- package/tests/client/basic/basic.collections.test.ripple +9 -9
- package/tests/client/basic/basic.components.test.ripple +28 -28
- package/tests/client/basic/basic.errors.test.ripple +46 -18
- package/tests/client/basic/basic.events.test.ripple +37 -37
- package/tests/client/basic/basic.get-set.test.ripple +6 -6
- package/tests/client/basic/basic.reactivity.test.ripple +58 -203
- package/tests/client/basic/basic.rendering.test.ripple +19 -19
- package/tests/client/basic/basic.utilities.test.ripple +3 -3
- package/tests/client/boundaries.test.ripple +12 -12
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
- package/tests/client/compiler/compiler.basic.test.ripple +46 -27
- package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
- package/tests/client/composite/composite.props.test.ripple +14 -16
- package/tests/client/composite/composite.reactivity.test.ripple +69 -70
- package/tests/client/composite/composite.render.test.ripple +3 -3
- package/tests/client/computed-properties.test.ripple +4 -4
- package/tests/client/date.test.ripple +42 -42
- package/tests/client/dynamic-elements.test.ripple +44 -45
- package/tests/client/events.test.ripple +70 -70
- package/tests/client/for.test.ripple +25 -25
- package/tests/client/head.test.ripple +19 -19
- package/tests/client/html.test.ripple +3 -3
- package/tests/client/input-value.test.ripple +84 -84
- package/tests/client/lazy-destructuring.test.ripple +138 -26
- package/tests/client/map.test.ripple +16 -16
- package/tests/client/media-query.test.ripple +7 -7
- package/tests/client/portal.test.ripple +11 -11
- package/tests/client/ref.test.ripple +4 -4
- package/tests/client/return.test.ripple +52 -52
- package/tests/client/set.test.ripple +6 -6
- package/tests/client/svg.test.ripple +5 -5
- package/tests/client/switch.test.ripple +44 -44
- package/tests/client/try.test.ripple +5 -5
- package/tests/client/url/url.derived.test.ripple +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
- package/tests/hydration/compiled/client/events.js +25 -25
- package/tests/hydration/compiled/client/for.js +70 -66
- package/tests/hydration/compiled/client/head.js +25 -25
- package/tests/hydration/compiled/client/hmr.js +2 -2
- package/tests/hydration/compiled/client/html.js +3 -3
- package/tests/hydration/compiled/client/if-children.js +24 -24
- package/tests/hydration/compiled/client/if.js +18 -18
- package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
- package/tests/hydration/compiled/client/portal.js +3 -3
- package/tests/hydration/compiled/client/reactivity.js +16 -16
- package/tests/hydration/compiled/client/return.js +40 -40
- package/tests/hydration/compiled/client/switch.js +12 -12
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +41 -41
- package/tests/hydration/compiled/server/head.js +26 -26
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +2 -2
- package/tests/hydration/compiled/server/if-children.js +16 -16
- package/tests/hydration/compiled/server/if.js +11 -11
- package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
- package/tests/hydration/compiled/server/portal.js +2 -2
- package/tests/hydration/compiled/server/reactivity.js +16 -16
- package/tests/hydration/compiled/server/return.js +25 -25
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/components/events.ripple +25 -25
- package/tests/hydration/components/for.ripple +66 -66
- package/tests/hydration/components/head.ripple +16 -16
- package/tests/hydration/components/hmr.ripple +2 -2
- package/tests/hydration/components/html.ripple +3 -3
- package/tests/hydration/components/if-children.ripple +24 -24
- package/tests/hydration/components/if.ripple +18 -18
- package/tests/hydration/components/mixed-control-flow.ripple +9 -9
- package/tests/hydration/components/portal.ripple +3 -3
- package/tests/hydration/components/reactivity.ripple +16 -16
- package/tests/hydration/components/return.ripple +40 -40
- package/tests/hydration/components/switch.ripple +20 -20
- package/tests/server/await.test.ripple +3 -3
- package/tests/server/basic.attributes.test.ripple +34 -34
- package/tests/server/basic.components.test.ripple +10 -10
- package/tests/server/basic.test.ripple +38 -40
- package/tests/server/compiler.test.ripple +22 -0
- package/tests/server/composite.props.test.ripple +12 -14
- package/tests/server/dynamic-elements.test.ripple +15 -15
- package/tests/server/head.test.ripple +11 -11
- package/tests/server/lazy-destructuring.test.ripple +92 -13
- package/tsconfig.typecheck.json +4 -0
- package/types/index.d.ts +0 -19
- package/tests/client/__snapshots__/tracked-expression.test.ripple.snap +0 -34
- package/tests/client/tracked-expression.test.ripple +0 -26
|
@@ -19,13 +19,13 @@ describe('head elements', () => {
|
|
|
19
19
|
|
|
20
20
|
it('renders reactive title element', async () => {
|
|
21
21
|
component App() {
|
|
22
|
-
let title = track('Initial Title');
|
|
22
|
+
let &[title] = track('Initial Title');
|
|
23
23
|
|
|
24
24
|
<head>
|
|
25
|
-
<title>{
|
|
25
|
+
<title>{title}</title>
|
|
26
26
|
</head>
|
|
27
27
|
<div>
|
|
28
|
-
<span>{
|
|
28
|
+
<span>{title}</span>
|
|
29
29
|
</div>
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -38,10 +38,10 @@ describe('head elements', () => {
|
|
|
38
38
|
|
|
39
39
|
it('renders title with template literal', async () => {
|
|
40
40
|
component App() {
|
|
41
|
-
let name = track('World');
|
|
41
|
+
let &[name] = track('World');
|
|
42
42
|
|
|
43
43
|
<head>
|
|
44
|
-
<title>{`Hello ${
|
|
44
|
+
<title>{`Hello ${name}!`}</title>
|
|
45
45
|
</head>
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -53,14 +53,14 @@ describe('head elements', () => {
|
|
|
53
53
|
|
|
54
54
|
it('renders title with computed value', async () => {
|
|
55
55
|
component App() {
|
|
56
|
-
let count = track(0);
|
|
56
|
+
let &[count] = track(0);
|
|
57
57
|
let prefix = 'Count: ';
|
|
58
58
|
|
|
59
59
|
<head>
|
|
60
|
-
<title>{prefix +
|
|
60
|
+
<title>{prefix + count}</title>
|
|
61
61
|
</head>
|
|
62
62
|
<div>
|
|
63
|
-
<span>{
|
|
63
|
+
<span>{count}</span>
|
|
64
64
|
</div>
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -86,11 +86,11 @@ describe('head elements', () => {
|
|
|
86
86
|
|
|
87
87
|
it('renders title with conditional content', async () => {
|
|
88
88
|
component App() {
|
|
89
|
-
let showPrefix = track(true);
|
|
90
|
-
let title = track('Main Page');
|
|
89
|
+
let &[showPrefix] = track(true);
|
|
90
|
+
let &[title] = track('Main Page');
|
|
91
91
|
|
|
92
92
|
<head>
|
|
93
|
-
<title>{
|
|
93
|
+
<title>{showPrefix ? 'App - ' + title : title}</title>
|
|
94
94
|
</head>
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Tracked } from 'ripple';
|
|
2
|
+
import { track } from 'ripple';
|
|
2
3
|
|
|
3
4
|
describe('lazy destructuring', () => {
|
|
4
5
|
it('supports tracked value getter and setter', async () => {
|
|
@@ -30,7 +31,7 @@ describe('lazy destructuring', () => {
|
|
|
30
31
|
|
|
31
32
|
it('supports default values in lazy object destructuring', async () => {
|
|
32
33
|
component Test() {
|
|
33
|
-
const obj = { a: 5 };
|
|
34
|
+
const obj: { a: number; b?: number } = { a: 5 };
|
|
34
35
|
const &{ a, b = 99 } = obj;
|
|
35
36
|
<pre>{`${a}-${b}`}</pre>
|
|
36
37
|
}
|
|
@@ -39,6 +40,20 @@ describe('lazy destructuring', () => {
|
|
|
39
40
|
expect(body).toBeHtml('<pre>5-99</pre>');
|
|
40
41
|
});
|
|
41
42
|
|
|
43
|
+
it('supports nested lazy destructuring in non-lazy component params', async () => {
|
|
44
|
+
component Inner({ something: &[first, second] }: { something: Tracked<number> }) {
|
|
45
|
+
first = second.value + 1;
|
|
46
|
+
<pre>{`${first}-${second.value}`}</pre>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
component Test() {
|
|
50
|
+
<Inner something={track(1)} />
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { body } = await render(Test);
|
|
54
|
+
expect(body).toBeHtml('<pre>2-2</pre>');
|
|
55
|
+
});
|
|
56
|
+
|
|
42
57
|
it('supports let lazy destructuring with assignment writeback', async () => {
|
|
43
58
|
component Test() {
|
|
44
59
|
const obj = { a: 1, b: 2 };
|
|
@@ -106,33 +121,74 @@ describe('lazy destructuring', () => {
|
|
|
106
121
|
expect(body).toBeHtml('<pre>15-105</pre>');
|
|
107
122
|
});
|
|
108
123
|
|
|
109
|
-
it('supports
|
|
124
|
+
it('supports nested lazy destructuring in non-lazy function params', async () => {
|
|
110
125
|
component Test() {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
<
|
|
126
|
+
const something = track(1);
|
|
127
|
+
|
|
128
|
+
function getInfo({ something: &[first, second] }: { something: Tracked<number> }) {
|
|
129
|
+
first = second.value + 1;
|
|
130
|
+
return `${first}-${second.value}`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
<pre>{getInfo({ something })}</pre>
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
const { body } = await render(Test);
|
|
117
|
-
expect(body).toBeHtml('<pre>
|
|
137
|
+
expect(body).toBeHtml('<pre>2-2</pre>');
|
|
118
138
|
});
|
|
119
139
|
|
|
120
|
-
it(
|
|
140
|
+
it(
|
|
141
|
+
'preserves lazy getter/setter behavior for RestElement nested destructuring in non-lazy component params',
|
|
142
|
+
async () => {
|
|
143
|
+
component Inner({ values: [head, ...&{ 0: first_rest, length: rest_length }] }) {
|
|
144
|
+
const before = `${first_rest}-${rest_length}`;
|
|
145
|
+
rest_length = 0;
|
|
146
|
+
<pre>{`${head}-${before}-${first_rest}-${rest_length}`}</pre>
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
component Test() {
|
|
150
|
+
<Inner values={[10, 20, 30]} />
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const { body } = await render(Test);
|
|
154
|
+
expect(body).toBeHtml('<pre>10-20-2-undefined-0</pre>');
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
it(
|
|
159
|
+
'preserves lazy getter/setter behavior for RestElement nested destructuring in non-lazy function params',
|
|
160
|
+
async () => {
|
|
161
|
+
component Test() {
|
|
162
|
+
function getInfo({ values: [head, ...&{ 0: first_rest, length: rest_length }] }) {
|
|
163
|
+
const before = `${first_rest}-${rest_length}`;
|
|
164
|
+
rest_length = 0;
|
|
165
|
+
return `${head}-${before}-${first_rest}-${rest_length}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
<pre>{getInfo({ values: [5, 6, 7] })}</pre>
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const { body } = await render(Test);
|
|
172
|
+
expect(body).toBeHtml('<pre>5-6-2-undefined-0</pre>');
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
it('supports member access on lazy destructured objects', async () => {
|
|
121
177
|
component Test() {
|
|
122
|
-
const
|
|
123
|
-
const &
|
|
124
|
-
<pre>{`${
|
|
178
|
+
const obj = { user: { name: 'Alice', age: 30 } };
|
|
179
|
+
const &{ user } = obj;
|
|
180
|
+
<pre>{`${user.name}-${user.age}`}</pre>
|
|
125
181
|
}
|
|
126
182
|
|
|
127
183
|
const { body } = await render(Test);
|
|
128
|
-
expect(body).toBeHtml('<pre>
|
|
184
|
+
expect(body).toBeHtml('<pre>Alice-30</pre>');
|
|
129
185
|
});
|
|
130
186
|
|
|
131
187
|
it('supports rest in lazy array destructuring for tracked tuples (iterable)', async () => {
|
|
132
188
|
component Test() {
|
|
133
189
|
let tracked_value = track(0);
|
|
134
190
|
let &[value, ...rest] = tracked_value;
|
|
135
|
-
<pre>{`${value}-${
|
|
191
|
+
<pre>{`${value}-${rest.length}-${rest[0] === tracked_value}`}</pre>
|
|
136
192
|
}
|
|
137
193
|
|
|
138
194
|
const { body } = await render(Test);
|
|
@@ -149,4 +205,27 @@ describe('lazy destructuring', () => {
|
|
|
149
205
|
const { body } = await render(Test);
|
|
150
206
|
expect(body).toBeHtml('<pre>x-yz</pre>');
|
|
151
207
|
});
|
|
208
|
+
|
|
209
|
+
it('supports standalone lazy array destructuring with track()', async () => {
|
|
210
|
+
component Test() {
|
|
211
|
+
let count;
|
|
212
|
+
&[count] = track(0);
|
|
213
|
+
<div>{count}</div>
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const { body } = await render(Test);
|
|
217
|
+
expect(body).toBeHtml('<div>0</div>');
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('supports standalone lazy object destructuring', async () => {
|
|
221
|
+
component Test() {
|
|
222
|
+
let a;
|
|
223
|
+
let b;
|
|
224
|
+
&{ a, b } = { a: 10, b: 20 };
|
|
225
|
+
<pre>{`${a}-${b}`}</pre>
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const { body } = await render(Test);
|
|
229
|
+
expect(body).toBeHtml('<pre>10-20</pre>');
|
|
230
|
+
});
|
|
152
231
|
});
|
package/types/index.d.ts
CHANGED
|
@@ -176,19 +176,6 @@ export type PropsNoChildren<T extends object = {}> = Expand<T>;
|
|
|
176
176
|
|
|
177
177
|
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
178
178
|
|
|
179
|
-
type WrapTracked<V> = V extends Tracked<any> ? V : Tracked<V>;
|
|
180
|
-
|
|
181
|
-
type PickKeys<T, K extends readonly (keyof T)[]> = {
|
|
182
|
-
[I in keyof K]: WrapTracked<T[K[I] & keyof T]>;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
type RestKeys<T, K extends readonly (keyof T)[]> = Expand<Omit<T, K[number]>>;
|
|
186
|
-
|
|
187
|
-
type SplitResult<T extends Props, K extends readonly (keyof T)[]> = [
|
|
188
|
-
...PickKeys<T, K>,
|
|
189
|
-
Tracked<RestKeys<T, K>>,
|
|
190
|
-
];
|
|
191
|
-
|
|
192
179
|
export function get<V>(tracked: Tracked<V>): V;
|
|
193
180
|
|
|
194
181
|
export function set<V>(tracked: Tracked<V>, value: V): void;
|
|
@@ -204,11 +191,6 @@ export function track<V>(
|
|
|
204
191
|
// Overload for non-function values
|
|
205
192
|
export function track<V>(value?: V, get?: (v: V) => V, set?: (next: V, prev: V) => V): Tracked<V>;
|
|
206
193
|
|
|
207
|
-
export function trackSplit<V extends Props, const K extends readonly (keyof V)[]>(
|
|
208
|
-
value: V,
|
|
209
|
-
splitKeys: K,
|
|
210
|
-
): SplitResult<V, K>;
|
|
211
|
-
|
|
212
194
|
export interface AddEventOptions extends ExtendedEventOptions {
|
|
213
195
|
customName?: string;
|
|
214
196
|
}
|
|
@@ -568,7 +550,6 @@ export interface RippleNamespace {
|
|
|
568
550
|
urlSearchParams: RippleURLSearchParamsCallable;
|
|
569
551
|
untrack: typeof untrack;
|
|
570
552
|
track: typeof track;
|
|
571
|
-
trackSplit: typeof trackSplit;
|
|
572
553
|
style: Record<string, string>;
|
|
573
554
|
server: ServerBlock;
|
|
574
555
|
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
-
|
|
3
|
-
exports[`TrackedExpression tests > should handle the syntax correctly 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div>
|
|
6
|
-
0
|
|
7
|
-
</div>
|
|
8
|
-
<div>
|
|
9
|
-
4
|
|
10
|
-
</div>
|
|
11
|
-
<div>
|
|
12
|
-
1
|
|
13
|
-
</div>
|
|
14
|
-
<div>
|
|
15
|
-
2
|
|
16
|
-
</div>
|
|
17
|
-
<div>
|
|
18
|
-
2
|
|
19
|
-
</div>
|
|
20
|
-
<div>
|
|
21
|
-
3
|
|
22
|
-
</div>
|
|
23
|
-
<div>
|
|
24
|
-
4
|
|
25
|
-
</div>
|
|
26
|
-
<div>
|
|
27
|
-
false
|
|
28
|
-
</div>
|
|
29
|
-
<div>
|
|
30
|
-
true
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
</div>
|
|
34
|
-
`;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { track } from 'ripple';
|
|
2
|
-
|
|
3
|
-
describe('TrackedExpression tests', () => {
|
|
4
|
-
it('should handle the syntax correctly', () => {
|
|
5
|
-
component App() {
|
|
6
|
-
let count = track(0);
|
|
7
|
-
|
|
8
|
-
function get_count() {
|
|
9
|
-
return count;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
<div>{@(count)}</div>
|
|
13
|
-
<div>{@(get_count())}</div>
|
|
14
|
-
<div>{++@(count)}</div>
|
|
15
|
-
<div>{++@(get_count())}</div>
|
|
16
|
-
<div>{@(count)++}</div>
|
|
17
|
-
<div>{@(get_count())++}</div>
|
|
18
|
-
<div>{@(count)}</div>
|
|
19
|
-
<div>{!@(count)}</div>
|
|
20
|
-
<div>{!!@(count)}</div>
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
render(App);
|
|
24
|
-
expect(container).toMatchSnapshot();
|
|
25
|
-
});
|
|
26
|
-
});
|