ripple 0.2.215 → 0.3.0
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 +86 -0
- package/package.json +16 -7
- package/src/compiler/errors.js +1 -1
- package/src/compiler/identifier-utils.js +2 -0
- package/src/compiler/index.d.ts +2 -6
- package/src/compiler/phases/1-parse/index.js +171 -233
- package/src/compiler/phases/2-analyze/index.js +216 -16
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +326 -94
- package/src/compiler/phases/3-transform/segments.js +43 -15
- package/src/compiler/phases/3-transform/server/index.js +71 -21
- package/src/compiler/scope.js +31 -12
- package/src/compiler/source-map-utils.js +4 -6
- package/src/compiler/types/acorn.d.ts +11 -0
- package/src/compiler/types/estree-jsx.d.ts +11 -0
- package/src/compiler/types/estree.d.ts +11 -0
- package/src/compiler/types/import.d.ts +32 -18
- package/src/compiler/types/index.d.ts +75 -23
- package/src/compiler/types/parse.d.ts +7 -10
- package/src/compiler/utils.js +48 -0
- package/src/runtime/array.js +53 -22
- package/src/runtime/date.js +15 -5
- package/src/runtime/index-client.js +41 -7
- package/src/runtime/index-server.js +7 -7
- package/src/runtime/internal/client/bindings.js +2 -2
- package/src/runtime/internal/client/blocks.js +40 -1
- package/src/runtime/internal/client/context.js +8 -0
- package/src/runtime/internal/client/for.js +3 -3
- package/src/runtime/internal/client/index.js +32 -5
- package/src/runtime/internal/client/render.js +20 -8
- package/src/runtime/internal/client/runtime.js +9 -7
- package/src/runtime/internal/client/template.js +1 -1
- package/src/runtime/internal/client/try.js +15 -22
- package/src/runtime/internal/client/utils.js +1 -1
- package/src/runtime/internal/server/context.js +8 -0
- package/src/runtime/internal/server/index.js +99 -6
- package/src/runtime/map.js +7 -7
- package/src/runtime/media-query.js +10 -1
- package/src/runtime/object.js +6 -6
- package/src/runtime/proxy.js +6 -6
- package/src/runtime/set.js +11 -11
- package/src/runtime/url-search-params.js +13 -2
- package/src/runtime/url.js +15 -5
- package/src/utils/builders.js +13 -3
- package/tests/client/array/array.copy-within.test.ripple +11 -11
- package/tests/client/array/array.derived.test.ripple +42 -42
- package/tests/client/array/array.iteration.test.ripple +12 -12
- package/tests/client/array/array.mutations.test.ripple +25 -25
- package/tests/client/array/array.static.test.ripple +103 -106
- package/tests/client/array/array.to-methods.test.ripple +8 -8
- package/tests/client/async-suspend.test.ripple +94 -0
- package/tests/client/basic/basic.attributes.test.ripple +31 -31
- package/tests/client/basic/basic.collections.test.ripple +7 -7
- package/tests/client/basic/basic.components.test.ripple +48 -10
- package/tests/client/basic/basic.errors.test.ripple +111 -30
- package/tests/client/basic/basic.events.test.ripple +11 -11
- package/tests/client/basic/basic.get-set.test.ripple +18 -18
- package/tests/client/basic/basic.reactivity.test.ripple +47 -42
- package/tests/client/basic/basic.rendering.test.ripple +7 -7
- package/tests/client/basic/basic.utilities.test.ripple +4 -4
- package/tests/client/boundaries.test.ripple +7 -7
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +2 -2
- package/tests/client/compiler/compiler.assignments.test.ripple +21 -21
- package/tests/client/compiler/compiler.basic.test.ripple +223 -82
- package/tests/client/compiler/compiler.tracked-access.test.ripple +8 -9
- package/tests/client/composite/composite.dynamic-components.test.ripple +8 -8
- package/tests/client/composite/composite.generics.test.ripple +4 -4
- package/tests/client/composite/composite.props.test.ripple +9 -9
- package/tests/client/composite/composite.reactivity.test.ripple +32 -26
- package/tests/client/composite/composite.render.test.ripple +13 -4
- package/tests/client/computed-properties.test.ripple +3 -3
- package/tests/client/context.test.ripple +3 -3
- package/tests/client/css/global-additional-cases.test.ripple +4 -4
- package/tests/client/css/style-identifier.test.ripple +49 -41
- package/tests/client/date.test.ripple +40 -40
- package/tests/client/dynamic-elements.test.ripple +165 -30
- package/tests/client/events.test.ripple +25 -25
- package/tests/client/for.test.ripple +76 -8
- package/tests/client/function-overload.test.ripple +0 -1
- package/tests/client/head.test.ripple +7 -7
- package/tests/client/html.test.ripple +2 -2
- package/tests/client/input-value.test.ripple +174 -176
- package/tests/client/map.test.ripple +21 -21
- package/tests/client/media-query.test.ripple +4 -4
- package/tests/client/object.test.ripple +12 -12
- package/tests/client/portal.test.ripple +4 -4
- package/tests/client/ref.test.ripple +5 -5
- package/tests/client/return.test.ripple +17 -17
- package/tests/client/set.test.ripple +16 -16
- package/tests/client/svg.test.ripple +6 -7
- package/tests/client/switch.test.ripple +10 -10
- package/tests/client/tracked-expression.test.ripple +1 -3
- package/tests/client/try.test.ripple +56 -4
- package/tests/client/url/url.derived.test.ripple +10 -9
- package/tests/client/url/url.parsing.test.ripple +10 -10
- package/tests/client/url/url.partial-removal.test.ripple +10 -10
- package/tests/client/url/url.reactivity.test.ripple +17 -17
- package/tests/client/url/url.serialization.test.ripple +4 -4
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +11 -10
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +5 -7
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +13 -13
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +19 -19
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +17 -17
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +5 -5
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +5 -5
- package/tests/hydration/compiled/client/events.js +8 -11
- package/tests/hydration/compiled/client/for.js +20 -23
- package/tests/hydration/compiled/client/head.js +17 -19
- package/tests/hydration/compiled/client/hmr.js +84 -0
- package/tests/hydration/compiled/client/html.js +1 -15
- package/tests/hydration/compiled/client/if-children.js +7 -9
- package/tests/hydration/compiled/client/if.js +5 -7
- package/tests/hydration/compiled/client/mixed-control-flow.js +3 -5
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +9 -11
- package/tests/hydration/compiled/client/return.js +11 -13
- package/tests/hydration/compiled/client/switch.js +4 -6
- package/tests/hydration/compiled/server/basic.js +0 -1
- package/tests/hydration/compiled/server/composite.js +0 -3
- package/tests/hydration/compiled/server/events.js +8 -12
- package/tests/hydration/compiled/server/for.js +20 -23
- package/tests/hydration/compiled/server/head.js +17 -19
- package/tests/hydration/compiled/server/hmr.js +107 -0
- package/tests/hydration/compiled/server/html.js +1 -35
- package/tests/hydration/compiled/server/if-children.js +7 -11
- package/tests/hydration/compiled/server/if.js +5 -7
- package/tests/hydration/compiled/server/mixed-control-flow.js +3 -5
- package/tests/hydration/compiled/server/portal.js +1 -9
- package/tests/hydration/compiled/server/reactivity.js +9 -11
- package/tests/hydration/compiled/server/return.js +11 -13
- package/tests/hydration/compiled/server/switch.js +4 -6
- package/tests/hydration/components/events.ripple +8 -9
- package/tests/hydration/components/for.ripple +20 -21
- package/tests/hydration/components/head.ripple +6 -8
- package/tests/hydration/components/hmr.ripple +34 -0
- package/tests/hydration/components/html.ripple +1 -3
- package/tests/hydration/components/if-children.ripple +7 -8
- package/tests/hydration/components/if.ripple +5 -6
- package/tests/hydration/components/mixed-control-flow.ripple +4 -6
- package/tests/hydration/components/portal.ripple +1 -1
- package/tests/hydration/components/reactivity.ripple +9 -10
- package/tests/hydration/components/return.ripple +11 -12
- package/tests/hydration/components/switch.ripple +6 -8
- package/tests/hydration/hmr.test.js +74 -0
- package/tests/server/await.test.ripple +2 -2
- package/tests/server/basic.attributes.test.ripple +19 -21
- package/tests/server/basic.components.test.ripple +13 -7
- package/tests/server/basic.test.ripple +20 -21
- package/tests/server/compiler.test.ripple +5 -5
- package/tests/server/composite.props.test.ripple +6 -7
- package/tests/server/composite.test.ripple +4 -4
- package/tests/server/context.test.ripple +1 -3
- package/tests/server/dynamic-elements.test.ripple +24 -24
- package/tests/server/head.test.ripple +5 -7
- package/tests/server/style-identifier.test.ripple +16 -17
- package/types/index.d.ts +266 -62
- package/types/server.d.ts +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushSync,
|
|
1
|
+
import { flushSync, RippleArray } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('for statements', () => {
|
|
4
4
|
it('renders a simple static array', () => {
|
|
@@ -17,7 +17,7 @@ describe('for statements', () => {
|
|
|
17
17
|
|
|
18
18
|
it('renders a simple dynamic array', () => {
|
|
19
19
|
component App() {
|
|
20
|
-
const items =
|
|
20
|
+
const items = #ripple['Item 1', 'Item 2', 'Item 3'];
|
|
21
21
|
|
|
22
22
|
for (const item of items) {
|
|
23
23
|
<div class={item}>{item}</div>
|
|
@@ -39,7 +39,7 @@ describe('for statements', () => {
|
|
|
39
39
|
|
|
40
40
|
it('correctly handles intermediate statements in for block', () => {
|
|
41
41
|
component App() {
|
|
42
|
-
const items =
|
|
42
|
+
const items = #ripple[1, 2, 3];
|
|
43
43
|
|
|
44
44
|
<div>
|
|
45
45
|
for (const item of items) {
|
|
@@ -68,7 +68,7 @@ describe('for statements', () => {
|
|
|
68
68
|
|
|
69
69
|
it('correctly handles the index in a for...of loop', () => {
|
|
70
70
|
component App() {
|
|
71
|
-
const items =
|
|
71
|
+
const items = #ripple['a', 'b', 'c'];
|
|
72
72
|
|
|
73
73
|
<div>
|
|
74
74
|
for (let item of items; index i) {
|
|
@@ -101,7 +101,7 @@ describe('for statements', () => {
|
|
|
101
101
|
|
|
102
102
|
it('correctly handles keyed for...of loops', () => {
|
|
103
103
|
component App() {
|
|
104
|
-
let items = track([
|
|
104
|
+
let items = #ripple.track([
|
|
105
105
|
{ id: 1, text: 'Item 1' },
|
|
106
106
|
{ id: 2, text: 'Item 2' },
|
|
107
107
|
{ id: 3, text: 'Item 3' },
|
|
@@ -134,9 +134,9 @@ describe('for statements', () => {
|
|
|
134
134
|
|
|
135
135
|
it('keyed for over derived updates sibling text nodes', () => {
|
|
136
136
|
component App() {
|
|
137
|
-
let count = track(0);
|
|
137
|
+
let count = #ripple.track(0);
|
|
138
138
|
|
|
139
|
-
const items = track(
|
|
139
|
+
const items = #ripple.track(
|
|
140
140
|
() => Array.from({ length: @count }).map((_, id) => ({ id, label: `Item ${id}` })),
|
|
141
141
|
);
|
|
142
142
|
|
|
@@ -173,9 +173,42 @@ describe('for statements', () => {
|
|
|
173
173
|
expect(container.querySelectorAll('.item').length).toBe(2);
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
+
it('keyed for with 32+ items: full reversal updates values via Map path', () => {
|
|
177
|
+
component App() {
|
|
178
|
+
let items = track(Array.from({ length: 40 }, (_, i) => ({ id: i, text: `Item ${i}` })));
|
|
179
|
+
|
|
180
|
+
<div>
|
|
181
|
+
for (let item of @items; index idx; key item.id) {
|
|
182
|
+
<span class="item">{idx + ':' + item.text}</span>
|
|
183
|
+
}
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<button
|
|
187
|
+
onClick={() => {
|
|
188
|
+
@items = @items.toReversed();
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
{'Reverse'}
|
|
192
|
+
</button>
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
render(App);
|
|
196
|
+
|
|
197
|
+
const getTexts = () => Array.from(container.querySelectorAll('.item')).map(
|
|
198
|
+
(el) => el.textContent,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
expect(getTexts()).toEqual(Array.from({ length: 40 }, (_, i) => `${i}:Item ${i}`));
|
|
202
|
+
|
|
203
|
+
container.querySelector('button').click();
|
|
204
|
+
flushSync();
|
|
205
|
+
|
|
206
|
+
expect(getTexts()).toEqual(Array.from({ length: 40 }, (_, i) => `${i}:Item ${39 - i}`));
|
|
207
|
+
});
|
|
208
|
+
|
|
176
209
|
it('handles updating with new objects with same key', () => {
|
|
177
210
|
component App() {
|
|
178
|
-
let items = track([
|
|
211
|
+
let items = #ripple.track([
|
|
179
212
|
{ id: 1, text: 'Item 1' },
|
|
180
213
|
{ id: 2, text: 'Item 2' },
|
|
181
214
|
{ id: 3, text: 'Item 3' },
|
|
@@ -211,4 +244,39 @@ describe('for statements', () => {
|
|
|
211
244
|
|
|
212
245
|
expect(container).toMatchSnapshot();
|
|
213
246
|
});
|
|
247
|
+
|
|
248
|
+
it('ref-based for with 32+ items: remove from start with shared refs via Map path', () => {
|
|
249
|
+
const objects = Array.from({ length: 50 }, (_, i) => ({ id: i, text: `Obj ${i}` }));
|
|
250
|
+
|
|
251
|
+
component App() {
|
|
252
|
+
let items = track(objects.slice());
|
|
253
|
+
|
|
254
|
+
<div>
|
|
255
|
+
for (const item of @items) {
|
|
256
|
+
<span class="item">{item.text}</span>
|
|
257
|
+
}
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<button
|
|
261
|
+
onClick={() => {
|
|
262
|
+
@items = objects.slice(15).reverse();
|
|
263
|
+
}}
|
|
264
|
+
>
|
|
265
|
+
{'Trim and reverse'}
|
|
266
|
+
</button>
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
render(App);
|
|
270
|
+
|
|
271
|
+
const getTexts = () => Array.from(container.querySelectorAll('.item')).map(
|
|
272
|
+
(el) => el.textContent,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
expect(getTexts()).toEqual(objects.map((o) => o.text));
|
|
276
|
+
|
|
277
|
+
container.querySelector('button').click();
|
|
278
|
+
flushSync();
|
|
279
|
+
|
|
280
|
+
expect(getTexts()).toEqual(objects.slice(15).reverse().map((o) => o.text));
|
|
281
|
+
});
|
|
214
282
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushSync
|
|
1
|
+
import { flushSync } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('head elements', () => {
|
|
4
4
|
let originalTitle: string;
|
|
@@ -29,7 +29,7 @@ describe('head elements', () => {
|
|
|
29
29
|
|
|
30
30
|
it('renders reactive title element', () => {
|
|
31
31
|
component App() {
|
|
32
|
-
let title = track('Initial Title');
|
|
32
|
+
let title = #ripple.track('Initial Title');
|
|
33
33
|
|
|
34
34
|
<head>
|
|
35
35
|
<title>{@title}</title>
|
|
@@ -61,7 +61,7 @@ describe('head elements', () => {
|
|
|
61
61
|
|
|
62
62
|
it('renders title with template literal', () => {
|
|
63
63
|
component App() {
|
|
64
|
-
let name = track('World');
|
|
64
|
+
let name = #ripple.track('World');
|
|
65
65
|
|
|
66
66
|
<head>
|
|
67
67
|
<title>{`Hello ${@name}!`}</title>
|
|
@@ -90,7 +90,7 @@ describe('head elements', () => {
|
|
|
90
90
|
|
|
91
91
|
it('renders title with computed value', () => {
|
|
92
92
|
component App() {
|
|
93
|
-
let count = track(0);
|
|
93
|
+
let count = #ripple.track(0);
|
|
94
94
|
let prefix = 'Count: ';
|
|
95
95
|
|
|
96
96
|
<head>
|
|
@@ -122,7 +122,7 @@ describe('head elements', () => {
|
|
|
122
122
|
|
|
123
123
|
it('handles multiple title updates', () => {
|
|
124
124
|
component App() {
|
|
125
|
-
let step = track(1);
|
|
125
|
+
let step = #ripple.track(1);
|
|
126
126
|
|
|
127
127
|
<head>
|
|
128
128
|
<title>{`Step ${@step} of 3`}</title>
|
|
@@ -172,8 +172,8 @@ describe('head elements', () => {
|
|
|
172
172
|
|
|
173
173
|
it('renders title with conditional content', () => {
|
|
174
174
|
component App() {
|
|
175
|
-
let showPrefix = track(true);
|
|
176
|
-
let title = track('Main Page');
|
|
175
|
+
let showPrefix = #ripple.track(true);
|
|
176
|
+
let title = #ripple.track('Main Page');
|
|
177
177
|
|
|
178
178
|
<head>
|
|
179
179
|
<title>{@showPrefix ? 'App - ' + @title : @title}</title>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushSync
|
|
1
|
+
import { flushSync } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('html directive', () => {
|
|
4
4
|
it('renders static html', () => {
|
|
@@ -14,7 +14,7 @@ describe('html directive', () => {
|
|
|
14
14
|
|
|
15
15
|
it('renders dynamic html', () => {
|
|
16
16
|
component App() {
|
|
17
|
-
let str = track('<div>Test</div>');
|
|
17
|
+
let str = #ripple.track('<div>Test</div>');
|
|
18
18
|
|
|
19
19
|
{html @str}
|
|
20
20
|
|