ripple 0.2.210 → 0.2.211
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 +9 -1
- package/src/compiler/types/index.d.ts +0 -1
- package/src/runtime/internal/client/template.js +2 -1
- package/tests/hydration/compiled/client/composite.js +139 -0
- package/tests/hydration/compiled/server/composite.js +176 -0
- package/tests/hydration/components/composite.ripple +37 -0
- package/tests/hydration/composite.test.js +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# ripple
|
|
2
2
|
|
|
3
|
+
## 0.2.211
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#694](https://github.com/Ripple-TS/ripple/pull/694)
|
|
8
|
+
[`fa285f4`](https://github.com/Ripple-TS/ripple/commit/fa285f441ab8d748c3dfea6adb463e3ca6d614b5)
|
|
9
|
+
Thanks [@trueadm](https://github.com/trueadm)! - Add a compiler validation error
|
|
10
|
+
for rendering `children` through text interpolation (for example `{children}` or
|
|
11
|
+
`{props.children}`) and direct users to render children as a component
|
|
12
|
+
(`<@children />`) instead.
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
[[`fa285f4`](https://github.com/Ripple-TS/ripple/commit/fa285f441ab8d748c3dfea6adb463e3ca6d614b5)]:
|
|
15
|
+
- ripple@0.2.211
|
|
16
|
+
|
|
3
17
|
## 0.2.210
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.211",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -93,6 +93,6 @@
|
|
|
93
93
|
"vscode-languageserver-types": "^3.17.5"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
|
-
"ripple": "0.2.
|
|
96
|
+
"ripple": "0.2.211"
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -2496,7 +2496,15 @@ function RipplePlugin(config) {
|
|
|
2496
2496
|
}
|
|
2497
2497
|
|
|
2498
2498
|
if (this.value === '#server') {
|
|
2499
|
-
|
|
2499
|
+
// Peek ahead to see if this is a server block (#server { ... }) vs
|
|
2500
|
+
// a server identifier expression (#server.fn(), #server.fn().then())
|
|
2501
|
+
let peek_pos = this.end;
|
|
2502
|
+
while (peek_pos < this.input.length && /\s/.test(this.input[peek_pos])) peek_pos++;
|
|
2503
|
+
if (peek_pos < this.input.length && this.input.charCodeAt(peek_pos) === 123) {
|
|
2504
|
+
// Next non-whitespace character is '{' — parse as server block
|
|
2505
|
+
return this.parseServerBlock();
|
|
2506
|
+
}
|
|
2507
|
+
// Otherwise fall through to parse as expression statement (e.g., #server.fn().then(...))
|
|
2500
2508
|
}
|
|
2501
2509
|
|
|
2502
2510
|
if (this.value === 'component') {
|
|
@@ -190,7 +190,8 @@ export function append(anchor, dom, skip_advance) {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
// During hydration, if anchor === dom, we're hydrating a child component
|
|
193
|
-
// where the "anchor" IS the content.
|
|
193
|
+
// where the "anchor" IS the content. Preserve the cursor on the
|
|
194
|
+
// template's hydrated end node so sibling traversal in the parent is correct.
|
|
194
195
|
if (anchor === dom) {
|
|
195
196
|
pop(dom);
|
|
196
197
|
return;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as _$_ from 'ripple/internal/client';
|
|
2
|
+
|
|
3
|
+
var root = _$_.template(`<div class="layout"><!></div>`, 0);
|
|
4
|
+
var root_1 = _$_.template(`<div class="single">single</div>`, 0);
|
|
5
|
+
var root_2 = _$_.template(`<h1>title</h1><p>description</p>`, 1);
|
|
6
|
+
var root_3 = _$_.template(`<!>`, 1);
|
|
7
|
+
var root_5 = _$_.template(`<!>`, 1);
|
|
8
|
+
var root_4 = _$_.template(`<!>`, 1);
|
|
9
|
+
var root_7 = _$_.template(`<!><div class="extra">extra</div>`, 1);
|
|
10
|
+
var root_6 = _$_.template(`<!>`, 1);
|
|
11
|
+
var root_9 = _$_.template(`<!>`, 1);
|
|
12
|
+
var root_8 = _$_.template(`<!>`, 1);
|
|
13
|
+
|
|
14
|
+
export function Layout(__anchor, __props, __block) {
|
|
15
|
+
_$_.push_component();
|
|
16
|
+
|
|
17
|
+
var div_1 = root();
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
var node = _$_.child(div_1);
|
|
21
|
+
|
|
22
|
+
_$_.composite(() => __props.children, node, {});
|
|
23
|
+
_$_.pop(div_1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_$_.append(__anchor, div_1);
|
|
27
|
+
_$_.pop_component();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function SingleChild(__anchor, _, __block) {
|
|
31
|
+
_$_.push_component();
|
|
32
|
+
|
|
33
|
+
var div_2 = root_1();
|
|
34
|
+
|
|
35
|
+
_$_.append(__anchor, div_2);
|
|
36
|
+
_$_.pop_component();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function MultiRootChild(__anchor, _, __block) {
|
|
40
|
+
_$_.push_component();
|
|
41
|
+
|
|
42
|
+
var fragment = root_2();
|
|
43
|
+
|
|
44
|
+
_$_.next();
|
|
45
|
+
_$_.append(__anchor, fragment, true);
|
|
46
|
+
_$_.pop_component();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function EmptyLayout(__anchor, _, __block) {
|
|
50
|
+
_$_.push_component();
|
|
51
|
+
|
|
52
|
+
var fragment_1 = root_3();
|
|
53
|
+
var node_1 = _$_.first_child_frag(fragment_1);
|
|
54
|
+
|
|
55
|
+
Layout(node_1, {}, _$_.active_block);
|
|
56
|
+
_$_.append(__anchor, fragment_1);
|
|
57
|
+
_$_.pop_component();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function LayoutWithSingleChild(__anchor, _, __block) {
|
|
61
|
+
_$_.push_component();
|
|
62
|
+
|
|
63
|
+
var fragment_2 = root_4();
|
|
64
|
+
var node_2 = _$_.first_child_frag(fragment_2);
|
|
65
|
+
|
|
66
|
+
Layout(
|
|
67
|
+
node_2,
|
|
68
|
+
{
|
|
69
|
+
children(__anchor, _, __block) {
|
|
70
|
+
_$_.push_component();
|
|
71
|
+
|
|
72
|
+
var fragment_3 = root_5();
|
|
73
|
+
var node_3 = _$_.first_child_frag(fragment_3);
|
|
74
|
+
|
|
75
|
+
SingleChild(node_3, {}, _$_.active_block);
|
|
76
|
+
_$_.append(__anchor, fragment_3);
|
|
77
|
+
_$_.pop_component();
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
_$_.active_block
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
_$_.append(__anchor, fragment_2);
|
|
84
|
+
_$_.pop_component();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function LayoutWithMultipleChildren(__anchor, _, __block) {
|
|
88
|
+
_$_.push_component();
|
|
89
|
+
|
|
90
|
+
var fragment_4 = root_6();
|
|
91
|
+
var node_4 = _$_.first_child_frag(fragment_4);
|
|
92
|
+
|
|
93
|
+
Layout(
|
|
94
|
+
node_4,
|
|
95
|
+
{
|
|
96
|
+
children(__anchor, _, __block) {
|
|
97
|
+
_$_.push_component();
|
|
98
|
+
|
|
99
|
+
var fragment_5 = root_7();
|
|
100
|
+
var node_5 = _$_.first_child_frag(fragment_5);
|
|
101
|
+
|
|
102
|
+
SingleChild(node_5, {}, _$_.active_block);
|
|
103
|
+
_$_.append(__anchor, fragment_5);
|
|
104
|
+
_$_.pop_component();
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
_$_.active_block
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
_$_.append(__anchor, fragment_4);
|
|
111
|
+
_$_.pop_component();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function LayoutWithMultiRootChild(__anchor, _, __block) {
|
|
115
|
+
_$_.push_component();
|
|
116
|
+
|
|
117
|
+
var fragment_6 = root_8();
|
|
118
|
+
var node_6 = _$_.first_child_frag(fragment_6);
|
|
119
|
+
|
|
120
|
+
Layout(
|
|
121
|
+
node_6,
|
|
122
|
+
{
|
|
123
|
+
children(__anchor, _, __block) {
|
|
124
|
+
_$_.push_component();
|
|
125
|
+
|
|
126
|
+
var fragment_7 = root_9();
|
|
127
|
+
var node_7 = _$_.first_child_frag(fragment_7);
|
|
128
|
+
|
|
129
|
+
MultiRootChild(node_7, {}, _$_.active_block);
|
|
130
|
+
_$_.append(__anchor, fragment_7);
|
|
131
|
+
_$_.pop_component();
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
_$_.active_block
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
_$_.append(__anchor, fragment_6);
|
|
138
|
+
_$_.pop_component();
|
|
139
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import * as _$_ from 'ripple/internal/server';
|
|
2
|
+
|
|
3
|
+
export async function Layout(__output, { children }) {
|
|
4
|
+
return _$_.async(async () => {
|
|
5
|
+
_$_.push_component();
|
|
6
|
+
__output.push('<div');
|
|
7
|
+
__output.push(' class="layout"');
|
|
8
|
+
__output.push('>');
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
{
|
|
12
|
+
const comp = children;
|
|
13
|
+
const args = [__output, {}];
|
|
14
|
+
|
|
15
|
+
if (comp?.async) {
|
|
16
|
+
await comp(...args);
|
|
17
|
+
} else if (comp) {
|
|
18
|
+
comp(...args);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
__output.push('</div>');
|
|
24
|
+
_$_.pop_component();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function SingleChild(__output) {
|
|
29
|
+
_$_.push_component();
|
|
30
|
+
__output.push('<div');
|
|
31
|
+
__output.push(' class="single"');
|
|
32
|
+
__output.push('>');
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
__output.push('single');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
__output.push('</div>');
|
|
39
|
+
_$_.pop_component();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function MultiRootChild(__output) {
|
|
43
|
+
_$_.push_component();
|
|
44
|
+
__output.push('<h1');
|
|
45
|
+
__output.push('>');
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
__output.push('title');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
__output.push('</h1>');
|
|
52
|
+
__output.push('<p');
|
|
53
|
+
__output.push('>');
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
__output.push('description');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
__output.push('</p>');
|
|
60
|
+
_$_.pop_component();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function EmptyLayout(__output) {
|
|
64
|
+
_$_.push_component();
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
const comp = Layout;
|
|
68
|
+
const args = [__output, {}];
|
|
69
|
+
|
|
70
|
+
comp(...args);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
_$_.pop_component();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function LayoutWithSingleChild(__output) {
|
|
77
|
+
_$_.push_component();
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
const comp = Layout;
|
|
81
|
+
|
|
82
|
+
const args = [
|
|
83
|
+
__output,
|
|
84
|
+
|
|
85
|
+
{
|
|
86
|
+
children: function children(__output) {
|
|
87
|
+
_$_.push_component();
|
|
88
|
+
|
|
89
|
+
{
|
|
90
|
+
const comp = SingleChild;
|
|
91
|
+
const args = [__output, {}];
|
|
92
|
+
|
|
93
|
+
comp(...args);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_$_.pop_component();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
comp(...args);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_$_.pop_component();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function LayoutWithMultipleChildren(__output) {
|
|
108
|
+
_$_.push_component();
|
|
109
|
+
|
|
110
|
+
{
|
|
111
|
+
const comp = Layout;
|
|
112
|
+
|
|
113
|
+
const args = [
|
|
114
|
+
__output,
|
|
115
|
+
|
|
116
|
+
{
|
|
117
|
+
children: function children(__output) {
|
|
118
|
+
_$_.push_component();
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
const comp = SingleChild;
|
|
122
|
+
const args = [__output, {}];
|
|
123
|
+
|
|
124
|
+
comp(...args);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
__output.push('<div');
|
|
128
|
+
__output.push(' class="extra"');
|
|
129
|
+
__output.push('>');
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
__output.push('extra');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
__output.push('</div>');
|
|
136
|
+
_$_.pop_component();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
comp(...args);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_$_.pop_component();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function LayoutWithMultiRootChild(__output) {
|
|
148
|
+
_$_.push_component();
|
|
149
|
+
|
|
150
|
+
{
|
|
151
|
+
const comp = Layout;
|
|
152
|
+
|
|
153
|
+
const args = [
|
|
154
|
+
__output,
|
|
155
|
+
|
|
156
|
+
{
|
|
157
|
+
children: function children(__output) {
|
|
158
|
+
_$_.push_component();
|
|
159
|
+
|
|
160
|
+
{
|
|
161
|
+
const comp = MultiRootChild;
|
|
162
|
+
const args = [__output, {}];
|
|
163
|
+
|
|
164
|
+
comp(...args);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
_$_.pop_component();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
comp(...args);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
_$_.pop_component();
|
|
176
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export component Layout({ children }) {
|
|
2
|
+
<div class="layout">
|
|
3
|
+
<children />
|
|
4
|
+
</div>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export component SingleChild() {
|
|
8
|
+
<div class="single">{'single'}</div>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export component MultiRootChild() {
|
|
12
|
+
<h1>{'title'}</h1>
|
|
13
|
+
<p>{'description'}</p>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export component EmptyLayout() {
|
|
17
|
+
<Layout />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export component LayoutWithSingleChild() {
|
|
21
|
+
<Layout>
|
|
22
|
+
<SingleChild />
|
|
23
|
+
</Layout>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export component LayoutWithMultipleChildren() {
|
|
27
|
+
<Layout>
|
|
28
|
+
<SingleChild />
|
|
29
|
+
<div class="extra">{'extra'}</div>
|
|
30
|
+
</Layout>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export component LayoutWithMultiRootChild() {
|
|
34
|
+
<Layout>
|
|
35
|
+
<MultiRootChild />
|
|
36
|
+
</Layout>
|
|
37
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { hydrateComponent, container } from '../setup-hydration.js';
|
|
3
|
+
|
|
4
|
+
import * as ServerComponents from './compiled/server/composite.js';
|
|
5
|
+
import * as ClientComponents from './compiled/client/composite.js';
|
|
6
|
+
|
|
7
|
+
describe('hydration > composite', () => {
|
|
8
|
+
it('hydrates a layout with no children', async () => {
|
|
9
|
+
await hydrateComponent(ServerComponents.EmptyLayout, ClientComponents.EmptyLayout);
|
|
10
|
+
expect(container.innerHTML).toBeHtml('<div class=\"layout\"></div>');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('hydrates a layout with a single child component', async () => {
|
|
14
|
+
await hydrateComponent(
|
|
15
|
+
ServerComponents.LayoutWithSingleChild,
|
|
16
|
+
ClientComponents.LayoutWithSingleChild,
|
|
17
|
+
);
|
|
18
|
+
expect(container.innerHTML).toBeHtml(
|
|
19
|
+
'<div class=\"layout\"><div class=\"single\">single</div></div>',
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('hydrates a layout with multiple children', async () => {
|
|
24
|
+
await hydrateComponent(
|
|
25
|
+
ServerComponents.LayoutWithMultipleChildren,
|
|
26
|
+
ClientComponents.LayoutWithMultipleChildren,
|
|
27
|
+
);
|
|
28
|
+
expect(container.innerHTML).toBeHtml(
|
|
29
|
+
'<div class=\"layout\"><div class=\"single\">single</div><div class=\"extra\">extra</div></div>',
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('hydrates a layout with a child that has multiple roots', async () => {
|
|
34
|
+
await hydrateComponent(
|
|
35
|
+
ServerComponents.LayoutWithMultiRootChild,
|
|
36
|
+
ClientComponents.LayoutWithMultiRootChild,
|
|
37
|
+
);
|
|
38
|
+
expect(container.innerHTML).toBeHtml(
|
|
39
|
+
'<div class=\"layout\"><h1>title</h1><p>description</p></div>',
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|