ripple 0.3.71 → 0.3.74
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 +75 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -8
- package/src/runtime/index-client.js +3 -13
- package/src/runtime/internal/client/blocks.js +3 -25
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +59 -71
- package/tests/client/basic/basic.components.test.tsrx +196 -222
- package/tests/client/basic/basic.errors.test.tsrx +72 -78
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +364 -296
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +41 -44
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +491 -437
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +62 -69
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +227 -283
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +40 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +195 -215
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +290 -371
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +396 -325
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -286
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +120 -167
- package/tests/server/basic.components.test.tsrx +163 -197
- package/tests/server/basic.test.tsrx +298 -220
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +103 -135
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +31 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +58 -66
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +1 -0
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -15,9 +15,9 @@ const errorMap = new ErrorMap();`;
|
|
|
15
15
|
|
|
16
16
|
it('removes type assertions from function parameters and leaves default values', () => {
|
|
17
17
|
const source = `
|
|
18
|
-
function getString(e: string = 'test') {
|
|
19
|
-
|
|
20
|
-
}`;
|
|
18
|
+
function getString(e: string = 'test') {
|
|
19
|
+
return e;
|
|
20
|
+
}`;
|
|
21
21
|
|
|
22
22
|
const result = compile(source, 'test.tsrx', { mode: 'server' });
|
|
23
23
|
|
|
@@ -31,11 +31,11 @@ beforeAll(() => {
|
|
|
31
31
|
(global as any).count++;
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
function Test() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
function Test() @{
|
|
35
|
+
let toggle: { value: boolean } | undefined;
|
|
36
|
+
toggle!.value = false;
|
|
37
|
+
toggle!.value++;
|
|
38
|
+
}`;
|
|
39
39
|
|
|
40
40
|
const { code } = compile(source, 'test.tsrx', { mode: 'server' });
|
|
41
41
|
|
|
@@ -50,13 +50,13 @@ function Test() { return <>
|
|
|
50
50
|
it(
|
|
51
51
|
'compiles writes to unknown lazy array index 1 through lazy array helpers in SSR output',
|
|
52
52
|
() => {
|
|
53
|
-
const source = `function Child({ pair: &[first, second] }) {
|
|
53
|
+
const source = `function Child({ pair: &[first, second] }) @{
|
|
54
54
|
second = 10;
|
|
55
55
|
<div>{first}</div>
|
|
56
|
-
|
|
57
|
-
function App() {
|
|
56
|
+
}
|
|
57
|
+
function App() @{
|
|
58
58
|
<Child pair={[0, 1]} />
|
|
59
|
-
|
|
59
|
+
}`;
|
|
60
60
|
const { code } = compile(source, 'test.tsrx', { mode: 'server' });
|
|
61
61
|
|
|
62
62
|
expect(code).toContain('_$_.lazy_array_set(lazy, 10, 1)');
|
|
@@ -65,13 +65,13 @@ function App() { return <>
|
|
|
65
65
|
);
|
|
66
66
|
|
|
67
67
|
it('does not double-wrap member access on lazy array value bindings in SSR output', () => {
|
|
68
|
-
const source = `function Child({ pair: &[first] }) {
|
|
68
|
+
const source = `function Child({ pair: &[first] }) @{
|
|
69
69
|
let value = first[0];
|
|
70
70
|
<div>{value}</div>
|
|
71
|
-
|
|
72
|
-
function App() {
|
|
71
|
+
}
|
|
72
|
+
function App() @{
|
|
73
73
|
<Child pair={[{ 0: 'x' }]} />
|
|
74
|
-
|
|
74
|
+
}`;
|
|
75
75
|
const { code } = compile(source, 'test.tsrx', { mode: 'server' });
|
|
76
76
|
|
|
77
77
|
expect(code).toContain('let value = _$_.lazy_array_get(lazy, 0)[0];');
|
|
@@ -80,13 +80,13 @@ function App() { return <>
|
|
|
80
80
|
|
|
81
81
|
it('throws on indexed access through known tracked lazy destructures in SSR output', () => {
|
|
82
82
|
const source = `import { track } from 'ripple';
|
|
83
|
-
function App() {
|
|
83
|
+
function App() @{
|
|
84
84
|
let &[value, tracked_ref] = track({ 0: 'x' });
|
|
85
85
|
let nested = value[0];
|
|
86
86
|
tracked_ref[0] = { 0: 'y' };
|
|
87
87
|
let next = value[0];
|
|
88
88
|
<div>{nested}{next}</div>
|
|
89
|
-
|
|
89
|
+
}`;
|
|
90
90
|
|
|
91
91
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).toThrow(
|
|
92
92
|
/Use \.value or &\[\] lazy destructuring/,
|
|
@@ -95,7 +95,7 @@ function App() { return <>
|
|
|
95
95
|
|
|
96
96
|
it('throws on known tracked indexed access in SSR output', () => {
|
|
97
97
|
const source = `import { track } from 'ripple';
|
|
98
|
-
function App() {
|
|
98
|
+
function App() @{
|
|
99
99
|
let tracked = track(0);
|
|
100
100
|
++tracked[0];
|
|
101
101
|
tracked[0]++;
|
|
@@ -103,7 +103,7 @@ function App() { return <>
|
|
|
103
103
|
let value = tracked[0];
|
|
104
104
|
let ref = tracked[1];
|
|
105
105
|
<div>{value}</div>
|
|
106
|
-
|
|
106
|
+
}`;
|
|
107
107
|
|
|
108
108
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).toThrow(
|
|
109
109
|
/Use \.value or &\[\] lazy destructuring/,
|
|
@@ -114,15 +114,15 @@ function App() { return <>
|
|
|
114
114
|
'compiles indexed access on unknown lazy tracked refs through lazy array helpers in SSR output',
|
|
115
115
|
() => {
|
|
116
116
|
const source = `import { track } from 'ripple';
|
|
117
|
-
function Child({ pair: &[value, tracked_ref] }) {
|
|
117
|
+
function Child({ pair: &[value, tracked_ref] }) @{
|
|
118
118
|
++tracked_ref[0];
|
|
119
119
|
tracked_ref[0]++;
|
|
120
120
|
<div>{value}</div>
|
|
121
|
-
|
|
122
|
-
function App() {
|
|
121
|
+
}
|
|
122
|
+
function App() @{
|
|
123
123
|
let tracked = track(0);
|
|
124
124
|
<Child pair={tracked} />
|
|
125
|
-
|
|
125
|
+
}`;
|
|
126
126
|
const { code } = compile(source, 'test.tsrx', { mode: 'server' });
|
|
127
127
|
|
|
128
128
|
expect(code).toContain('_$_.lazy_array_get(lazy, 1)');
|
|
@@ -166,29 +166,29 @@ class PrintEvent implements BaseEvent {
|
|
|
166
166
|
|
|
167
167
|
it('throws error for interpolating children as text in SSR mode', () => {
|
|
168
168
|
const source = `
|
|
169
|
-
export function Layout({ children }) {
|
|
169
|
+
export function Layout({ children }) @{
|
|
170
170
|
<div>{children}</div>
|
|
171
|
-
|
|
171
|
+
}`;
|
|
172
172
|
|
|
173
173
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).not.toThrow();
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
it('throws error for interpolating props.children as text in SSR mode', () => {
|
|
177
177
|
const source = `
|
|
178
|
-
export function Layout(props) {
|
|
178
|
+
export function Layout(props) @{
|
|
179
179
|
<div>{props.children}</div>
|
|
180
|
-
|
|
180
|
+
}`;
|
|
181
181
|
|
|
182
182
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).not.toThrow();
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
-
it('compiles indented direct
|
|
185
|
+
it('compiles indented direct JSX text children in SSR mode', () => {
|
|
186
186
|
const source = `
|
|
187
|
-
export default function A() {
|
|
187
|
+
export default function A() @{
|
|
188
188
|
<div>
|
|
189
|
-
|
|
189
|
+
Hello
|
|
190
190
|
</div>
|
|
191
|
-
|
|
191
|
+
}`;
|
|
192
192
|
|
|
193
193
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
194
194
|
|
|
@@ -196,11 +196,81 @@ export default function A() { return <>
|
|
|
196
196
|
expect(result).not.toContain(`"Hello";`);
|
|
197
197
|
});
|
|
198
198
|
|
|
199
|
+
it('does not merge adjacent call-containing children into stringified text in SSR output', () => {
|
|
200
|
+
const setup = `function child(label) {
|
|
201
|
+
<span>{label}</span>
|
|
202
|
+
}
|
|
203
|
+
function Constructed(label) {
|
|
204
|
+
return child(label);
|
|
205
|
+
}
|
|
206
|
+
const factory = child;
|
|
207
|
+
function identity(value) {
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
function empty() {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
let assigned;
|
|
214
|
+
const lookup = { member: child('member') };
|
|
215
|
+
function getKey() {
|
|
216
|
+
return 'member';
|
|
217
|
+
}
|
|
218
|
+
function touch() {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function tag() {
|
|
222
|
+
return child('tagged');
|
|
223
|
+
}
|
|
224
|
+
const values = { member: 0 };`;
|
|
225
|
+
|
|
226
|
+
const cases = [
|
|
227
|
+
{ name: 'call expression', expression: 'child(\'call\')' },
|
|
228
|
+
{ name: 'new expression', expression: 'new Constructed(\'new\')' },
|
|
229
|
+
{ name: 'chain expression', expression: 'factory?.(\'chain\')' },
|
|
230
|
+
{ name: 'parenthesized expression', expression: '(child(\'parenthesized\'))' },
|
|
231
|
+
{ name: 'TS as expression', expression: 'child(\'as\') as any' },
|
|
232
|
+
{ name: 'TS non-null expression', expression: 'child(\'non-null\')!' },
|
|
233
|
+
{ name: 'TS satisfies expression', expression: 'child(\'satisfies\') satisfies any' },
|
|
234
|
+
{
|
|
235
|
+
name: 'TS instantiation expression',
|
|
236
|
+
expression: 'identity<typeof child>(child)(\'instantiation\')',
|
|
237
|
+
},
|
|
238
|
+
{ name: 'array expression', expression: '[child(\'array\')]' },
|
|
239
|
+
{ name: 'assignment expression', expression: 'assigned = child(\'assignment\')' },
|
|
240
|
+
{ name: 'binary expression', expression: 'empty() + \'\'' },
|
|
241
|
+
{ name: 'logical expression', expression: 'true && child(\'logical\')' },
|
|
242
|
+
{ name: 'conditional expression', expression: 'true ? child(\'conditional\') : \'\'' },
|
|
243
|
+
{ name: 'member expression', expression: 'lookup[getKey()]' },
|
|
244
|
+
{
|
|
245
|
+
name: 'object expression',
|
|
246
|
+
expression: '{ [Symbol.for(\'ripple.element\')]: true, render() { return child(\'object\'); } }',
|
|
247
|
+
},
|
|
248
|
+
{ name: 'sequence expression', expression: '(touch(), child(\'sequence\'))' },
|
|
249
|
+
{ name: 'tagged template expression', expression: 'tag`tagged`' },
|
|
250
|
+
{ name: 'template literal', expression: '`${empty()}`' },
|
|
251
|
+
{ name: 'unary expression', expression: 'void empty()' },
|
|
252
|
+
{ name: 'update expression', expression: 'values[getKey()]++' },
|
|
253
|
+
];
|
|
254
|
+
|
|
255
|
+
for (const test_case of cases) {
|
|
256
|
+
const source = `${setup}
|
|
257
|
+
export function App() @{
|
|
258
|
+
<div>{'${test_case.name}:'}{${test_case.expression}}</div>
|
|
259
|
+
}`;
|
|
260
|
+
|
|
261
|
+
const { code } = compile(source, `${test_case.name}.tsrx`, { mode: 'server' });
|
|
262
|
+
|
|
263
|
+
if (code.includes('String(')) {
|
|
264
|
+
throw new Error(`${test_case.name} was merged into a stringified text expression:\n${code}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
199
269
|
it('decodes JSX-style entities before server text escaping', () => {
|
|
200
270
|
const result = compile(
|
|
201
|
-
`function App() {
|
|
202
|
-
<div>
|
|
203
|
-
|
|
271
|
+
`function App() @{
|
|
272
|
+
<div>Rock & "Roll"</div>
|
|
273
|
+
}`,
|
|
204
274
|
'/src/App.tsrx',
|
|
205
275
|
{ mode: 'server' },
|
|
206
276
|
);
|
|
@@ -210,10 +280,10 @@ export default function A() { return <>
|
|
|
210
280
|
|
|
211
281
|
it('emits anonymous component expressions as arrows in SSR output', () => {
|
|
212
282
|
const source = `
|
|
213
|
-
const Inline = (props) =>
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
`;
|
|
283
|
+
const Inline = (props) => @{
|
|
284
|
+
<div>{props.x}</div>
|
|
285
|
+
}
|
|
286
|
+
`;
|
|
217
287
|
const result = compile(source, 'anonymous-component.tsrx', { mode: 'server' }).code;
|
|
218
288
|
|
|
219
289
|
expect(result).toContain('const Inline = (props) => {');
|
|
@@ -225,9 +295,9 @@ const Inline = (props) => <>
|
|
|
225
295
|
|
|
226
296
|
it('emits function-expression components as functions in SSR output', () => {
|
|
227
297
|
const source = `
|
|
228
|
-
const Inline = function(props) {
|
|
298
|
+
const Inline = function(props) @{
|
|
229
299
|
<div>{props.x}</div>
|
|
230
|
-
|
|
300
|
+
}
|
|
231
301
|
`;
|
|
232
302
|
const result = compile(source, 'anonymous-component.tsrx', { mode: 'server' }).code;
|
|
233
303
|
|
|
@@ -240,9 +310,9 @@ const Inline = function(props) { return <>
|
|
|
240
310
|
|
|
241
311
|
it('throws error for calling children as a function in SSR mode', () => {
|
|
242
312
|
const source = `
|
|
243
|
-
export function Layout({ children }) {
|
|
313
|
+
export function Layout({ children }) @{
|
|
244
314
|
{children()}
|
|
245
|
-
|
|
315
|
+
}`;
|
|
246
316
|
|
|
247
317
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).toThrow(
|
|
248
318
|
'`children` cannot be called like a regular function. Render it with `{children}` or `{props.children}` instead.',
|
|
@@ -251,9 +321,9 @@ export function Layout({ children }) { return <>
|
|
|
251
321
|
|
|
252
322
|
it('throws error for calling props.children as a function in SSR mode', () => {
|
|
253
323
|
const source = `
|
|
254
|
-
export function Layout(props) {
|
|
324
|
+
export function Layout(props) @{
|
|
255
325
|
{props.children()}
|
|
256
|
-
|
|
326
|
+
}`;
|
|
257
327
|
|
|
258
328
|
expect(() => compile(source, 'test.tsrx', { mode: 'server' })).toThrow(
|
|
259
329
|
'`children` cannot be called like a regular function. Render it with `{children}` or `{props.children}` instead.',
|
|
@@ -262,17 +332,17 @@ export function Layout(props) { return <>
|
|
|
262
332
|
|
|
263
333
|
it('merges explicit children prop with implicit children in SSR output', () => {
|
|
264
334
|
const source = `
|
|
265
|
-
function Card(props) {
|
|
335
|
+
function Card(props) @{
|
|
266
336
|
<div>{props.children}</div>
|
|
267
|
-
|
|
337
|
+
}
|
|
268
338
|
|
|
269
|
-
export function App() {
|
|
339
|
+
export function App() @{
|
|
270
340
|
const fallback = 'fallback';
|
|
271
341
|
|
|
272
342
|
<Card children={fallback}>
|
|
273
343
|
<span>{'content'}</span>
|
|
274
344
|
</Card>
|
|
275
|
-
|
|
345
|
+
}
|
|
276
346
|
`;
|
|
277
347
|
|
|
278
348
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
@@ -284,18 +354,18 @@ export function App() { return <>
|
|
|
284
354
|
|
|
285
355
|
it('routes calls to functions with nested template returns through render_expression', () => {
|
|
286
356
|
const source = `
|
|
287
|
-
function App() { return <>
|
|
288
357
|
function make(flag) {
|
|
289
358
|
if (flag) {
|
|
290
|
-
return <
|
|
359
|
+
return <span>{'nested'}</span>;
|
|
291
360
|
}
|
|
292
361
|
|
|
293
362
|
return null;
|
|
294
363
|
}
|
|
295
364
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
365
|
+
function App() @{
|
|
366
|
+
<div>{make(true)}</div>
|
|
367
|
+
}
|
|
368
|
+
`;
|
|
299
369
|
|
|
300
370
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
301
371
|
|
|
@@ -305,23 +375,23 @@ function App() { return <>
|
|
|
305
375
|
|
|
306
376
|
it('does not treat nested function template returns as outer function returns', () => {
|
|
307
377
|
const source = `
|
|
308
|
-
function App() { return <>
|
|
309
378
|
function make() {
|
|
310
|
-
function nested() {
|
|
311
|
-
|
|
379
|
+
function nested() @{
|
|
380
|
+
<span>{'nested'}</span>
|
|
312
381
|
}
|
|
313
382
|
|
|
314
383
|
return nested;
|
|
315
384
|
}
|
|
316
385
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
386
|
+
function App() @{
|
|
387
|
+
<div>{make()}</div>
|
|
388
|
+
}
|
|
389
|
+
`;
|
|
320
390
|
|
|
321
391
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
322
392
|
|
|
323
|
-
expect(result).toContain('_$_.
|
|
324
|
-
expect(result).not.toContain('_$_.
|
|
393
|
+
expect(result).toContain('_$_.render_expression(make())');
|
|
394
|
+
expect(result).not.toContain('_$_.render_tsrx_element(make())');
|
|
325
395
|
});
|
|
326
396
|
});
|
|
327
397
|
|
|
@@ -374,10 +444,10 @@ module server {
|
|
|
374
444
|
|
|
375
445
|
import { loadUser as getUser } from server;
|
|
376
446
|
|
|
377
|
-
export function App() {
|
|
447
|
+
export function App() @{
|
|
378
448
|
const user = getUser('1');
|
|
379
449
|
<div>{user.id}</div>
|
|
380
|
-
|
|
450
|
+
}`;
|
|
381
451
|
|
|
382
452
|
const result = compile(source, 'test.tsrx', { mode: 'server' });
|
|
383
453
|
expect(result.code).toContain('const getUser = function (...args)');
|
|
@@ -442,15 +512,15 @@ module server {
|
|
|
442
512
|
|
|
443
513
|
it('wraps children in normalize_children for explicit children prop passed to component', () => {
|
|
444
514
|
const source = `
|
|
445
|
-
function Card(props) {
|
|
515
|
+
function Card(props) @{
|
|
446
516
|
<div>{props.children}</div>
|
|
447
|
-
|
|
517
|
+
}
|
|
448
518
|
|
|
449
|
-
export function App() {
|
|
519
|
+
export function App() @{
|
|
450
520
|
const content = 'hello';
|
|
451
521
|
|
|
452
522
|
<Card children={content} />
|
|
453
|
-
|
|
523
|
+
}
|
|
454
524
|
`;
|
|
455
525
|
|
|
456
526
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
@@ -460,15 +530,15 @@ export function App() { return <>
|
|
|
460
530
|
|
|
461
531
|
it('passes spread through to component when spread may contain children', () => {
|
|
462
532
|
const source = `
|
|
463
|
-
function Card(props) {
|
|
533
|
+
function Card(props) @{
|
|
464
534
|
<div>{props.children}</div>
|
|
465
|
-
|
|
535
|
+
}
|
|
466
536
|
|
|
467
|
-
export function App() {
|
|
537
|
+
export function App() @{
|
|
468
538
|
const props = { children: 'hello' };
|
|
469
539
|
|
|
470
540
|
<Card {...props} />
|
|
471
|
-
|
|
541
|
+
}
|
|
472
542
|
`;
|
|
473
543
|
|
|
474
544
|
const result = compile(source, 'test.tsrx', { mode: 'server' }).code;
|
|
@@ -3,16 +3,16 @@ import type { Tracked, Props } from 'ripple';
|
|
|
3
3
|
|
|
4
4
|
describe('composite > props', () => {
|
|
5
5
|
it('correctly handles default prop values', async () => {
|
|
6
|
-
function Child({ foo = 456 }) {
|
|
7
|
-
|
|
6
|
+
function Child({ foo = 456 }) @{
|
|
7
|
+
<div>{foo}</div>
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
function App() {
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
function App() @{
|
|
11
|
+
let &[foo] = track(123);
|
|
12
|
+
<>
|
|
13
13
|
<Child />
|
|
14
14
|
<Child {foo} />
|
|
15
|
-
|
|
15
|
+
</>
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const { body } = await render(App);
|
|
@@ -23,16 +23,16 @@ describe('composite > props', () => {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('correctly handles default prop values #2', async () => {
|
|
26
|
-
function Child({ foo = 456 }) {
|
|
27
|
-
|
|
26
|
+
function Child({ foo = 456 }) @{
|
|
27
|
+
<div>{foo}</div>
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function App() {
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
function App() @{
|
|
31
|
+
let foo = 123;
|
|
32
|
+
<>
|
|
33
33
|
<Child />
|
|
34
34
|
<Child {foo} />
|
|
35
|
-
|
|
35
|
+
</>
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const { body } = await render(App);
|
|
@@ -43,16 +43,18 @@ describe('composite > props', () => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('correctly handles no props', async () => {
|
|
46
|
-
function Child(props: { foo?: Tracked<number> }) {
|
|
47
|
-
|
|
46
|
+
function Child(props: { foo?: Tracked<number> }) @{
|
|
47
|
+
<div>
|
|
48
|
+
{props.foo?.value}
|
|
49
|
+
</div>
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
function App() {
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
function App() @{
|
|
53
|
+
let foo = track(123);
|
|
54
|
+
<>
|
|
53
55
|
<Child />
|
|
54
56
|
<Child {foo} />
|
|
55
|
-
|
|
57
|
+
</>
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
const { body } = await render(App);
|
|
@@ -63,16 +65,16 @@ describe('composite > props', () => {
|
|
|
63
65
|
});
|
|
64
66
|
|
|
65
67
|
it('correctly handles no props #2', async () => {
|
|
66
|
-
function Child({ foo }: { foo?: number }) {
|
|
67
|
-
|
|
68
|
+
function Child({ foo }: { foo?: number }) @{
|
|
69
|
+
<div>{foo}</div>
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
function App() {
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
function App() @{
|
|
73
|
+
let &[foo] = track(123);
|
|
74
|
+
<>
|
|
73
75
|
<Child />
|
|
74
76
|
<Child {foo} />
|
|
75
|
-
|
|
77
|
+
</>
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
const { body } = await render(App);
|
|
@@ -83,8 +85,8 @@ describe('composite > props', () => {
|
|
|
83
85
|
});
|
|
84
86
|
|
|
85
87
|
it('correctly retains prop accessors and reactivity when using rest props', async () => {
|
|
86
|
-
function Button(&{ children, ...rest }: Props) {
|
|
87
|
-
|
|
88
|
+
function Button(&{ children, ...rest }: Props) @{
|
|
89
|
+
<>
|
|
88
90
|
<button {...rest}>{children}</button>
|
|
89
91
|
<style>
|
|
90
92
|
.on {
|
|
@@ -94,22 +96,20 @@ describe('composite > props', () => {
|
|
|
94
96
|
color: red;
|
|
95
97
|
}
|
|
96
98
|
</style>
|
|
97
|
-
|
|
99
|
+
</>
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
function Toggle(&{ pressed, ...rest }: { pressed: Tracked<boolean> }) {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
function Toggle(&{ pressed, ...rest }: { pressed: Tracked<boolean> }) @{
|
|
103
|
+
const onClick = () => (pressed.value = !pressed.value);
|
|
104
|
+
<>
|
|
103
105
|
<Button {...rest} class={pressed.value ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
|
|
104
106
|
<Button class={pressed.value ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
|
|
105
|
-
|
|
107
|
+
</>
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
function App() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<Toggle {pressed} />
|
|
112
|
-
</>;
|
|
110
|
+
function App() @{
|
|
111
|
+
const pressed = track(true);
|
|
112
|
+
<Toggle {pressed} />
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const { body } = await render(App);
|
|
@@ -132,30 +132,26 @@ describe('composite > props', () => {
|
|
|
132
132
|
price: number;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function Product({ id, name, organizationName, description, imageUrl, price }: ProductInfo) {
|
|
136
|
-
|
|
137
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</article>
|
|
145
|
-
</>;
|
|
135
|
+
function Product({ id, name, organizationName, description, imageUrl, price }: ProductInfo) @{
|
|
136
|
+
<article class="no-padding">
|
|
137
|
+
<img class="responsive small" src={imageUrl} alt={name} />
|
|
138
|
+
<span>{id}</span>
|
|
139
|
+
<h5>{name}</h5>
|
|
140
|
+
<h3>{organizationName}</h3>
|
|
141
|
+
<p>{description}</p>
|
|
142
|
+
<price class="price">{price}</price>
|
|
143
|
+
</article>
|
|
146
144
|
}
|
|
147
145
|
|
|
148
|
-
function App() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/>
|
|
158
|
-
</>;
|
|
146
|
+
function App() @{
|
|
147
|
+
<Product
|
|
148
|
+
id="1"
|
|
149
|
+
name="Product 1"
|
|
150
|
+
organizationName="Org 1"
|
|
151
|
+
description="Description 1"
|
|
152
|
+
imageUrl="https://picsum.photos/300/200"
|
|
153
|
+
price={15}
|
|
154
|
+
/>
|
|
159
155
|
}
|
|
160
156
|
|
|
161
157
|
const { body } = await render(App);
|