ripple 0.3.128 → 0.4.0
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 +267 -0
- package/package.json +10 -4
- package/src/runtime/element.js +23 -6
- package/src/runtime/index-client.js +81 -41
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/blocks.js +173 -91
- package/src/runtime/internal/client/component.js +4 -30
- package/src/runtime/internal/client/composite.js +12 -13
- package/src/runtime/internal/client/constants.js +9 -0
- package/src/runtime/internal/client/context.js +12 -19
- package/src/runtime/internal/client/css.js +7 -9
- package/src/runtime/internal/client/events.js +178 -90
- package/src/runtime/internal/client/expression.js +45 -25
- package/src/runtime/internal/client/for.js +409 -129
- package/src/runtime/internal/client/head.js +10 -5
- package/src/runtime/internal/client/html.js +1 -0
- package/src/runtime/internal/client/hydration.js +152 -10
- package/src/runtime/internal/client/if.js +239 -50
- package/src/runtime/internal/client/index.js +4 -12
- package/src/runtime/internal/client/operations.js +40 -61
- package/src/runtime/internal/client/portal.js +163 -85
- package/src/runtime/internal/client/render.js +39 -39
- package/src/runtime/internal/client/rpc.js +3 -3
- package/src/runtime/internal/client/runtime.js +592 -433
- package/src/runtime/internal/client/selector.js +5 -2
- package/src/runtime/internal/client/template.js +133 -158
- package/src/runtime/internal/client/transport.js +38 -0
- package/src/runtime/internal/client/try.js +465 -426
- package/src/runtime/internal/client/types.d.ts +56 -23
- package/src/runtime/internal/client/utils.js +1 -3
- package/src/runtime/internal/server/dynamic.js +20 -21
- package/src/runtime/internal/server/index.js +325 -275
- package/src/runtime/internal/server/rpc.js +3 -2
- package/src/runtime/internal/server/transport.js +16 -0
- package/src/runtime/transport.js +21 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
- package/tests/client/array/array.copy-within.test.tsrx +12 -12
- package/tests/client/array/array.derived.test.tsrx +46 -46
- package/tests/client/array/array.iteration.test.tsrx +10 -10
- package/tests/client/array/array.mutations.test.tsrx +20 -20
- package/tests/client/array/array.static.test.tsrx +11 -11
- package/tests/client/array/array.to-methods.test.tsrx +6 -6
- package/tests/client/async-suspend.test.tsrx +74 -75
- package/tests/client/basic/basic.attributes.test.tsrx +86 -83
- package/tests/client/basic/basic.collections.test.tsrx +12 -12
- package/tests/client/basic/basic.components.test.tsrx +99 -25
- package/tests/client/basic/basic.errors.test.tsrx +18 -18
- package/tests/client/basic/basic.events.test.tsrx +42 -42
- package/tests/client/basic/basic.get-set.test.tsrx +8 -8
- package/tests/client/basic/basic.reactivity.test.tsrx +73 -38
- package/tests/client/basic/basic.rendering.test.tsrx +25 -25
- package/tests/client/basic/basic.utilities.test.tsrx +3 -3
- package/tests/client/boundaries.test.tsrx +8 -8
- package/tests/client/boxed-locals.test.tsrx +452 -0
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
- package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
- package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
- package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
- package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
- package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
- package/tests/client/composite/composite.props.test.tsrx +149 -12
- package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
- package/tests/client/composite/composite.render.test.tsrx +26 -9
- package/tests/client/css/scoped-styles.test.tsrx +8 -8
- package/tests/client/date.test.tsrx +42 -42
- package/tests/client/derived-release.test.tsrx +370 -0
- package/tests/client/dynamic-elements.test.tsrx +45 -45
- package/tests/client/events.test.tsrx +97 -71
- package/tests/client/for-selector.test.tsrx +14 -14
- package/tests/client/for-single-root-items.test.tsrx +118 -3
- package/tests/client/for.test.tsrx +332 -31
- package/tests/client/head.test.tsrx +19 -19
- package/tests/client/html.test.tsrx +11 -9
- package/tests/client/if-block.test.tsrx +80 -0
- package/tests/client/map.test.tsrx +16 -16
- package/tests/client/media-query.test.tsrx +7 -7
- package/tests/client/portal.test.tsrx +224 -26
- package/tests/client/primitive-text.test.tsrx +50 -0
- package/tests/client/prop-kind-switch.test.tsrx +141 -0
- package/tests/client/ref.test.tsrx +17 -17
- package/tests/client/return.test.tsrx +26 -3
- package/tests/client/root-boundary.test.tsrx +42 -0
- package/tests/client/scoped-flush.test.tsrx +8 -8
- package/tests/client/set.test.tsrx +6 -6
- package/tests/client/svg.test.tsrx +11 -11
- package/tests/client/switch.test.tsrx +44 -44
- package/tests/client/track-async-hydration.test.tsrx +4 -4
- package/tests/client/try.test.tsrx +151 -83
- package/tests/client/tsx.test.tsrx +43 -40
- package/tests/client/url/url.derived.test.tsrx +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
- package/tests/hydration/basic.test.js +74 -1
- package/tests/hydration/build-components.js +22 -1
- package/tests/hydration/compiled/client/basic.js +1142 -713
- package/tests/hydration/compiled/client/composite.js +151 -100
- package/tests/hydration/compiled/client/events.js +184 -171
- package/tests/hydration/compiled/client/for.js +1472 -1132
- package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
- package/tests/hydration/compiled/client/head.js +254 -201
- package/tests/hydration/compiled/client/hmr.js +54 -41
- package/tests/hydration/compiled/client/html-in-template.js +54 -39
- package/tests/hydration/compiled/client/html.js +1633 -1263
- package/tests/hydration/compiled/client/if-children.js +420 -270
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
- package/tests/hydration/compiled/client/if.js +229 -219
- package/tests/hydration/compiled/client/mixed-control-flow.js +420 -404
- package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
- package/tests/hydration/compiled/client/portal.js +87 -95
- package/tests/hydration/compiled/client/reactivity.js +135 -101
- package/tests/hydration/compiled/client/return.js +28 -19
- package/tests/hydration/compiled/client/streaming.js +390 -306
- package/tests/hydration/compiled/client/switch.js +258 -266
- package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
- package/tests/hydration/compiled/client/try.js +173 -129
- package/tests/hydration/compiled/client/typed-text.js +71 -0
- package/tests/hydration/compiled/fixtures/money.js +10 -0
- package/tests/hydration/compiled/server/basic.js +123 -6
- package/tests/hydration/compiled/server/composite.js +16 -30
- package/tests/hydration/compiled/server/events.js +66 -18
- package/tests/hydration/compiled/server/for.js +117 -41
- package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
- package/tests/hydration/compiled/server/head.js +20 -20
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +70 -238
- package/tests/hydration/compiled/server/if-children.js +107 -15
- package/tests/hydration/compiled/server/if.js +11 -15
- package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
- package/tests/hydration/compiled/server/portal.js +14 -22
- package/tests/hydration/compiled/server/reactivity.js +14 -14
- package/tests/hydration/compiled/server/streaming.js +19 -19
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
- package/tests/hydration/compiled/server/try.js +8 -8
- package/tests/hydration/compiled/server/typed-text.js +17 -0
- package/tests/hydration/components/basic.tsrx +44 -8
- package/tests/hydration/components/composite.tsrx +2 -2
- package/tests/hydration/components/events.tsrx +25 -25
- package/tests/hydration/components/for.tsrx +115 -67
- package/tests/hydration/components/fragment-cursor.tsrx +650 -0
- package/tests/hydration/components/head.tsrx +16 -16
- package/tests/hydration/components/hmr.tsrx +2 -2
- package/tests/hydration/components/html.tsrx +7 -7
- package/tests/hydration/components/if-children.tsrx +72 -25
- package/tests/hydration/components/if.tsrx +18 -18
- package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
- package/tests/hydration/components/portal.tsrx +3 -3
- package/tests/hydration/components/reactivity.tsrx +16 -16
- package/tests/hydration/components/streaming.tsrx +20 -20
- package/tests/hydration/components/switch.tsrx +20 -20
- package/tests/hydration/components/text-types.ts +4 -0
- package/tests/hydration/components/track-async-serialization.tsrx +80 -26
- package/tests/hydration/components/try.tsrx +8 -8
- package/tests/hydration/components/typed-text.tsrx +22 -0
- package/tests/hydration/fixtures/money.js +10 -0
- package/tests/hydration/for.test.js +36 -0
- package/tests/hydration/fragment-cursor.test.js +111 -0
- package/tests/hydration/if-children.test.js +24 -0
- package/tests/hydration/streaming.test.js +19 -0
- package/tests/hydration/track-async-serialization.test.js +87 -2
- package/tests/hydration/tsconfig.text-types.json +10 -0
- package/tests/hydration/typed-text.test.js +34 -0
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +42 -42
- package/tests/server/basic.components.test.tsrx +64 -8
- package/tests/server/basic.test.tsrx +34 -32
- package/tests/server/compiler.test.tsrx +1 -70
- package/tests/server/composite.props.test.tsrx +6 -6
- package/tests/server/dynamic-elements.test.tsrx +31 -8
- package/tests/server/for.test.tsrx +94 -0
- package/tests/server/head.test.tsrx +11 -11
- package/tests/server/scoped-styles.test.tsrx +2 -2
- package/tests/server/streaming-ssr.test.tsrx +48 -43
- package/tests/server/track-async-serialization.test.tsrx +204 -21
- package/tests/server/try.test.tsrx +48 -48
- package/tests/types/transport.ts +40 -0
- package/tests/utils/vite-plugin-config.test.js +23 -0
- package/types/index.d.ts +48 -7
- package/types/server.d.ts +3 -0
- package/types/transport.d.ts +15 -0
- package/src/runtime/internal/client/switch.js +0 -113
- package/src/utils/errors.js +0 -13
- package/tests/client/lazy-array.test.tsrx +0 -31
- package/tests/client/lazy-destructuring.test.tsrx +0 -438
- package/tests/client/tracked-index-access.test.tsrx +0 -113
- package/tests/server/lazy-destructuring.test.tsrx +0 -595
- package/tests/server/tracked-index-access.test.tsrx +0 -76
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
import type { Tracked } from 'ripple';
|
|
2
|
-
import { flushSync, track } from 'ripple';
|
|
3
|
-
|
|
4
|
-
describe('lazy destructuring', () => {
|
|
5
|
-
it('supports tracked value getter and setter', () => {
|
|
6
|
-
function Test() @{
|
|
7
|
-
let count = track(1);
|
|
8
|
-
let doubled = track(() => count.value * 2);
|
|
9
|
-
<>
|
|
10
|
-
<div>{`${count.value}-${doubled.value}`}</div>
|
|
11
|
-
<button
|
|
12
|
-
onClick={() => {
|
|
13
|
-
count.value = 5;
|
|
14
|
-
}}
|
|
15
|
-
>{'set'}</button>
|
|
16
|
-
</>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
render(Test);
|
|
20
|
-
expect(container.querySelector('div')!.textContent).toBe('1-2');
|
|
21
|
-
container.querySelector('button')!.click();
|
|
22
|
-
flushSync();
|
|
23
|
-
expect(container.querySelector('div')!.textContent).toBe('5-10');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('lazily accesses object properties with const', () => {
|
|
27
|
-
function Inner(&{ a, b }: { a: number; b: string }) @{
|
|
28
|
-
<pre>{`${a}-${b}`}</pre>
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function Test() @{
|
|
32
|
-
let &[a] = track(1);
|
|
33
|
-
let &[b] = track('hello');
|
|
34
|
-
<>
|
|
35
|
-
<Inner {a} {b} />
|
|
36
|
-
<button
|
|
37
|
-
onClick={() => {
|
|
38
|
-
a = 2;
|
|
39
|
-
b = 'world';
|
|
40
|
-
}}
|
|
41
|
-
>{'update'}</button>
|
|
42
|
-
</>
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
render(Test);
|
|
46
|
-
expect(container.querySelector('pre')!.textContent).toBe('1-hello');
|
|
47
|
-
container.querySelector('button')!.click();
|
|
48
|
-
flushSync();
|
|
49
|
-
expect(container.querySelector('pre')!.textContent).toBe('2-world');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('lazily accesses array elements with const', () => {
|
|
53
|
-
function Inner(&{ first, second }: { first: number; second: number }) @{
|
|
54
|
-
<pre>{`${first}-${second}`}</pre>
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function Test() @{
|
|
58
|
-
let &[first] = track(10);
|
|
59
|
-
let &[second] = track(20);
|
|
60
|
-
<>
|
|
61
|
-
<Inner {first} {second} />
|
|
62
|
-
<button
|
|
63
|
-
onClick={() => {
|
|
64
|
-
first = 30;
|
|
65
|
-
second = 40;
|
|
66
|
-
}}
|
|
67
|
-
>{'update'}</button>
|
|
68
|
-
</>
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
render(Test);
|
|
72
|
-
expect(container.querySelector('pre')!.textContent).toBe('10-20');
|
|
73
|
-
container.querySelector('button')!.click();
|
|
74
|
-
flushSync();
|
|
75
|
-
expect(container.querySelector('pre')!.textContent).toBe('30-40');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('preserves numeric member access on lazy array value bindings', () => {
|
|
79
|
-
function Child({ pair: &[first] }: { pair: [{ 0: string }] }) @{
|
|
80
|
-
<pre>{first[0]}</pre>
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function Test() @{
|
|
84
|
-
<Child pair={[{ 0: 'x' }]} />
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
render(Test);
|
|
88
|
-
expect(container.querySelector('pre')!.textContent).toBe('x');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('supports default values in lazy object destructuring', () => {
|
|
92
|
-
function Test() @{
|
|
93
|
-
const obj: { a: number; b?: number } = { a: 5 };
|
|
94
|
-
const &{ a, b = 99 } = obj;
|
|
95
|
-
<pre>{`${a}-${b}`}</pre>
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
render(Test);
|
|
99
|
-
expect(container.querySelector('pre')!.textContent).toBe('5-99');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('supports lazy destructuring in component params', () => {
|
|
103
|
-
function Inner(&{ name, age }: { name: string; age: number }) @{
|
|
104
|
-
<pre>{`${name}-${age}`}</pre>
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function Test() @{
|
|
108
|
-
<Inner name="Alice" age={30} />
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
render(Test);
|
|
112
|
-
expect(container.querySelector('pre')!.textContent).toBe('Alice-30');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('supports lazy destructuring in component params with reactivity', () => {
|
|
116
|
-
function Inner(&{ count }: { count: number }) @{
|
|
117
|
-
<pre>{count}</pre>
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function Test() @{
|
|
121
|
-
let &[count] = track(0);
|
|
122
|
-
<>
|
|
123
|
-
<Inner {count} />
|
|
124
|
-
<button
|
|
125
|
-
onClick={() => {
|
|
126
|
-
count++;
|
|
127
|
-
}}
|
|
128
|
-
>{'increment'}</button>
|
|
129
|
-
</>
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
render(Test);
|
|
133
|
-
expect(container.querySelector('pre')!.textContent).toBe('0');
|
|
134
|
-
container.querySelector('button')!.click();
|
|
135
|
-
flushSync();
|
|
136
|
-
expect(container.querySelector('pre')!.textContent).toBe('1');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('supports nested lazy destructuring in non-lazy component params', () => {
|
|
140
|
-
function Inner({ something: &[first, second] }: { something: Tracked<number> }) @{
|
|
141
|
-
first = second.value + 1;
|
|
142
|
-
<pre>{`${first}-${second.value}`}</pre>
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function Test() @{
|
|
146
|
-
<Inner something={track(1)} />
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
render(Test);
|
|
150
|
-
expect(container.querySelector('pre')!.textContent).toBe('2-2');
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it(
|
|
154
|
-
'preserves lazy getter/setter behavior for nested rest destructuring in non-lazy component params',
|
|
155
|
-
() => {
|
|
156
|
-
function Inner({
|
|
157
|
-
values: [head, ...&{ length: rest_length, 0: first_rest }],
|
|
158
|
-
}: {
|
|
159
|
-
values: [number, Tracked<number>, Tracked<number>];
|
|
160
|
-
}) @{
|
|
161
|
-
const before = `${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
162
|
-
rest_length = 0;
|
|
163
|
-
<pre>{`${head}-${before}-${first_rest?.value ?? 'nil'}-${rest_length}`}</pre>
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function Test() @{
|
|
167
|
-
<Inner values={[10, track(20), track(30)]} />
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
render(Test);
|
|
171
|
-
expect(container.querySelector('pre')!.textContent).toBe('10-20-2-nil-0');
|
|
172
|
-
},
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
it('supports lazy destructuring in function params', () => {
|
|
176
|
-
function Test() @{
|
|
177
|
-
function getInfo(&{ x, y }: { x: number; y: number }) {
|
|
178
|
-
return x + y;
|
|
179
|
-
}
|
|
180
|
-
const result = getInfo({ x: 3, y: 7 });
|
|
181
|
-
<pre>{result}</pre>
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
render(Test);
|
|
185
|
-
expect(container.querySelector('pre')!.textContent).toBe('10');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('supports nested lazy destructuring in non-lazy function params', () => {
|
|
189
|
-
function Test() @{
|
|
190
|
-
const something = track(1);
|
|
191
|
-
function getInfo({ something: &[first, second] }: { something: Tracked<number> }) {
|
|
192
|
-
first = second.value + 1;
|
|
193
|
-
return `${first}-${second.value}`;
|
|
194
|
-
}
|
|
195
|
-
const result = getInfo({ something });
|
|
196
|
-
<pre>{result}</pre>
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
render(Test);
|
|
200
|
-
expect(container.querySelector('pre')!.textContent).toBe('2-2');
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it(
|
|
204
|
-
'preserves lazy getter/setter behavior for nested rest destructuring in non-lazy function params',
|
|
205
|
-
() => {
|
|
206
|
-
function Test() @{
|
|
207
|
-
function summarize({
|
|
208
|
-
values: [head, ...&{ length: rest_length, 0: first_rest }],
|
|
209
|
-
}: {
|
|
210
|
-
values: [number, Tracked<number>, Tracked<number>];
|
|
211
|
-
}) {
|
|
212
|
-
const before = `${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
213
|
-
rest_length = 0;
|
|
214
|
-
return `${head}-${before}-${first_rest?.value ?? 'nil'}-${rest_length}`;
|
|
215
|
-
}
|
|
216
|
-
const result = summarize({ values: [5, track(6), track(7)] });
|
|
217
|
-
<pre>{result}</pre>
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
render(Test);
|
|
221
|
-
expect(container.querySelector('pre')!.textContent).toBe('5-6-2-nil-0');
|
|
222
|
-
},
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
it('supports let lazy destructuring with assignment writeback', () => {
|
|
226
|
-
function Test() @{
|
|
227
|
-
const obj = { a: 1, b: 2 };
|
|
228
|
-
let &{ a, b } = obj;
|
|
229
|
-
a = 10;
|
|
230
|
-
b = 20;
|
|
231
|
-
<pre>{`${obj.a}-${obj.b}`}</pre>
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
render(Test);
|
|
235
|
-
expect(container.querySelector('pre')!.textContent).toBe('10-20');
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('supports compound assignment operators on lazy bindings', () => {
|
|
239
|
-
function Test() @{
|
|
240
|
-
const obj = { a: 5, b: 10 };
|
|
241
|
-
let &{ a, b } = obj;
|
|
242
|
-
a += 3;
|
|
243
|
-
b *= 2;
|
|
244
|
-
<pre>{`${obj.a}-${obj.b}`}</pre>
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
render(Test);
|
|
248
|
-
expect(container.querySelector('pre')!.textContent).toBe('8-20');
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('supports update expressions on lazy bindings', () => {
|
|
252
|
-
function Test() @{
|
|
253
|
-
const obj = { count: 0 };
|
|
254
|
-
let &{ count } = obj;
|
|
255
|
-
count++;
|
|
256
|
-
count++;
|
|
257
|
-
count--;
|
|
258
|
-
<pre>{obj.count}</pre>
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
render(Test);
|
|
262
|
-
expect(container.querySelector('pre')!.textContent).toBe('1');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('supports function params with lazy destructuring and default values', () => {
|
|
266
|
-
function Test() @{
|
|
267
|
-
function calc(&{ x, y = 100 }: { x: number; y?: number }) {
|
|
268
|
-
return x + y;
|
|
269
|
-
}
|
|
270
|
-
const a = calc({ x: 5, y: 10 });
|
|
271
|
-
const b = calc({ x: 5 });
|
|
272
|
-
<pre>{`${a}-${b}`}</pre>
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
render(Test);
|
|
276
|
-
expect(container.querySelector('pre')!.textContent).toBe('15-105');
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('supports lazy destructuring with default value writeback', () => {
|
|
280
|
-
function Test() @{
|
|
281
|
-
const obj: { a: number; b?: number } = { a: 1 };
|
|
282
|
-
let &{ a, b = 50 } = obj;
|
|
283
|
-
b = 99;
|
|
284
|
-
<pre>{`${a}-${obj.b}`}</pre>
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
render(Test);
|
|
288
|
-
expect(container.querySelector('pre')!.textContent).toBe('1-99');
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it('supports rest destructuring from iterable array-like tracked values', () => {
|
|
292
|
-
function Test() @{
|
|
293
|
-
let &[value, ...rest] = track(0);
|
|
294
|
-
<pre>{`${value}-${rest.length}-${(rest[0] as Tracked<number>).value === value}`}</pre>
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
render(Test);
|
|
298
|
-
expect(container.querySelector('pre')!.textContent).toBe('0-1-true');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('supports rest destructuring from length-only array-like sources', () => {
|
|
302
|
-
function Test() @{
|
|
303
|
-
const source = { 0: 'x', 1: 'y', 2: 'z', length: 3 };
|
|
304
|
-
const &[first, ...rest] = source;
|
|
305
|
-
<pre>{`${first}-${rest.join(',')}`}</pre>
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
render(Test);
|
|
309
|
-
expect(container.querySelector('pre')!.textContent).toBe('x-y,z');
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it('supports rest destructuring from iterable sources', () => {
|
|
313
|
-
function Test() @{
|
|
314
|
-
const source = {
|
|
315
|
-
*[Symbol.iterator]() {
|
|
316
|
-
yield 'x';
|
|
317
|
-
yield 'y';
|
|
318
|
-
yield 'z';
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
const &[first, ...rest] = source;
|
|
322
|
-
<pre>{`${first}-${rest.join(',')}`}</pre>
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
render(Test);
|
|
326
|
-
expect(container.querySelector('pre')!.textContent).toBe('x-y,z');
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('supports update expressions on lazy bindings with default values', () => {
|
|
330
|
-
function Test() @{
|
|
331
|
-
const obj: { count?: number } = {};
|
|
332
|
-
let &{ count = 0 } = obj;
|
|
333
|
-
count++;
|
|
334
|
-
count++;
|
|
335
|
-
<pre>{obj.count}</pre>
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
render(Test);
|
|
339
|
-
expect(container.querySelector('pre')!.textContent).toBe('2');
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it('supports member access on lazy destructured objects', () => {
|
|
343
|
-
function Test() @{
|
|
344
|
-
const obj = { user: { name: 'Alice', age: 30 } };
|
|
345
|
-
const &{ user } = obj;
|
|
346
|
-
<pre>{`${user.name}-${user.age}`}</pre>
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
render(Test);
|
|
350
|
-
expect(container.querySelector('pre')!.textContent).toBe('Alice-30');
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('supports standalone lazy array destructuring with track()', () => {
|
|
354
|
-
function Test() @{
|
|
355
|
-
let count: number;
|
|
356
|
-
&[count] = track(0);
|
|
357
|
-
<>
|
|
358
|
-
<div>{count}</div>
|
|
359
|
-
<button
|
|
360
|
-
onClick={() => {
|
|
361
|
-
count++;
|
|
362
|
-
}}
|
|
363
|
-
>{'inc'}</button>
|
|
364
|
-
</>
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
render(Test);
|
|
368
|
-
expect(container.querySelector('div')!.textContent).toBe('0');
|
|
369
|
-
container.querySelector('button')!.click();
|
|
370
|
-
flushSync();
|
|
371
|
-
expect(container.querySelector('div')!.textContent).toBe('1');
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
it('supports standalone lazy array destructuring with second element', () => {
|
|
375
|
-
function Test() @{
|
|
376
|
-
let value;
|
|
377
|
-
let tracked;
|
|
378
|
-
&[value, tracked] = track(42);
|
|
379
|
-
<>
|
|
380
|
-
<div>{value}</div>
|
|
381
|
-
<button
|
|
382
|
-
onClick={() => {
|
|
383
|
-
value = 100;
|
|
384
|
-
}}
|
|
385
|
-
>{'set'}</button>
|
|
386
|
-
</>
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
render(Test);
|
|
390
|
-
expect(container.querySelector('div')!.textContent).toBe('42');
|
|
391
|
-
container.querySelector('button')!.click();
|
|
392
|
-
flushSync();
|
|
393
|
-
expect(container.querySelector('div')!.textContent).toBe('100');
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
it('supports direct value access on tracked values', () => {
|
|
397
|
-
function Test() @{
|
|
398
|
-
let tracked = track(0);
|
|
399
|
-
++tracked.value;
|
|
400
|
-
tracked.value++;
|
|
401
|
-
tracked.value = tracked.value + 1;
|
|
402
|
-
let value = tracked.value;
|
|
403
|
-
let ref = tracked;
|
|
404
|
-
<pre>{`${value}-${ref === tracked}`}</pre>
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
render(Test);
|
|
408
|
-
expect(container.querySelector('pre')!.textContent).toBe('3-true');
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
it('supports lazy destructured tracked ref value access', () => {
|
|
412
|
-
function Child({ pair: &[value, tracked_ref] }: { pair: Tracked<number> }) @{
|
|
413
|
-
++tracked_ref.value;
|
|
414
|
-
tracked_ref.value++;
|
|
415
|
-
<pre>{`${value}-${tracked_ref.value}`}</pre>
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function Test() @{
|
|
419
|
-
let tracked = track(0);
|
|
420
|
-
<Child pair={tracked} />
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
render(Test);
|
|
424
|
-
expect(container.querySelector('pre')!.textContent).toBe('2-2');
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
it('supports standalone lazy object destructuring', () => {
|
|
428
|
-
function Test() @{
|
|
429
|
-
let a;
|
|
430
|
-
let b;
|
|
431
|
-
&{ a, b } = { a: 10, b: 20 };
|
|
432
|
-
<pre>{`${a}-${b}`}</pre>
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
render(Test);
|
|
436
|
-
expect(container.querySelector('pre')!.textContent).toBe('10-20');
|
|
437
|
-
});
|
|
438
|
-
});
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { track } from 'ripple';
|
|
3
|
-
import {
|
|
4
|
-
lazy_array_get,
|
|
5
|
-
lazy_array_set,
|
|
6
|
-
lazy_array_update,
|
|
7
|
-
} from '../../src/runtime/internal/client/runtime.js';
|
|
8
|
-
|
|
9
|
-
const value_message = /Use \.value or &\[\] lazy destructuring/;
|
|
10
|
-
const reference_message = /Use the tracked value directly instead/;
|
|
11
|
-
const value_index = Number(0);
|
|
12
|
-
const reference_index = Number(1);
|
|
13
|
-
|
|
14
|
-
describe('client tracked numeric access', () => {
|
|
15
|
-
it('throws when tracked values are accessed through numeric properties', () => {
|
|
16
|
-
let value: any;
|
|
17
|
-
|
|
18
|
-
function Test() @{
|
|
19
|
-
value = track(0);
|
|
20
|
-
<div />
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
render(Test);
|
|
24
|
-
|
|
25
|
-
expect(() => value[value_index]).toThrow(value_message);
|
|
26
|
-
expect(() => {
|
|
27
|
-
value[value_index] = 1;
|
|
28
|
-
}).toThrow(value_message);
|
|
29
|
-
expect(() => value[reference_index]).toThrow(reference_message);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('throws when derived values are accessed through numeric properties', () => {
|
|
33
|
-
let value: any;
|
|
34
|
-
|
|
35
|
-
function Test() @{
|
|
36
|
-
value = track(() => 1);
|
|
37
|
-
<div />
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
render(Test);
|
|
41
|
-
|
|
42
|
-
expect(() => value[value_index]).toThrow(value_message);
|
|
43
|
-
expect(() => {
|
|
44
|
-
value[value_index] = 2;
|
|
45
|
-
}).toThrow(value_message);
|
|
46
|
-
expect(() => value[reference_index]).toThrow(reference_message);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('sets tracked lazy index 0 and rejects tracked lazy index 1', () => {
|
|
50
|
-
let value: any;
|
|
51
|
-
let next: any;
|
|
52
|
-
|
|
53
|
-
function Test() @{
|
|
54
|
-
value = track(0);
|
|
55
|
-
next = track(1);
|
|
56
|
-
<div />
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
render(Test);
|
|
60
|
-
|
|
61
|
-
lazy_array_set(value, 2, 0);
|
|
62
|
-
expect(value.value).toBe(2);
|
|
63
|
-
expect(() => {
|
|
64
|
-
lazy_array_set(value, next, 1);
|
|
65
|
-
}).toThrow(reference_message);
|
|
66
|
-
expect(() => {
|
|
67
|
-
lazy_array_update(value, 1);
|
|
68
|
-
}).toThrow(reference_message);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('returns undefined for tracked lazy indexes past the tuple length', () => {
|
|
72
|
-
let value: any;
|
|
73
|
-
let derived: any;
|
|
74
|
-
|
|
75
|
-
function Test() @{
|
|
76
|
-
value = track(0);
|
|
77
|
-
derived = track(() => value.value + 1);
|
|
78
|
-
<div />
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
render(Test);
|
|
82
|
-
|
|
83
|
-
expect(lazy_array_get(value, 0)).toBe(0);
|
|
84
|
-
expect(lazy_array_get(value, 1)).toBe(value);
|
|
85
|
-
expect(lazy_array_get(value, 2)).toBeUndefined();
|
|
86
|
-
expect(lazy_array_get(derived, 0)).toBe(1);
|
|
87
|
-
expect(lazy_array_get(derived, 1)).toBe(derived);
|
|
88
|
-
expect(lazy_array_get(derived, 2)).toBeUndefined();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('ignores tracked lazy writes past the tuple length', () => {
|
|
92
|
-
let value: any;
|
|
93
|
-
let derived: any;
|
|
94
|
-
|
|
95
|
-
function Test() @{
|
|
96
|
-
value = track(0);
|
|
97
|
-
derived = track(() => value.value + 1);
|
|
98
|
-
<div />
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
render(Test);
|
|
102
|
-
|
|
103
|
-
lazy_array_set(value, 10, 2);
|
|
104
|
-
lazy_array_update(value, 2);
|
|
105
|
-
lazy_array_set(derived, 20, 2);
|
|
106
|
-
lazy_array_update(derived, 2);
|
|
107
|
-
|
|
108
|
-
expect(lazy_array_get(value, 2)).toBeUndefined();
|
|
109
|
-
expect(lazy_array_get(derived, 2)).toBeUndefined();
|
|
110
|
-
expect(Object.hasOwn(value, 2)).toBe(false);
|
|
111
|
-
expect(Object.hasOwn(derived, 2)).toBe(false);
|
|
112
|
-
});
|
|
113
|
-
});
|