ripple 0.3.67 → 0.3.69
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 +57 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -2
- package/src/runtime/element.js +1 -1
- package/src/runtime/index-client.js +11 -11
- package/src/runtime/index-server.js +7 -4
- package/src/runtime/internal/client/bindings.js +1 -1
- package/src/runtime/internal/client/blocks.js +13 -4
- package/src/runtime/internal/client/component.js +55 -0
- package/src/runtime/internal/client/composite.js +4 -2
- package/src/runtime/internal/client/expression.js +65 -7
- package/src/runtime/internal/client/hmr.js +54 -43
- package/src/runtime/internal/client/index.js +5 -1
- package/src/runtime/internal/client/portal.js +70 -69
- package/src/runtime/internal/client/render.js +3 -0
- package/src/runtime/internal/server/index.js +92 -8
- package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
- package/tests/client/array/array.copy-within.test.tsrx +33 -31
- package/tests/client/array/array.derived.test.tsrx +186 -169
- package/tests/client/array/array.iteration.test.tsrx +40 -37
- package/tests/client/array/array.mutations.test.tsrx +113 -101
- package/tests/client/array/array.static.test.tsrx +119 -101
- package/tests/client/array/array.to-methods.test.tsrx +24 -21
- package/tests/client/async-suspend.test.tsrx +247 -246
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
- package/tests/client/basic/basic.attributes.test.tsrx +428 -423
- package/tests/client/basic/basic.collections.test.tsrx +109 -102
- package/tests/client/basic/basic.components.test.tsrx +323 -205
- package/tests/client/basic/basic.errors.test.tsrx +91 -91
- package/tests/client/basic/basic.events.test.tsrx +114 -115
- package/tests/client/basic/basic.get-set.test.tsrx +97 -87
- package/tests/client/basic/basic.hmr.test.tsrx +19 -16
- package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
- package/tests/client/basic/basic.rendering.test.tsrx +272 -182
- package/tests/client/basic/basic.styling.test.tsrx +23 -22
- package/tests/client/basic/basic.utilities.test.tsrx +10 -8
- package/tests/client/boundaries.test.tsrx +26 -26
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
- package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
- package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
- package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
- package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
- package/tests/client/composite/composite.generics.test.tsrx +168 -192
- package/tests/client/composite/composite.props.test.tsrx +97 -81
- package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
- package/tests/client/composite/composite.render.test.tsrx +122 -105
- package/tests/client/computed-properties.test.tsrx +28 -28
- package/tests/client/context.test.tsrx +21 -21
- package/tests/client/css/global-additional-cases.test.tsrx +58 -58
- package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
- package/tests/client/css/global-at-rules.test.tsrx +10 -10
- package/tests/client/css/global-basic.test.tsrx +14 -14
- package/tests/client/css/global-classes-ids.test.tsrx +14 -14
- package/tests/client/css/global-combinators.test.tsrx +10 -10
- package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
- package/tests/client/css/global-edge-cases.test.tsrx +18 -18
- package/tests/client/css/global-keyframes.test.tsrx +12 -12
- package/tests/client/css/global-nested.test.tsrx +10 -10
- package/tests/client/css/global-pseudo.test.tsrx +12 -12
- package/tests/client/css/global-scoping.test.tsrx +20 -20
- package/tests/client/css/style-identifier.test.tsrx +143 -291
- package/tests/client/date.test.tsrx +146 -133
- package/tests/client/dynamic-elements.test.tsrx +398 -365
- package/tests/client/events.test.tsrx +292 -290
- package/tests/client/for.test.tsrx +156 -153
- package/tests/client/head.test.tsrx +105 -96
- package/tests/client/html.test.tsrx +122 -26
- package/tests/client/input-value.test.tsrx +1361 -1314
- package/tests/client/lazy-array.test.tsrx +16 -13
- package/tests/client/lazy-destructuring.test.tsrx +257 -213
- package/tests/client/map.test.tsrx +65 -60
- package/tests/client/media-query.test.tsrx +22 -20
- package/tests/client/object.test.tsrx +87 -81
- package/tests/client/portal.test.tsrx +57 -51
- package/tests/client/ref.test.tsrx +233 -202
- package/tests/client/return.test.tsrx +71 -2560
- package/tests/client/set.test.tsrx +54 -45
- package/tests/client/svg.test.tsrx +216 -186
- package/tests/client/switch.test.tsrx +194 -193
- package/tests/client/track-async-hydration.test.tsrx +18 -14
- package/tests/client/tracked-index-access.test.tsrx +28 -18
- package/tests/client/try.test.tsrx +675 -548
- package/tests/client/tsx.test.tsrx +373 -311
- package/tests/client/typescript-generics.test.tsrx +145 -145
- package/tests/client/url/url.derived.test.tsrx +33 -28
- package/tests/client/url/url.parsing.test.tsrx +61 -51
- package/tests/client/url/url.partial-removal.test.tsrx +56 -48
- package/tests/client/url/url.reactivity.test.tsrx +142 -125
- package/tests/client/url/url.serialization.test.tsrx +13 -11
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
- package/tests/hydration/basic.test.js +3 -3
- package/tests/hydration/compiled/client/basic.js +586 -651
- package/tests/hydration/compiled/client/composite.js +79 -104
- package/tests/hydration/compiled/client/events.js +140 -148
- package/tests/hydration/compiled/client/for.js +1005 -1018
- package/tests/hydration/compiled/client/head.js +124 -134
- package/tests/hydration/compiled/client/hmr.js +41 -48
- package/tests/hydration/compiled/client/html-in-template.js +38 -41
- package/tests/hydration/compiled/client/html.js +970 -1314
- package/tests/hydration/compiled/client/if-children.js +234 -249
- package/tests/hydration/compiled/client/if.js +182 -189
- package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
- package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
- package/tests/hydration/compiled/client/portal.js +65 -85
- package/tests/hydration/compiled/client/reactivity.js +84 -90
- package/tests/hydration/compiled/client/return.js +38 -1939
- package/tests/hydration/compiled/client/switch.js +218 -224
- package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
- package/tests/hydration/compiled/client/try.js +123 -132
- package/tests/hydration/compiled/server/basic.js +773 -831
- package/tests/hydration/compiled/server/composite.js +166 -191
- package/tests/hydration/compiled/server/events.js +170 -184
- package/tests/hydration/compiled/server/for.js +851 -909
- package/tests/hydration/compiled/server/head.js +206 -216
- package/tests/hydration/compiled/server/hmr.js +64 -72
- package/tests/hydration/compiled/server/html-in-template.js +42 -76
- package/tests/hydration/compiled/server/html.js +1362 -1667
- package/tests/hydration/compiled/server/if-children.js +419 -445
- package/tests/hydration/compiled/server/if.js +194 -208
- package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
- package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
- package/tests/hydration/compiled/server/portal.js +152 -160
- package/tests/hydration/compiled/server/reactivity.js +94 -106
- package/tests/hydration/compiled/server/return.js +28 -2172
- package/tests/hydration/compiled/server/switch.js +274 -286
- package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
- package/tests/hydration/compiled/server/try.js +167 -185
- package/tests/hydration/components/basic.tsrx +320 -272
- package/tests/hydration/components/composite.tsrx +44 -32
- package/tests/hydration/components/events.tsrx +101 -91
- package/tests/hydration/components/for.tsrx +510 -452
- package/tests/hydration/components/head.tsrx +87 -80
- package/tests/hydration/components/hmr.tsrx +22 -17
- package/tests/hydration/components/html-in-template.tsrx +22 -17
- package/tests/hydration/components/html.tsrx +525 -443
- package/tests/hydration/components/if-children.tsrx +158 -148
- package/tests/hydration/components/if.tsrx +109 -95
- package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
- package/tests/hydration/components/nested-control-flow.tsrx +215 -203
- package/tests/hydration/components/portal.tsrx +41 -34
- package/tests/hydration/components/reactivity.tsrx +37 -27
- package/tests/hydration/components/return.tsrx +12 -556
- package/tests/hydration/components/switch.tsrx +120 -114
- package/tests/hydration/components/track-async-serialization.tsrx +107 -91
- package/tests/hydration/components/try.tsrx +55 -40
- package/tests/hydration/html.test.js +4 -4
- package/tests/hydration/return.test.js +13 -532
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +264 -195
- package/tests/server/basic.components.test.tsrx +296 -169
- package/tests/server/basic.test.tsrx +300 -198
- package/tests/server/compiler.test.tsrx +62 -60
- package/tests/server/composite.props.test.tsrx +77 -63
- package/tests/server/composite.test.tsrx +168 -192
- package/tests/server/context.test.tsrx +18 -12
- package/tests/server/dynamic-elements.test.tsrx +197 -180
- package/tests/server/for.test.tsrx +85 -78
- package/tests/server/head.test.tsrx +50 -43
- package/tests/server/html-nesting-validation.test.tsrx +8 -8
- package/tests/server/if.test.tsrx +57 -51
- package/tests/server/lazy-destructuring.test.tsrx +366 -294
- package/tests/server/return.test.tsrx +76 -1355
- package/tests/server/streaming-ssr.test.tsrx +4 -75
- package/tests/server/style-identifier.test.tsrx +169 -148
- package/tests/server/switch.test.tsrx +91 -85
- package/tests/server/track-async-serialization.test.tsrx +105 -85
- package/tests/server/try.test.tsrx +374 -280
- package/tests/utils/compiler-compat-config.test.js +2 -2
- package/tests/utils/runtime-imports.test.js +10 -0
- package/types/index.d.ts +8 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
|
@@ -2,18 +2,18 @@ import { RippleMap, flushSync, track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
describe('RippleMap', () => {
|
|
4
4
|
it('handles set with update and delete operations with a reactive size var', () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
function MapTest() {
|
|
6
|
+
return <>
|
|
7
|
+
let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
|
|
8
|
+
let &[value] = track(() => map.get('a'));
|
|
9
|
+
let &[size] = track(() => map.size);
|
|
10
|
+
<button onClick={() => map.set('d', 4)}>{'set'}</button>
|
|
11
|
+
<button onClick={() => map.delete('b')}>{'delete'}</button>
|
|
12
|
+
<button onClick={() => map.set('a', 5)}>{'update'}</button>
|
|
13
|
+
<pre>{map.get('d')}</pre>
|
|
14
|
+
<pre>{size}</pre>
|
|
15
|
+
<pre>{value}</pre>
|
|
16
|
+
</>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
render(MapTest);
|
|
@@ -41,11 +41,12 @@ describe('RippleMap', () => {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
it('handles clear operation', () => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
function MapTest() {
|
|
45
|
+
return <>
|
|
46
|
+
let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
|
|
47
|
+
<button onClick={() => map.clear()}>{'clear'}</button>
|
|
48
|
+
<pre>{map.size}</pre>
|
|
49
|
+
</>;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
render(MapTest);
|
|
@@ -59,12 +60,13 @@ describe('RippleMap', () => {
|
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
it('handles has operation and tracks reactive $has', () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
function MapTest() {
|
|
64
|
+
return <>
|
|
65
|
+
let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
|
|
66
|
+
let &[has] = track(() => map.has('b'));
|
|
67
|
+
<button onClick={() => map.delete('b')}>{'delete'}</button>
|
|
68
|
+
<pre>{has}</pre>
|
|
69
|
+
</>;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
render(MapTest);
|
|
@@ -79,17 +81,17 @@ describe('RippleMap', () => {
|
|
|
79
81
|
});
|
|
80
82
|
|
|
81
83
|
it('handles reactivity of keys, values, and entries', () => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
function MapTest() {
|
|
85
|
+
return <>
|
|
86
|
+
let map = RippleMap([['x', 10], ['y', 20]]);
|
|
87
|
+
let &[keys] = track(() => Array.from(map.keys()));
|
|
88
|
+
let &[values] = track(() => Array.from(map.values()));
|
|
89
|
+
let &[entries] = track(() => Array.from(map.entries()));
|
|
90
|
+
<button onClick={() => map.delete('x')}>{'delete'}</button>
|
|
91
|
+
<pre>{JSON.stringify(keys)}</pre>
|
|
92
|
+
<pre>{JSON.stringify(values)}</pre>
|
|
93
|
+
<pre>{JSON.stringify(entries)}</pre>
|
|
94
|
+
</>;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
render(MapTest);
|
|
@@ -109,10 +111,11 @@ describe('RippleMap', () => {
|
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
it('toJSON returns correct object', () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
function MapTest() {
|
|
115
|
+
return <>
|
|
116
|
+
let map = RippleMap([['foo', 1], ['bar', 2]]);
|
|
117
|
+
<pre>{JSON.stringify(map)}</pre>
|
|
118
|
+
</>;
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
render(MapTest);
|
|
@@ -121,11 +124,12 @@ describe('RippleMap', () => {
|
|
|
121
124
|
});
|
|
122
125
|
|
|
123
126
|
it('creates empty RippleMap using RippleMap() shorthand syntax', () => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
function MapTest() {
|
|
128
|
+
return <>
|
|
129
|
+
let map = RippleMap();
|
|
130
|
+
<button onClick={() => map.set('a', 1)}>{'add'}</button>
|
|
131
|
+
<pre>{map.size}</pre>
|
|
132
|
+
</>;
|
|
129
133
|
}
|
|
130
134
|
|
|
131
135
|
render(MapTest);
|
|
@@ -140,13 +144,14 @@ describe('RippleMap', () => {
|
|
|
140
144
|
});
|
|
141
145
|
|
|
142
146
|
it('creates RippleMap with initial entries using RippleMap() shorthand syntax', () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
function MapTest() {
|
|
148
|
+
return <>
|
|
149
|
+
let map = RippleMap([['a', 1], ['b', 2], ['c', 3]]);
|
|
150
|
+
let &[value] = track(() => map.get('b'));
|
|
151
|
+
<button onClick={() => map.set('b', 10)}>{'update'}</button>
|
|
152
|
+
<pre>{map.size}</pre>
|
|
153
|
+
<pre>{value}</pre>
|
|
154
|
+
</>;
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
render(MapTest);
|
|
@@ -162,16 +167,16 @@ describe('RippleMap', () => {
|
|
|
162
167
|
});
|
|
163
168
|
|
|
164
169
|
it('handles all operations with RippleMap() shorthand syntax', () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
function MapTest() {
|
|
171
|
+
return <>
|
|
172
|
+
let map = RippleMap([['x', 100], ['y', 200]]);
|
|
173
|
+
let &[keys] = track(() => Array.from(map.keys()));
|
|
174
|
+
<button onClick={() => map.set('z', 300)}>{'add'}</button>
|
|
175
|
+
<button onClick={() => map.delete('x')}>{'delete'}</button>
|
|
176
|
+
<button onClick={() => map.clear()}>{'clear'}</button>
|
|
177
|
+
<pre>{JSON.stringify(keys)}</pre>
|
|
178
|
+
<pre>{map.size}</pre>
|
|
179
|
+
</>;
|
|
175
180
|
}
|
|
176
181
|
|
|
177
182
|
render(MapTest);
|
|
@@ -50,12 +50,13 @@ describe('MediaQuery', () => {
|
|
|
50
50
|
it('should be reactive if matchMedia changes', () => {
|
|
51
51
|
const media = '(min-width: 600px)';
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
function App() {
|
|
54
|
+
return <>
|
|
55
|
+
let &[medium] = MediaQuery(media);
|
|
56
|
+
<div>
|
|
57
|
+
<p>{medium}</p>
|
|
58
|
+
</div>
|
|
59
|
+
</>;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
render(App);
|
|
@@ -85,22 +86,23 @@ describe('MediaQuery', () => {
|
|
|
85
86
|
it('should have cleared event listeners after unmount', async () => {
|
|
86
87
|
const media = '(min-width: 600px)';
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
function App() {
|
|
90
|
+
return <>
|
|
91
|
+
let &[show] = track(true);
|
|
92
|
+
if (show) {
|
|
93
|
+
<Child />
|
|
94
|
+
}
|
|
95
|
+
<button onClick={() => (show = !show)}>{'Toggle Child'}</button>
|
|
96
|
+
</>;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
function Child() {
|
|
100
|
+
return <>
|
|
101
|
+
let &[medium] = MediaQuery(media);
|
|
102
|
+
<div>
|
|
103
|
+
<p>{medium}</p>
|
|
104
|
+
</div>
|
|
105
|
+
</>;
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
render(App);
|
|
@@ -3,19 +3,19 @@ import { TRACKED_OBJECT } from '../../src/runtime/internal/client/constants.js';
|
|
|
3
3
|
|
|
4
4
|
describe('RippleObject', () => {
|
|
5
5
|
it('makes new properties reactive', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
function ObjectTest() {
|
|
7
|
+
return <>
|
|
8
|
+
const obj = new RippleObject({ a: -1 });
|
|
9
|
+
obj.a = 0;
|
|
10
|
+
<pre>{obj.a}</pre>
|
|
11
|
+
<button
|
|
12
|
+
onClick={() => {
|
|
13
|
+
obj.a++;
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
{'Increment A'}
|
|
17
|
+
</button>
|
|
18
|
+
</>;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
render(ObjectTest);
|
|
@@ -32,17 +32,18 @@ describe('RippleObject', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('makes existing object properties reactive', () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
function ObjectTest() {
|
|
36
|
+
return <>
|
|
37
|
+
const obj = new RippleObject({ a: 0 });
|
|
38
|
+
<pre>{obj.a}</pre>
|
|
39
|
+
<button
|
|
40
|
+
onClick={() => {
|
|
41
|
+
obj.a++;
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
{'Increment A'}
|
|
45
|
+
</button>
|
|
46
|
+
</>;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
render(ObjectTest);
|
|
@@ -59,12 +60,12 @@ describe('RippleObject', () => {
|
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
it('checks if property exists via the has trap', () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
function ObjectTest() {
|
|
64
|
+
return <>
|
|
65
|
+
const obj = new RippleObject({ a: -1, b: 1 });
|
|
66
|
+
obj.a = 0;
|
|
67
|
+
<pre>{'a' in obj && 'b' in obj}</pre>
|
|
68
|
+
</>;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
render(ObjectTest);
|
|
@@ -75,17 +76,18 @@ describe('RippleObject', () => {
|
|
|
75
76
|
});
|
|
76
77
|
|
|
77
78
|
it('deletes properties via the delete trap', () => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
function ObjectTest() {
|
|
80
|
+
return <>
|
|
81
|
+
const obj = new RippleObject<{ a?: number; b: number }>({ a: 0, b: 1 });
|
|
82
|
+
<pre>{String(obj.a)}</pre>
|
|
83
|
+
<button
|
|
84
|
+
onClick={() => {
|
|
85
|
+
delete obj.a;
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
{'Delete A'}
|
|
89
|
+
</button>
|
|
90
|
+
</>;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
render(ObjectTest);
|
|
@@ -102,17 +104,18 @@ describe('RippleObject', () => {
|
|
|
102
104
|
});
|
|
103
105
|
|
|
104
106
|
it('checks if non-existent property is reactive when added later', () => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
function ObjectTest() {
|
|
108
|
+
return <>
|
|
109
|
+
const obj = new RippleObject<{ a?: number }>({});
|
|
110
|
+
<pre>{String(obj.a)}</pre>
|
|
111
|
+
<button
|
|
112
|
+
onClick={() => {
|
|
113
|
+
obj.a = 1;
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
{'Add A'}
|
|
117
|
+
</button>
|
|
118
|
+
</>;
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
render(ObjectTest);
|
|
@@ -129,17 +132,18 @@ describe('RippleObject', () => {
|
|
|
129
132
|
});
|
|
130
133
|
|
|
131
134
|
it('checks that deeply nested objects are not proxied or reactive', () => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
function ObjectTest() {
|
|
136
|
+
return <>
|
|
137
|
+
const obj = new RippleObject({ a: { b: 1 } });
|
|
138
|
+
<pre>{String(obj.a.b)}</pre>
|
|
139
|
+
<button
|
|
140
|
+
onClick={() => {
|
|
141
|
+
obj.a.b++;
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
{'Increment B'}
|
|
145
|
+
</button>
|
|
146
|
+
</>;
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
render(ObjectTest);
|
|
@@ -157,28 +161,30 @@ describe('RippleObject', () => {
|
|
|
157
161
|
});
|
|
158
162
|
|
|
159
163
|
it('checks if TRACKED_OBJECT symbol is present on RippleObject instances', () => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
function ObjectTest() {
|
|
165
|
+
return <>
|
|
166
|
+
const obj = new RippleObject({ a: 0 });
|
|
167
|
+
// @ts-expect-error TRACKED_OBJECT is internal
|
|
168
|
+
expect(obj[TRACKED_OBJECT]).toBe(true);
|
|
169
|
+
</>;
|
|
165
170
|
}
|
|
166
171
|
});
|
|
167
172
|
|
|
168
173
|
it('uses the hash syntax for creating RippleObject', () => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
function ObjectTest() {
|
|
175
|
+
return <>
|
|
176
|
+
const obj = new RippleObject({ a: 0, b: 1, c: { d: { e: 8 } } });
|
|
177
|
+
<pre>{obj.a}</pre>
|
|
178
|
+
<pre>{TRACKED_OBJECT in obj}</pre>
|
|
179
|
+
<pre>{JSON.stringify(obj)}</pre>
|
|
180
|
+
<button
|
|
181
|
+
onClick={() => {
|
|
182
|
+
obj.a++;
|
|
183
|
+
}}
|
|
184
|
+
>
|
|
185
|
+
{'Increment A'}
|
|
186
|
+
</button>
|
|
187
|
+
</>;
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
render(ObjectTest);
|
|
@@ -11,10 +11,12 @@ describe('Portal', () => {
|
|
|
11
11
|
const target = document.createElement('div');
|
|
12
12
|
document.body.appendChild(target);
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<
|
|
17
|
-
|
|
14
|
+
function TestPortal() {
|
|
15
|
+
return <>
|
|
16
|
+
<Portal {target}>
|
|
17
|
+
<div class="test-portal">{'Portal works!'}</div>
|
|
18
|
+
</Portal>
|
|
19
|
+
</>;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
render(TestPortal);
|
|
@@ -28,10 +30,12 @@ describe('Portal', () => {
|
|
|
28
30
|
});
|
|
29
31
|
|
|
30
32
|
it('renders portal content to document.body', () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
33
|
+
function TestPortal() {
|
|
34
|
+
return <>
|
|
35
|
+
<Portal target={document.body}>
|
|
36
|
+
<div class="test-portal">{'In document.body!'}</div>
|
|
37
|
+
</Portal>
|
|
38
|
+
</>;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
render(TestPortal);
|
|
@@ -45,16 +49,16 @@ describe('Portal', () => {
|
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
it('cleans up portal content when destroyed via conditional rendering', () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
function TestPortal() {
|
|
53
|
+
return <>
|
|
54
|
+
let &[open] = track(true);
|
|
55
|
+
if (open) {
|
|
56
|
+
<Portal target={document.body}>
|
|
57
|
+
<div class="test-portal">{'Conditional content'}</div>
|
|
58
|
+
</Portal>
|
|
59
|
+
}
|
|
60
|
+
<button onClick={() => (open = false)}>{'Close'}</button>
|
|
61
|
+
</>;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
render(TestPortal);
|
|
@@ -71,21 +75,21 @@ describe('Portal', () => {
|
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
it('opens and closes portal via conditional rendering', () => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
function TestPortal() {
|
|
79
|
+
return <>
|
|
80
|
+
let &[open] = track(false);
|
|
81
|
+
if (open) {
|
|
82
|
+
<Portal target={document.body}>
|
|
83
|
+
<div class="test-portal">
|
|
84
|
+
{'Content'}
|
|
85
|
+
<button onClick={() => (open = false)}>{'Close'}</button>
|
|
86
|
+
</div>
|
|
87
|
+
</Portal>
|
|
88
|
+
}
|
|
89
|
+
if (!open) {
|
|
90
|
+
<button onClick={() => (open = true)}>{'Open'}</button>
|
|
91
|
+
}
|
|
92
|
+
</>;
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
render(TestPortal);
|
|
@@ -113,14 +117,15 @@ describe('Portal', () => {
|
|
|
113
117
|
document.body.appendChild(target1);
|
|
114
118
|
document.body.appendChild(target2);
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
function TestMultiPortal() {
|
|
121
|
+
return <>
|
|
122
|
+
<Portal target={target1}>
|
|
123
|
+
<div class="test-portal">{'Portal 1 content'}</div>
|
|
124
|
+
</Portal>
|
|
125
|
+
<Portal target={target2}>
|
|
126
|
+
<div class="test-portal">{'Portal 2 content'}</div>
|
|
127
|
+
</Portal>
|
|
128
|
+
</>;
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
render(TestMultiPortal);
|
|
@@ -137,16 +142,17 @@ describe('Portal', () => {
|
|
|
137
142
|
});
|
|
138
143
|
|
|
139
144
|
it('handles portal with reactive content', () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
145
|
+
function TestReactivePortal() {
|
|
146
|
+
return <>
|
|
147
|
+
let &[count] = track(0);
|
|
148
|
+
<Portal target={document.body}>
|
|
149
|
+
<div class="test-portal">
|
|
150
|
+
{'Count: '}
|
|
151
|
+
{String(count)}
|
|
152
|
+
<button onClick={() => count++}>{'Increment'}</button>
|
|
153
|
+
</div>
|
|
154
|
+
</Portal>
|
|
155
|
+
</>;
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
render(TestReactivePortal);
|