ripple 0.2.208 → 0.2.210
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 +43 -0
- package/README.md +2 -1
- package/package.json +2 -6
- package/shims/rollup-estree-types.d.ts +1 -1
- package/src/compiler/index.d.ts +1 -0
- package/src/compiler/index.js +7 -1
- package/src/compiler/phases/1-parse/index.js +15 -6
- package/src/compiler/phases/2-analyze/css-analyze.js +100 -104
- package/src/compiler/phases/2-analyze/index.js +215 -2
- package/src/compiler/phases/3-transform/client/index.js +388 -50
- package/src/compiler/phases/3-transform/segments.js +123 -39
- package/src/compiler/phases/3-transform/server/index.js +266 -13
- package/src/compiler/types/index.d.ts +16 -3
- package/src/compiler/utils.js +1 -15
- package/src/constants.js +0 -2
- package/src/helpers.d.ts +4 -0
- package/src/html-tree-validation.js +211 -0
- package/src/jsx-runtime.d.ts +260 -259
- package/src/jsx-runtime.js +12 -12
- package/src/runtime/array.js +17 -17
- package/src/runtime/create-subscriber.js +1 -1
- package/src/runtime/index-client.js +1 -5
- package/src/runtime/index-server.js +15 -0
- package/src/runtime/internal/client/compat.js +3 -3
- package/src/runtime/internal/client/composite.js +6 -1
- package/src/runtime/internal/client/head.js +50 -4
- package/src/runtime/internal/client/html.js +73 -12
- package/src/runtime/internal/client/hydration.js +12 -0
- package/src/runtime/internal/client/index.js +1 -1
- package/src/runtime/internal/client/portal.js +54 -29
- package/src/runtime/internal/client/rpc.js +3 -1
- package/src/runtime/internal/client/switch.js +5 -0
- package/src/runtime/internal/client/template.js +117 -11
- package/src/runtime/internal/client/try.js +1 -0
- package/src/runtime/internal/server/index.js +113 -1
- package/src/runtime/internal/server/rpc.js +4 -4
- package/src/runtime/map.js +2 -2
- package/src/runtime/object.js +6 -6
- package/src/runtime/proxy.js +12 -11
- package/src/runtime/reactive-value.js +9 -1
- package/src/runtime/set.js +12 -7
- package/src/runtime/url-search-params.js +0 -1
- package/src/server/index.js +4 -0
- package/src/utils/hashing.js +15 -0
- package/src/utils/normalize_css_property_name.js +1 -1
- package/tests/client/array/array.mutations.test.ripple +8 -8
- package/tests/client/basic/basic.errors.test.ripple +28 -0
- package/tests/client/basic/basic.events.test.ripple +6 -3
- package/tests/client/basic/basic.utilities.test.ripple +1 -1
- package/tests/client/compiler/compiler.regex.test.ripple +10 -8
- package/tests/client/composite/composite.generics.test.ripple +5 -2
- package/tests/client/dynamic-elements.test.ripple +30 -1
- package/tests/client/function-overload-import.ripple +6 -7
- package/tests/client/html.test.ripple +0 -1
- package/tests/client/object.test.ripple +2 -2
- package/tests/client/portal.test.ripple +3 -3
- package/tests/client/return.test.ripple +2500 -0
- package/tests/client/try.test.ripple +69 -0
- package/tests/client/typescript-generics.test.ripple +1 -1
- package/tests/client/url/url.derived.test.ripple +1 -1
- package/tests/client/url/url.parsing.test.ripple +3 -3
- package/tests/client/url/url.partial-removal.test.ripple +7 -7
- package/tests/client/url/url.reactivity.test.ripple +15 -15
- package/tests/client/url/url.serialization.test.ripple +2 -2
- package/tests/hydration/basic.test.js +23 -0
- package/tests/hydration/build-components.js +10 -4
- package/tests/hydration/compiled/client/basic.js +165 -3
- package/tests/hydration/compiled/client/for.js +1140 -23
- package/tests/hydration/compiled/client/head.js +234 -0
- package/tests/hydration/compiled/client/html.js +135 -0
- package/tests/hydration/compiled/client/portal.js +172 -0
- package/tests/hydration/compiled/client/reactivity.js +3 -1
- package/tests/hydration/compiled/client/return.js +1976 -0
- package/tests/hydration/compiled/client/switch.js +162 -0
- package/tests/hydration/compiled/server/basic.js +249 -0
- package/tests/hydration/compiled/server/events.js +1 -1
- package/tests/hydration/compiled/server/for.js +891 -1
- package/tests/hydration/compiled/server/head.js +291 -0
- package/tests/hydration/compiled/server/html.js +133 -0
- package/tests/hydration/compiled/server/if.js +1 -1
- package/tests/hydration/compiled/server/portal.js +250 -0
- package/tests/hydration/compiled/server/reactivity.js +1 -1
- package/tests/hydration/compiled/server/return.js +1969 -0
- package/tests/hydration/compiled/server/switch.js +130 -0
- package/tests/hydration/components/basic.ripple +55 -0
- package/tests/hydration/components/for.ripple +403 -0
- package/tests/hydration/components/head.ripple +111 -0
- package/tests/hydration/components/html.ripple +38 -0
- package/tests/hydration/components/portal.ripple +49 -0
- package/tests/hydration/components/return.ripple +564 -0
- package/tests/hydration/components/switch.ripple +51 -0
- package/tests/hydration/for.test.js +363 -0
- package/tests/hydration/head.test.js +105 -0
- package/tests/hydration/html.test.js +46 -0
- package/tests/hydration/portal.test.js +71 -0
- package/tests/hydration/return.test.js +544 -0
- package/tests/hydration/switch.test.js +42 -0
- package/tests/server/basic.attributes.test.ripple +1 -1
- package/tests/server/compiler.test.ripple +22 -0
- package/tests/server/composite.test.ripple +5 -2
- package/tests/server/html-nesting-validation.test.ripple +237 -0
- package/tests/server/return.test.ripple +1379 -0
- package/tests/setup-hydration.js +6 -1
- package/tests/utils/escaping.test.js +3 -1
- package/tests/utils/normalize_css_property_name.test.js +0 -1
- package/tests/utils/patterns.test.js +6 -2
- package/tests/utils/sanitize_template_string.test.js +3 -2
- package/types/server.d.ts +16 -0
|
@@ -61,6 +61,34 @@ describe('basic client > errors', () => {
|
|
|
61
61
|
}).toThrow('Unclosed tag');
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
it('should throw error for interpolating children as text', () => {
|
|
65
|
+
const code = `
|
|
66
|
+
export component Layout({ children }) {
|
|
67
|
+
<div>{children}</div>
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
expect(() => {
|
|
72
|
+
compile(code, 'test.ripple');
|
|
73
|
+
}).toThrow(
|
|
74
|
+
'`children` cannot be rendered using text interpolation. Use `<children />` instead.',
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should throw error for interpolating props.children as text', () => {
|
|
79
|
+
const code = `
|
|
80
|
+
export component Layout(props) {
|
|
81
|
+
<div>{props.children}</div>
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
expect(() => {
|
|
86
|
+
compile(code, 'test.ripple');
|
|
87
|
+
}).toThrow(
|
|
88
|
+
'`children` cannot be rendered using text interpolation. Use `<children />` instead.',
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
64
92
|
it('errors on mutating tracked value inside computed track() evaluation', () => {
|
|
65
93
|
component Basic() {
|
|
66
94
|
let count = track(0);
|
|
@@ -42,9 +42,12 @@ describe('basic client > events', () => {
|
|
|
42
42
|
let bubbleClicks = track(0);
|
|
43
43
|
|
|
44
44
|
<div
|
|
45
|
-
onClick={{
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
onClick={{
|
|
46
|
+
handleEvent: () => {
|
|
47
|
+
@captureClicks++;
|
|
48
|
+
},
|
|
49
|
+
capture: true,
|
|
50
|
+
}}
|
|
48
51
|
>
|
|
49
52
|
<button
|
|
50
53
|
onClick={() => {
|
|
@@ -3,7 +3,7 @@ import { track, effect, untrack, tick } from 'ripple';
|
|
|
3
3
|
describe('basic client > utilities', () => {
|
|
4
4
|
it('tick function', async () => {
|
|
5
5
|
let resolve: () => void;
|
|
6
|
-
const promise = new Promise<void>((res) => resolve = res);
|
|
6
|
+
const promise = new Promise<void>((res) => (resolve = res));
|
|
7
7
|
|
|
8
8
|
component Basic() {
|
|
9
9
|
let value = track(0);
|
|
@@ -59,16 +59,18 @@ describe('compiler > regex', () => {
|
|
|
59
59
|
// Mix of regex parsing and legitimate JSX
|
|
60
60
|
let paragraphs = htmlString.match(/<p[^>]*>.*?<\/p>/g);
|
|
61
61
|
let cleaned = htmlString.replace(/<\/?[^>]+>/g, '');
|
|
62
|
-
let splitArray = htmlString.split(/<\/?\w+>/g).filter(s => s.trim());
|
|
62
|
+
let splitArray = htmlString.split(/<\/?\w+>/g).filter((s) => s.trim());
|
|
63
63
|
|
|
64
|
-
<div class=
|
|
65
|
-
<span class=
|
|
66
|
-
<span class=
|
|
64
|
+
<div class="container">
|
|
65
|
+
<span class="result">{String(paragraphs)}</span>
|
|
66
|
+
<span class="cleaned">{cleaned}</span>
|
|
67
67
|
<p>{'This is real JSX'}</p>
|
|
68
|
-
<div
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
<div>
|
|
69
|
+
<span>
|
|
70
|
+
{'Split result: '}
|
|
71
|
+
{splitArray.join(', ')}
|
|
72
|
+
</span>
|
|
73
|
+
</div>
|
|
72
74
|
</div>
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -201,8 +201,11 @@ describe('composite > generics', () => {
|
|
|
201
201
|
this.map = new Map<Key, Value>();
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
const gg = new Mapper
|
|
205
|
-
|
|
204
|
+
const gg = new Mapper<
|
|
205
|
+
// key type
|
|
206
|
+
string /* value type */,
|
|
207
|
+
number
|
|
208
|
+
>();
|
|
206
209
|
|
|
207
210
|
// 33. Map of generic instance as key
|
|
208
211
|
const mm = new Map<TrackedArray<number>, TrackedArray<string>>();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PropsWithExtras } from 'ripple';
|
|
2
2
|
import { flushSync, track, createRefKey, trackSplit } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('dynamic DOM elements', () => {
|
|
@@ -592,4 +592,33 @@ describe('dynamic DOM elements', () => {
|
|
|
592
592
|
expect(outerScopes).toHaveLength(1);
|
|
593
593
|
expect(innerScopes).toHaveLength(0);
|
|
594
594
|
});
|
|
595
|
+
|
|
596
|
+
it('should remove and add back a text node in a conditional statement with a tracked', () => {
|
|
597
|
+
component App() {
|
|
598
|
+
let b = track(true);
|
|
599
|
+
<div>
|
|
600
|
+
if (@b) {
|
|
601
|
+
{'Inside if'}
|
|
602
|
+
}
|
|
603
|
+
</div>
|
|
604
|
+
<button onClick={() => (@b = !@b)}>{'Toggle b'}</button>
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
render(App);
|
|
608
|
+
|
|
609
|
+
const button = container.querySelector('button');
|
|
610
|
+
const div = container.querySelector('div');
|
|
611
|
+
|
|
612
|
+
expect(div.textContent).toBe('Inside if');
|
|
613
|
+
|
|
614
|
+
button.click();
|
|
615
|
+
flushSync();
|
|
616
|
+
|
|
617
|
+
expect(div.textContent).toBe('');
|
|
618
|
+
|
|
619
|
+
button.click();
|
|
620
|
+
flushSync();
|
|
621
|
+
|
|
622
|
+
expect(div.textContent).toBe('Inside if');
|
|
623
|
+
});
|
|
595
624
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export function test(arg: string): string
|
|
2
|
-
export function test(arg: number): string
|
|
3
|
-
|
|
1
|
+
export function test(arg: string): string;
|
|
2
|
+
export function test(arg: number): string;
|
|
4
3
|
export function test(arg: string | number): string {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
if (typeof arg === 'string') {
|
|
5
|
+
return arg;
|
|
6
|
+
}
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
return arg.toString();
|
|
10
9
|
}
|
|
@@ -4,7 +4,7 @@ import { TRACKED_OBJECT } from '../../src/runtime/internal/client/constants.js';
|
|
|
4
4
|
describe('TrackedObject', () => {
|
|
5
5
|
it('makes new properties reactive', () => {
|
|
6
6
|
component ObjectTest() {
|
|
7
|
-
const obj = new TrackedObject<{ a: number }>({a: -1});
|
|
7
|
+
const obj = new TrackedObject<{ a: number }>({ a: -1 });
|
|
8
8
|
|
|
9
9
|
obj.a = 0;
|
|
10
10
|
|
|
@@ -60,7 +60,7 @@ describe('TrackedObject', () => {
|
|
|
60
60
|
|
|
61
61
|
it('checks if property exists via the has trap', () => {
|
|
62
62
|
component ObjectTest() {
|
|
63
|
-
const obj = new TrackedObject<{ a: number; b: number }>({ a: -
|
|
63
|
+
const obj = new TrackedObject<{ a: number; b: number }>({ a: -1, b: 1 });
|
|
64
64
|
|
|
65
65
|
obj.a = 0;
|
|
66
66
|
|
|
@@ -54,7 +54,7 @@ describe('Portal', () => {
|
|
|
54
54
|
</Portal>
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
<button onClick={() => @open = false}>{'Close'}</button>
|
|
57
|
+
<button onClick={() => (@open = false)}>{'Close'}</button>
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
render(TestPortal);
|
|
@@ -78,13 +78,13 @@ describe('Portal', () => {
|
|
|
78
78
|
<Portal target={document.body}>
|
|
79
79
|
<div class="test-portal">
|
|
80
80
|
{'Content'}
|
|
81
|
-
<button onClick={() => @open = false}>{'Close'}</button>
|
|
81
|
+
<button onClick={() => (@open = false)}>{'Close'}</button>
|
|
82
82
|
</div>
|
|
83
83
|
</Portal>
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
if (!@open) {
|
|
87
|
-
<button onClick={() => @open = true}>{'Open'}</button>
|
|
87
|
+
<button onClick={() => (@open = true)}>{'Open'}</button>
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|