ripple 0.2.78 → 0.2.80
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/package.json +1 -1
- package/src/compiler/phases/3-transform/client/index.js +20 -5
- package/src/runtime/internal/client/composite.js +22 -0
- package/src/runtime/internal/client/constants.js +3 -3
- package/src/runtime/internal/client/index.js +2 -0
- package/src/runtime/internal/server/index.js +4 -0
- package/tests/client/__snapshots__/basic.test.ripple.snap +8 -26
- package/tests/client/basic.test.ripple +1 -1
- package/tests/client/composite.test.ripple +37 -1
- package/tests/server/basic.test.ripple +15 -0
- package/types/server.d.ts +4 -0
package/package.json
CHANGED
|
@@ -802,20 +802,35 @@ const visitors = {
|
|
|
802
802
|
}
|
|
803
803
|
}
|
|
804
804
|
|
|
805
|
-
|
|
805
|
+
const metadata = { tracking: false, await: false };
|
|
806
|
+
// We visit, but only to gather metadata
|
|
807
|
+
b.call(visit(node.id, { ...state, metadata }));
|
|
808
|
+
|
|
809
|
+
if (metadata.tracking) {
|
|
806
810
|
state.init.push(
|
|
807
811
|
b.stmt(
|
|
808
812
|
b.call(
|
|
809
|
-
|
|
813
|
+
'_$_.composite',
|
|
814
|
+
b.thunk(visit(node.id, state)),
|
|
810
815
|
id,
|
|
811
|
-
|
|
812
|
-
|
|
816
|
+
is_spreading
|
|
817
|
+
? b.call('_$_.spread_props', b.thunk(b.object(props)), b.id('__block'))
|
|
818
|
+
: b.object(props),
|
|
813
819
|
),
|
|
814
820
|
),
|
|
815
821
|
);
|
|
816
822
|
} else {
|
|
817
823
|
state.init.push(
|
|
818
|
-
b.stmt(
|
|
824
|
+
b.stmt(
|
|
825
|
+
b.call(
|
|
826
|
+
visit(node.id, state),
|
|
827
|
+
id,
|
|
828
|
+
is_spreading
|
|
829
|
+
? b.call('_$_.spread_props', b.thunk(b.object(props)), b.id('__block'))
|
|
830
|
+
: b.object(props),
|
|
831
|
+
b.id('_$_.active_block'),
|
|
832
|
+
),
|
|
833
|
+
),
|
|
819
834
|
);
|
|
820
835
|
}
|
|
821
836
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { branch, destroy_block, render } from './blocks.js';
|
|
2
|
+
import { COMPOSITE_BLOCK } from './constants.js';
|
|
3
|
+
import { active_block } from './runtime.js';
|
|
4
|
+
|
|
5
|
+
export function composite(get_component, node, props) {
|
|
6
|
+
var anchor = node;
|
|
7
|
+
var b = null;
|
|
8
|
+
|
|
9
|
+
render(() => {
|
|
10
|
+
var component = get_component();
|
|
11
|
+
|
|
12
|
+
if (b !== null) {
|
|
13
|
+
destroy_block(b);
|
|
14
|
+
b = null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
b = branch(() => {
|
|
18
|
+
var block = active_block;
|
|
19
|
+
component(anchor, props, block);
|
|
20
|
+
});
|
|
21
|
+
}, COMPOSITE_BLOCK);
|
|
22
|
+
}
|
|
@@ -5,8 +5,8 @@ export var BRANCH_BLOCK = 1 << 4;
|
|
|
5
5
|
export var FOR_BLOCK = 1 << 5;
|
|
6
6
|
export var TRY_BLOCK = 1 << 6;
|
|
7
7
|
export var IF_BLOCK = 1 << 7;
|
|
8
|
-
export var
|
|
9
|
-
export var
|
|
8
|
+
export var COMPOSITE_BLOCK = 1 << 8;
|
|
9
|
+
export var ASYNC_BLOCK = 1 << 9;
|
|
10
10
|
export var CONTAINS_UPDATE = 1 << 10;
|
|
11
11
|
export var CONTAINS_TEARDOWN = 1 << 11;
|
|
12
12
|
export var BLOCK_HAS_RUN = 1 << 12;
|
|
@@ -16,7 +16,7 @@ export var DEFERRED = 1 << 15;
|
|
|
16
16
|
export var PAUSED = 1 << 16;
|
|
17
17
|
export var DESTROYED = 1 << 17;
|
|
18
18
|
|
|
19
|
-
export var
|
|
19
|
+
export var CONTROL_FLOW_BLOCK = FOR_BLOCK | IF_BLOCK | TRY_BLOCK | COMPOSITE_BLOCK;
|
|
20
20
|
|
|
21
21
|
export var UNINITIALIZED = Symbol();
|
|
22
22
|
/** @type {unique symbol} */
|
|
@@ -114,6 +114,10 @@ export function spread_attrs(attrs, css_hash) {
|
|
|
114
114
|
|
|
115
115
|
if (typeof value === 'function') continue;
|
|
116
116
|
|
|
117
|
+
if (is_tracked_object(value)) {
|
|
118
|
+
value = get(value);
|
|
119
|
+
}
|
|
120
|
+
|
|
117
121
|
if (name === 'class' && css_hash) {
|
|
118
122
|
value = (value == null ? '' : value) + ' ' + css_hash;
|
|
119
123
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`basic > basic operations 1`] = `
|
|
3
|
+
exports[`basic client > basic operations 1`] = `
|
|
4
4
|
<div>
|
|
5
5
|
<div>
|
|
6
6
|
0
|
|
@@ -18,25 +18,7 @@ exports[`basic > basic operations 1`] = `
|
|
|
18
18
|
</div>
|
|
19
19
|
`;
|
|
20
20
|
|
|
21
|
-
exports[`basic >
|
|
22
|
-
<div>
|
|
23
|
-
<div>
|
|
24
|
-
11
|
|
25
|
-
</div>
|
|
26
|
-
<div>
|
|
27
|
-
11
|
|
28
|
-
</div>
|
|
29
|
-
<div>
|
|
30
|
-
truetrue
|
|
31
|
-
</div>
|
|
32
|
-
<div>
|
|
33
|
-
truetrue
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
</div>
|
|
37
|
-
`;
|
|
38
|
-
|
|
39
|
-
exports[`basic > handles boolean attributes with no prop value provides 1`] = `
|
|
21
|
+
exports[`basic client > handles boolean attributes with no prop value provides 1`] = `
|
|
40
22
|
<div>
|
|
41
23
|
<div
|
|
42
24
|
class="container"
|
|
@@ -55,7 +37,7 @@ exports[`basic > handles boolean attributes with no prop value provides 1`] = `
|
|
|
55
37
|
</div>
|
|
56
38
|
`;
|
|
57
39
|
|
|
58
|
-
exports[`basic > render semi-dynamic text 1`] = `
|
|
40
|
+
exports[`basic client > render semi-dynamic text 1`] = `
|
|
59
41
|
<div>
|
|
60
42
|
<div>
|
|
61
43
|
Hello World
|
|
@@ -64,7 +46,7 @@ exports[`basic > render semi-dynamic text 1`] = `
|
|
|
64
46
|
</div>
|
|
65
47
|
`;
|
|
66
48
|
|
|
67
|
-
exports[`basic > render spread props without duplication 1`] = `
|
|
49
|
+
exports[`basic client > render spread props without duplication 1`] = `
|
|
68
50
|
<div>
|
|
69
51
|
<div>
|
|
70
52
|
<input
|
|
@@ -78,7 +60,7 @@ exports[`basic > render spread props without duplication 1`] = `
|
|
|
78
60
|
</div>
|
|
79
61
|
`;
|
|
80
62
|
|
|
81
|
-
exports[`basic > render static attributes 1`] = `
|
|
63
|
+
exports[`basic client > render static attributes 1`] = `
|
|
82
64
|
<div>
|
|
83
65
|
<div
|
|
84
66
|
class="foo"
|
|
@@ -91,7 +73,7 @@ exports[`basic > render static attributes 1`] = `
|
|
|
91
73
|
</div>
|
|
92
74
|
`;
|
|
93
75
|
|
|
94
|
-
exports[`basic > render static text 1`] = `
|
|
76
|
+
exports[`basic client > render static text 1`] = `
|
|
95
77
|
<div>
|
|
96
78
|
<div>
|
|
97
79
|
Hello World
|
|
@@ -100,7 +82,7 @@ exports[`basic > render static text 1`] = `
|
|
|
100
82
|
</div>
|
|
101
83
|
`;
|
|
102
84
|
|
|
103
|
-
exports[`basic > renders simple JS expression logic correctly 1`] = `
|
|
85
|
+
exports[`basic client > renders simple JS expression logic correctly 1`] = `
|
|
104
86
|
<div>
|
|
105
87
|
<div>
|
|
106
88
|
{"0":"Test"}
|
|
@@ -112,7 +94,7 @@ exports[`basic > renders simple JS expression logic correctly 1`] = `
|
|
|
112
94
|
</div>
|
|
113
95
|
`;
|
|
114
96
|
|
|
115
|
-
exports[`basic > should handle lexical scopes correctly 1`] = `
|
|
97
|
+
exports[`basic client > should handle lexical scopes correctly 1`] = `
|
|
116
98
|
<div>
|
|
117
99
|
<section>
|
|
118
100
|
Nested scope variable
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
2
2
|
import { mount, flushSync, effect, track } from 'ripple';
|
|
3
3
|
import { compile } from 'ripple/compiler';
|
|
4
4
|
|
|
5
|
-
describe('basic', () => {
|
|
5
|
+
describe('basic client', () => {
|
|
6
6
|
let container;
|
|
7
7
|
|
|
8
8
|
function render(component) {
|
|
@@ -663,5 +663,41 @@ describe('composite components', () => {
|
|
|
663
663
|
|
|
664
664
|
render(App);
|
|
665
665
|
expect(container).toMatchSnapshot();
|
|
666
|
-
})
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
it('handles dynamic component switching', () => {
|
|
669
|
+
component Child1() {
|
|
670
|
+
<div>{"I am child 1"}</div>
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
component Child2() {
|
|
674
|
+
<div>{"I am child 2"}</div>
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
component App() {
|
|
678
|
+
let thing = track(() => Child1)
|
|
679
|
+
|
|
680
|
+
<div id="container">
|
|
681
|
+
<@thing />
|
|
682
|
+
</div>
|
|
683
|
+
|
|
684
|
+
<button onClick={() => @thing = @thing === Child1 ? Child2 : Child1}>{"Change Child"}</button>
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
render(App);
|
|
688
|
+
flushSync();
|
|
689
|
+
|
|
690
|
+
expect(container.querySelector('#container').textContent).toBe('I am child 1');
|
|
691
|
+
|
|
692
|
+
const button = container.querySelector('button');
|
|
693
|
+
button.click();
|
|
694
|
+
flushSync();
|
|
695
|
+
|
|
696
|
+
expect(container.querySelector('#container').textContent).toBe('I am child 2');
|
|
697
|
+
|
|
698
|
+
button.click();
|
|
699
|
+
flushSync();
|
|
700
|
+
|
|
701
|
+
expect(container.querySelector('#container').textContent).toBe('I am child 1');
|
|
702
|
+
});
|
|
667
703
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { render } from 'ripple/server';
|
|
3
|
+
|
|
4
|
+
describe('basic client', () => {
|
|
5
|
+
it('render static text', async () => {
|
|
6
|
+
component Basic() {
|
|
7
|
+
<div>{'Hello World'}</div>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { head, body } = await render(Basic);
|
|
11
|
+
|
|
12
|
+
expect(head).toBe('');
|
|
13
|
+
expect(body).toBe('<div>Hello World</div>');
|
|
14
|
+
});
|
|
15
|
+
});
|
package/types/server.d.ts
CHANGED