ripple 0.3.8 → 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 +7 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +13 -157
- package/src/compiler/phases/2-analyze/index.js +289 -43
- package/src/compiler/phases/3-transform/client/index.js +9 -157
- package/src/compiler/phases/3-transform/segments.js +0 -7
- package/src/compiler/phases/3-transform/server/index.js +15 -130
- 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 -9
- 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 +1 -0
- 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/basic/basic.errors.test.ripple +28 -0
- package/tests/client/basic/basic.reactivity.test.ripple +10 -155
- package/tests/client/compiler/compiler.basic.test.ripple +31 -12
- package/tests/client/composite/composite.props.test.ripple +5 -7
- package/tests/client/composite/composite.reactivity.test.ripple +35 -36
- package/tests/client/dynamic-elements.test.ripple +3 -4
- package/tests/client/lazy-destructuring.test.ripple +69 -12
- package/tests/server/compiler.test.ripple +22 -0
- package/tests/server/composite.props.test.ripple +5 -7
- package/tests/server/dynamic-elements.test.ripple +3 -4
- package/tests/server/lazy-destructuring.test.ripple +68 -12
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Props, Tracked } from 'ripple';
|
|
2
|
-
import { RippleObject, effect, flushSync, track
|
|
2
|
+
import { RippleObject, effect, flushSync, track } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('composite > reactivity', () => {
|
|
5
5
|
it('renders composite components with object state', () => {
|
|
@@ -227,46 +227,42 @@ describe('composite > reactivity', () => {
|
|
|
227
227
|
expect(logs).toEqual(['Child effect: 1, 2, 3', 'Child effect: 2, 3, 4']);
|
|
228
228
|
});
|
|
229
229
|
|
|
230
|
-
it(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
<CounterWrapper {count} up={() => count++} down={() => count--} />
|
|
236
|
-
}
|
|
230
|
+
it('keeps reactivity for spread props via intermediate components and lazy destructuring', () => {
|
|
231
|
+
component App() {
|
|
232
|
+
let &[count] = track(0);
|
|
233
|
+
<CounterWrapper {count} up={() => count++} down={() => count--} />
|
|
234
|
+
}
|
|
237
235
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
236
|
+
component CounterWrapper(props: Props) {
|
|
237
|
+
<div>
|
|
238
|
+
<Counter {...props} />
|
|
239
|
+
</div>
|
|
240
|
+
}
|
|
243
241
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
242
|
+
component Counter(&{ count, up, down, ...rest }: Props) {
|
|
243
|
+
<button onClick={() => up()}>{'UP'}</button>
|
|
244
|
+
<button onClick={() => down()}>{'DOWN'}</button>
|
|
245
|
+
<span {...rest}>{`Counter: ${count}`}</span>
|
|
246
|
+
}
|
|
250
247
|
|
|
251
|
-
|
|
248
|
+
render(App);
|
|
252
249
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
250
|
+
const buttonIncrement = container.querySelectorAll('button')[0];
|
|
251
|
+
const buttonDecrement = container.querySelectorAll('button')[1];
|
|
252
|
+
const span = container.querySelector('span');
|
|
256
253
|
|
|
257
|
-
|
|
254
|
+
expect(span.textContent).toBe('Counter: 0');
|
|
258
255
|
|
|
259
|
-
|
|
260
|
-
|
|
256
|
+
buttonIncrement.click();
|
|
257
|
+
flushSync();
|
|
261
258
|
|
|
262
|
-
|
|
259
|
+
expect(span.textContent).toBe('Counter: 1');
|
|
263
260
|
|
|
264
|
-
|
|
265
|
-
|
|
261
|
+
buttonDecrement.click();
|
|
262
|
+
flushSync();
|
|
266
263
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
);
|
|
264
|
+
expect(span.textContent).toBe('Counter: 0');
|
|
265
|
+
});
|
|
270
266
|
|
|
271
267
|
it('keeps reactivity on elements for element spreads and adds / removes dynamic props', () => {
|
|
272
268
|
component App() {
|
|
@@ -295,16 +291,19 @@ describe('composite > reactivity', () => {
|
|
|
295
291
|
</div>
|
|
296
292
|
}
|
|
297
293
|
|
|
298
|
-
component Counter(
|
|
294
|
+
component Counter(&{
|
|
295
|
+
count,
|
|
296
|
+
up,
|
|
297
|
+
...rest
|
|
298
|
+
}: {
|
|
299
299
|
count: number;
|
|
300
300
|
up: () => void;
|
|
301
301
|
double: Tracked<number>;
|
|
302
302
|
another?: number;
|
|
303
303
|
extra: number;
|
|
304
304
|
}) {
|
|
305
|
-
|
|
306
|
-
<
|
|
307
|
-
<button onClick={() => up.value()}>{'UP'}</button>
|
|
305
|
+
<div {...rest}>{`Counter: ${count} Double: ${rest.double.value}`}</div>
|
|
306
|
+
<button onClick={() => up()}>{'UP'}</button>
|
|
308
307
|
}
|
|
309
308
|
|
|
310
309
|
render(App);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsWithExtras } from 'ripple';
|
|
2
|
-
import { createRefKey, flushSync, track
|
|
2
|
+
import { createRefKey, flushSync, track } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('dynamic DOM elements', () => {
|
|
5
5
|
it('renders static dynamic element', () => {
|
|
@@ -405,14 +405,13 @@ describe('dynamic DOM elements', () => {
|
|
|
405
405
|
});
|
|
406
406
|
|
|
407
407
|
it('handles spread attributes with class and CSS scoping ', () => {
|
|
408
|
-
component DynamicButton(
|
|
408
|
+
component DynamicButton(&{ ...rest }: PropsWithExtras<{
|
|
409
409
|
class: string;
|
|
410
410
|
id: string;
|
|
411
411
|
onClick: EventListener;
|
|
412
412
|
}>) {
|
|
413
413
|
const tag = track('button');
|
|
414
|
-
|
|
415
|
-
<@tag {...rest.value}>{rest.value.class}</@tag>
|
|
414
|
+
<@tag {...rest}>{rest.class}</@tag>
|
|
416
415
|
|
|
417
416
|
<style>
|
|
418
417
|
.even {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushSync, track
|
|
1
|
+
import { flushSync, track } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('lazy destructuring', () => {
|
|
4
4
|
it('supports tracked value getter and setter', () => {
|
|
@@ -126,6 +126,38 @@ describe('lazy destructuring', () => {
|
|
|
126
126
|
expect(container.querySelector('pre')!.textContent).toBe('1');
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
+
it('supports nested lazy destructuring in non-lazy component params', () => {
|
|
130
|
+
component Inner({ something: &[first, second] }) {
|
|
131
|
+
first = second.value + 1;
|
|
132
|
+
<pre>{`${first}-${second.value}`}</pre>
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
component Test() {
|
|
136
|
+
<Inner something={track(1)} />
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
render(Test);
|
|
140
|
+
expect(container.querySelector('pre')!.textContent).toBe('2-2');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it(
|
|
144
|
+
'preserves lazy getter/setter behavior for nested rest destructuring in non-lazy component params',
|
|
145
|
+
() => {
|
|
146
|
+
component Inner({ values: [head, ...&{ length: rest_length, 0: first_rest }] }) {
|
|
147
|
+
const before = `${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
148
|
+
rest_length = 0;
|
|
149
|
+
<pre>{`${head}-${before}-${first_rest?.value ?? 'nil'}-${rest_length}`}</pre>
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
component Test() {
|
|
153
|
+
<Inner values={[10, track(20), track(30)]} />
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
render(Test);
|
|
157
|
+
expect(container.querySelector('pre')!.textContent).toBe('10-20-2-nil-0');
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
|
|
129
161
|
it('supports lazy destructuring in function params', () => {
|
|
130
162
|
component Test() {
|
|
131
163
|
function getInfo(&{ x, y }: { x: number; y: number }) {
|
|
@@ -139,6 +171,42 @@ describe('lazy destructuring', () => {
|
|
|
139
171
|
expect(container.querySelector('pre')!.textContent).toBe('10');
|
|
140
172
|
});
|
|
141
173
|
|
|
174
|
+
it('supports nested lazy destructuring in non-lazy function params', () => {
|
|
175
|
+
component Test() {
|
|
176
|
+
const something = track(1);
|
|
177
|
+
|
|
178
|
+
function getInfo({ something: &[first, second] }) {
|
|
179
|
+
first = second.value + 1;
|
|
180
|
+
return `${first}-${second.value}`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const result = getInfo({ something });
|
|
184
|
+
<pre>{result}</pre>
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
render(Test);
|
|
188
|
+
expect(container.querySelector('pre')!.textContent).toBe('2-2');
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it(
|
|
192
|
+
'preserves lazy getter/setter behavior for nested rest destructuring in non-lazy function params',
|
|
193
|
+
() => {
|
|
194
|
+
component Test() {
|
|
195
|
+
function summarize({ values: [head, ...&{ length: rest_length, 0: first_rest }] }) {
|
|
196
|
+
const before = `${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
197
|
+
rest_length = 0;
|
|
198
|
+
return `${head}-${before}-${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const result = summarize({ values: [5, track(6), track(7)] });
|
|
202
|
+
<pre>{result}</pre>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
render(Test);
|
|
206
|
+
expect(container.querySelector('pre')!.textContent).toBe('5-6-2-nil-0');
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
|
|
142
210
|
it('supports let lazy destructuring with assignment writeback', () => {
|
|
143
211
|
component Test() {
|
|
144
212
|
const obj = { a: 1, b: 2 };
|
|
@@ -205,17 +273,6 @@ describe('lazy destructuring', () => {
|
|
|
205
273
|
expect(container.querySelector('pre')!.textContent).toBe('1-99');
|
|
206
274
|
});
|
|
207
275
|
|
|
208
|
-
it('does not apply the track tuple fast-path to trackSplit lazy arrays', () => {
|
|
209
|
-
component Test() {
|
|
210
|
-
const source = { a: 1, b: 2, c: 3 };
|
|
211
|
-
let [a, b, rest] = trackSplit(source, ['a', 'b']);
|
|
212
|
-
<pre>{`${a.value}-${b.value}-${rest.value.c}`}</pre>
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
render(Test);
|
|
216
|
-
expect(container.querySelector('pre')!.textContent).toBe('1-2-3');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
276
|
it('supports rest destructuring from iterable array-like tracked values', () => {
|
|
220
277
|
component Test() {
|
|
221
278
|
let &[value, ...rest] = track(0);
|
|
@@ -93,6 +93,28 @@ export component Layout(props) {
|
|
|
93
93
|
'`children` cannot be rendered using text interpolation. Use `<children />` instead.',
|
|
94
94
|
);
|
|
95
95
|
});
|
|
96
|
+
|
|
97
|
+
it('throws error for calling children as a function in SSR mode', () => {
|
|
98
|
+
const source = `
|
|
99
|
+
export component Layout({ children }) {
|
|
100
|
+
{children()}
|
|
101
|
+
}`;
|
|
102
|
+
|
|
103
|
+
expect(() => compile(source, 'test.ripple', { mode: 'server' })).toThrow(
|
|
104
|
+
'`children` cannot be called like a regular function. Use element syntax instead, e.g. `<children />` or `<props.children />`.',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('throws error for calling props.children as a function in SSR mode', () => {
|
|
109
|
+
const source = `
|
|
110
|
+
export component Layout(props) {
|
|
111
|
+
{props.children()}
|
|
112
|
+
}`;
|
|
113
|
+
|
|
114
|
+
expect(() => compile(source, 'test.ripple', { mode: 'server' })).toThrow(
|
|
115
|
+
'`children` cannot be called like a regular function. Use element syntax instead, e.g. `<children />` or `<props.children />`.',
|
|
116
|
+
);
|
|
117
|
+
});
|
|
96
118
|
});
|
|
97
119
|
|
|
98
120
|
describe('compiler server block tests', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { track
|
|
1
|
+
import { track } from 'ripple';
|
|
2
2
|
import type { Tracked, Props } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('composite > props', () => {
|
|
@@ -79,9 +79,8 @@ describe('composite > props', () => {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
it('correctly retains prop accessors and reactivity when using rest props', async () => {
|
|
82
|
-
component Button(
|
|
83
|
-
|
|
84
|
-
<button {...rest.value}>
|
|
82
|
+
component Button(&{ children, ...rest }: Props) {
|
|
83
|
+
<button {...rest}>
|
|
85
84
|
<@children />
|
|
86
85
|
</button>
|
|
87
86
|
<style>
|
|
@@ -94,10 +93,9 @@ describe('composite > props', () => {
|
|
|
94
93
|
</style>
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
component Toggle(
|
|
98
|
-
const [pressed, rest] = trackSplit(props, ['pressed']);
|
|
96
|
+
component Toggle(&{ pressed, ...rest }: { pressed: Tracked<boolean> }) {
|
|
99
97
|
const onClick = () => (pressed.value = !pressed.value);
|
|
100
|
-
<Button {...rest
|
|
98
|
+
<Button {...rest} class={pressed.value ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
|
|
101
99
|
<Button class={pressed.value ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
|
|
102
100
|
}
|
|
103
101
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PropsWithExtras } from 'ripple';
|
|
2
|
-
import { createRefKey, track
|
|
2
|
+
import { createRefKey, track } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('server dynamic DOM elements', () => {
|
|
5
5
|
it('renders static dynamic element', async () => {
|
|
@@ -258,13 +258,12 @@ describe('server dynamic DOM elements', () => {
|
|
|
258
258
|
});
|
|
259
259
|
|
|
260
260
|
it('handles spread attributes with class and CSS scoping', async () => {
|
|
261
|
-
component DynamicButton(
|
|
261
|
+
component DynamicButton(&{ ...rest }: PropsWithExtras<{
|
|
262
262
|
class: string;
|
|
263
263
|
id: string;
|
|
264
264
|
}>) {
|
|
265
265
|
const tag = track('button');
|
|
266
|
-
|
|
267
|
-
<@tag {...rest.value}>{rest.value.class}</@tag>
|
|
266
|
+
<@tag {...rest}>{rest.class}</@tag>
|
|
268
267
|
|
|
269
268
|
<style>
|
|
270
269
|
.even {
|
|
@@ -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,26 +121,67 @@ 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 () => {
|
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
|
-
});
|