ripple 0.2.115 → 0.2.118
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 +16 -16
- package/src/compiler/index.js +20 -1
- package/src/compiler/phases/1-parse/index.js +79 -0
- package/src/compiler/phases/3-transform/client/index.js +54 -8
- package/src/compiler/phases/3-transform/segments.js +107 -60
- package/src/compiler/phases/3-transform/server/index.js +21 -11
- package/src/compiler/types/index.d.ts +16 -0
- package/src/runtime/index-client.js +19 -185
- package/src/runtime/index-server.js +24 -0
- package/src/runtime/internal/client/bindings.js +443 -0
- package/src/runtime/internal/client/index.js +4 -0
- package/src/runtime/internal/client/runtime.js +10 -0
- package/src/runtime/internal/client/utils.js +0 -8
- package/src/runtime/map.js +11 -1
- package/src/runtime/set.js +11 -1
- package/tests/client/__snapshots__/for.test.ripple.snap +80 -0
- package/tests/client/_etc.test.ripple +5 -0
- package/tests/client/array/array.copy-within.test.ripple +120 -0
- package/tests/client/array/array.derived.test.ripple +495 -0
- package/tests/client/array/array.iteration.test.ripple +115 -0
- package/tests/client/array/array.mutations.test.ripple +385 -0
- package/tests/client/array/array.static.test.ripple +237 -0
- package/tests/client/array/array.to-methods.test.ripple +93 -0
- package/tests/client/basic/__snapshots__/basic.attributes.test.ripple.snap +60 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.ripple.snap +106 -0
- package/tests/client/basic/__snapshots__/basic.text.test.ripple.snap +49 -0
- package/tests/client/basic/basic.attributes.test.ripple +474 -0
- package/tests/client/basic/basic.collections.test.ripple +94 -0
- package/tests/client/basic/basic.components.test.ripple +225 -0
- package/tests/client/basic/basic.errors.test.ripple +126 -0
- package/tests/client/basic/basic.events.test.ripple +222 -0
- package/tests/client/basic/basic.reactivity.test.ripple +476 -0
- package/tests/client/basic/basic.rendering.test.ripple +204 -0
- package/tests/client/basic/basic.styling.test.ripple +63 -0
- package/tests/client/basic/basic.utilities.test.ripple +25 -0
- package/tests/client/boundaries.test.ripple +2 -21
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +12 -0
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +22 -0
- package/tests/client/compiler/compiler.assignments.test.ripple +112 -0
- package/tests/client/compiler/compiler.attributes.test.ripple +95 -0
- package/tests/client/compiler/compiler.basic.test.ripple +203 -0
- package/tests/client/compiler/compiler.regex.test.ripple +87 -0
- package/tests/client/compiler/compiler.typescript.test.ripple +29 -0
- package/tests/client/{__snapshots__/composite.test.ripple.snap → composite/__snapshots__/composite.render.test.ripple.snap} +2 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +100 -0
- package/tests/client/composite/composite.generics.test.ripple +211 -0
- package/tests/client/composite/composite.props.test.ripple +106 -0
- package/tests/client/composite/composite.reactivity.test.ripple +184 -0
- package/tests/client/composite/composite.render.test.ripple +84 -0
- package/tests/client/computed-properties.test.ripple +2 -21
- package/tests/client/context.test.ripple +5 -22
- package/tests/client/date.test.ripple +1 -20
- package/tests/client/dynamic-elements.test.ripple +16 -24
- package/tests/client/for.test.ripple +4 -23
- package/tests/client/head.test.ripple +11 -23
- package/tests/client/html.test.ripple +1 -20
- package/tests/client/input-value.test.ripple +11 -31
- package/tests/client/map.test.ripple +82 -20
- package/tests/client/media-query.test.ripple +10 -23
- package/tests/client/object.test.ripple +5 -24
- package/tests/client/portal.test.ripple +2 -19
- package/tests/client/ref.test.ripple +8 -26
- package/tests/client/set.test.ripple +84 -22
- package/tests/client/svg.test.ripple +1 -22
- package/tests/client/switch.test.ripple +6 -25
- package/tests/client/tracked-expression.test.ripple +2 -21
- package/tests/client/typescript-generics.test.ripple +0 -21
- package/tests/client/url/url.derived.test.ripple +83 -0
- package/tests/client/url/url.parsing.test.ripple +165 -0
- package/tests/client/url/url.partial-removal.test.ripple +198 -0
- package/tests/client/url/url.reactivity.test.ripple +449 -0
- package/tests/client/url/url.serialization.test.ripple +50 -0
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +84 -0
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +61 -0
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +153 -0
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +343 -0
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +160 -0
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +53 -0
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +55 -0
- package/tests/client.d.ts +12 -0
- package/tests/server/if.test.ripple +66 -0
- package/tests/setup-client.js +28 -0
- package/tsconfig.json +4 -2
- package/types/index.d.ts +92 -46
- package/LICENSE +0 -21
- package/tests/client/__snapshots__/basic.test.ripple.snap +0 -117
- package/tests/client/__snapshots__/compiler.test.ripple.snap +0 -33
- package/tests/client/array.test.ripple +0 -1455
- package/tests/client/basic.test.ripple +0 -1892
- package/tests/client/compiler.test.ripple +0 -541
- package/tests/client/composite.test.ripple +0 -692
- package/tests/client/url-search-params.test.ripple +0 -912
- package/tests/client/url.test.ripple +0 -954
|
@@ -35,14 +35,6 @@ export function create_anchor() {
|
|
|
35
35
|
return t;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/**
|
|
39
|
-
* @param {any} value
|
|
40
|
-
* @returns {boolean}
|
|
41
|
-
*/
|
|
42
|
-
export function is_positive_integer(value) {
|
|
43
|
-
return Number.isInteger(value) && /**@type {number} */ (value) >= 0;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
38
|
/**
|
|
47
39
|
* Checks if an object is a tracked object (has a numeric 'f' property).
|
|
48
40
|
* @param {any} v - The object to check.
|
package/src/runtime/map.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { Block, Tracked } from '#client' */
|
|
2
|
-
import { get, increment, safe_scope, set, tracked } from './internal/client/runtime.js';
|
|
2
|
+
import { get, increment, safe_scope, set, tracked, with_scope } from './internal/client/runtime.js';
|
|
3
3
|
|
|
4
4
|
const introspect_methods = ['entries', 'forEach', 'values', Symbol.iterator];
|
|
5
5
|
|
|
@@ -193,3 +193,13 @@ export class TrackedMap extends Map {
|
|
|
193
193
|
return [...this];
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @template K, V
|
|
199
|
+
* @param {Block} block
|
|
200
|
+
* @param {...any} args
|
|
201
|
+
* @returns {TrackedMap<K, V>}
|
|
202
|
+
*/
|
|
203
|
+
export function tracked_map(block, ...args) {
|
|
204
|
+
return with_scope(block, () => new TrackedMap(...args));
|
|
205
|
+
}
|
package/src/runtime/set.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { Block, Tracked } from '#client' */
|
|
2
|
-
import { get, increment, safe_scope, set, tracked } from './internal/client/runtime.js';
|
|
2
|
+
import { get, increment, safe_scope, set, tracked, with_scope } from './internal/client/runtime.js';
|
|
3
3
|
|
|
4
4
|
const introspect_methods = ['entries', 'forEach', 'keys', 'values', Symbol.iterator];
|
|
5
5
|
|
|
@@ -193,3 +193,13 @@ export class TrackedSet extends Set {
|
|
|
193
193
|
return [...this];
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @template V
|
|
199
|
+
* @param {Block} block
|
|
200
|
+
* @param {...any} args
|
|
201
|
+
* @returns {TrackedSet<V>}
|
|
202
|
+
*/
|
|
203
|
+
export function tracked_set(block, ...args) {
|
|
204
|
+
return with_scope(block, () => new TrackedSet(...args));
|
|
205
|
+
}
|
|
@@ -317,3 +317,83 @@ exports[`for statements > render a simple static array 1`] = `
|
|
|
317
317
|
|
|
318
318
|
</div>
|
|
319
319
|
`;
|
|
320
|
+
|
|
321
|
+
exports[`for statements > renders a simple dynamic array 1`] = `
|
|
322
|
+
<div>
|
|
323
|
+
<!---->
|
|
324
|
+
<div
|
|
325
|
+
class="Item 1"
|
|
326
|
+
>
|
|
327
|
+
Item 1
|
|
328
|
+
</div>
|
|
329
|
+
<div
|
|
330
|
+
class="Item 2"
|
|
331
|
+
>
|
|
332
|
+
Item 2
|
|
333
|
+
</div>
|
|
334
|
+
<div
|
|
335
|
+
class="Item 3"
|
|
336
|
+
>
|
|
337
|
+
Item 3
|
|
338
|
+
</div>
|
|
339
|
+
<!---->
|
|
340
|
+
<button>
|
|
341
|
+
Add Item
|
|
342
|
+
</button>
|
|
343
|
+
|
|
344
|
+
</div>
|
|
345
|
+
`;
|
|
346
|
+
|
|
347
|
+
exports[`for statements > renders a simple dynamic array 2`] = `
|
|
348
|
+
<div>
|
|
349
|
+
<!---->
|
|
350
|
+
<div
|
|
351
|
+
class="Item 1"
|
|
352
|
+
>
|
|
353
|
+
Item 1
|
|
354
|
+
</div>
|
|
355
|
+
<div
|
|
356
|
+
class="Item 2"
|
|
357
|
+
>
|
|
358
|
+
Item 2
|
|
359
|
+
</div>
|
|
360
|
+
<div
|
|
361
|
+
class="Item 3"
|
|
362
|
+
>
|
|
363
|
+
Item 3
|
|
364
|
+
</div>
|
|
365
|
+
<div
|
|
366
|
+
class="Item 4"
|
|
367
|
+
>
|
|
368
|
+
Item 4
|
|
369
|
+
</div>
|
|
370
|
+
<!---->
|
|
371
|
+
<button>
|
|
372
|
+
Add Item
|
|
373
|
+
</button>
|
|
374
|
+
|
|
375
|
+
</div>
|
|
376
|
+
`;
|
|
377
|
+
|
|
378
|
+
exports[`for statements > renders a simple static array 1`] = `
|
|
379
|
+
<div>
|
|
380
|
+
<!---->
|
|
381
|
+
<div
|
|
382
|
+
class="Item 1"
|
|
383
|
+
>
|
|
384
|
+
Item 1
|
|
385
|
+
</div>
|
|
386
|
+
<div
|
|
387
|
+
class="Item 2"
|
|
388
|
+
>
|
|
389
|
+
Item 2
|
|
390
|
+
</div>
|
|
391
|
+
<div
|
|
392
|
+
class="Item 3"
|
|
393
|
+
>
|
|
394
|
+
Item 3
|
|
395
|
+
</div>
|
|
396
|
+
<!---->
|
|
397
|
+
|
|
398
|
+
</div>
|
|
399
|
+
`;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { track, flushSync, TrackedArray } from 'ripple';
|
|
2
|
+
|
|
3
|
+
describe('TrackedArray copyWithin', () => {
|
|
4
|
+
it('handles copyWithin operation with reactivity', () => {
|
|
5
|
+
component ArrayTest() {
|
|
6
|
+
let items = new TrackedArray(1, 2, 3, 4, 5);
|
|
7
|
+
let firstItem = track(() => items[0]);
|
|
8
|
+
let thirdItem = track(() => items[2]);
|
|
9
|
+
let fourthItem = track(() => items[3]);
|
|
10
|
+
|
|
11
|
+
<button onClick={() => items.copyWithin(0, 3)}>{'copy end to start'}</button>
|
|
12
|
+
<button onClick={() => items.copyWithin(2, 0, 2)}>{'copy start to middle'}</button>
|
|
13
|
+
<pre>{JSON.stringify(items)}</pre>
|
|
14
|
+
<pre>{@firstItem}</pre>
|
|
15
|
+
<pre>{@thirdItem}</pre>
|
|
16
|
+
<pre>{@fourthItem}</pre>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
render(ArrayTest);
|
|
20
|
+
|
|
21
|
+
const copyEndToStartButton = container.querySelectorAll('button')[0];
|
|
22
|
+
const copyStartToMiddleButton = container.querySelectorAll('button')[1];
|
|
23
|
+
|
|
24
|
+
// Initial state
|
|
25
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,2,3,4,5]');
|
|
26
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('1');
|
|
27
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('3');
|
|
28
|
+
expect(container.querySelectorAll('pre')[3].textContent).toBe('4');
|
|
29
|
+
|
|
30
|
+
// Test copyWithin from end to start
|
|
31
|
+
copyEndToStartButton.click();
|
|
32
|
+
flushSync();
|
|
33
|
+
|
|
34
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[4,5,3,4,5]');
|
|
35
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('4');
|
|
36
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('3');
|
|
37
|
+
expect(container.querySelectorAll('pre')[3].textContent).toBe('4');
|
|
38
|
+
|
|
39
|
+
// Test copyWithin from start to middle
|
|
40
|
+
copyStartToMiddleButton.click();
|
|
41
|
+
flushSync();
|
|
42
|
+
|
|
43
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[4,5,4,5,5]');
|
|
44
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('4');
|
|
45
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('4');
|
|
46
|
+
expect(container.querySelectorAll('pre')[3].textContent).toBe('5');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('handles copyWithin with negative indexes and reactivity', () => {
|
|
50
|
+
component ArrayTest() {
|
|
51
|
+
let items = new TrackedArray(1, 2, 3, 4, 5);
|
|
52
|
+
let secondItem = track(() => items[1]);
|
|
53
|
+
let thirdItem = track(() => items[2]);
|
|
54
|
+
|
|
55
|
+
<button onClick={() => items.copyWithin(-4, -2)}>{'copy with negative indexes'}</button>
|
|
56
|
+
<pre>{JSON.stringify(items)}</pre>
|
|
57
|
+
<pre>{@secondItem}</pre>
|
|
58
|
+
<pre>{@thirdItem}</pre>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
render(ArrayTest);
|
|
62
|
+
|
|
63
|
+
const copyButton = container.querySelector('button');
|
|
64
|
+
|
|
65
|
+
// Initial state
|
|
66
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,2,3,4,5]');
|
|
67
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('2');
|
|
68
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('3');
|
|
69
|
+
|
|
70
|
+
// Test copyWithin with negative indexes
|
|
71
|
+
copyButton.click();
|
|
72
|
+
flushSync();
|
|
73
|
+
|
|
74
|
+
// copyWithin(-4, -2) should copy [4,5] to positions [1,2]
|
|
75
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,4,5,4,5]');
|
|
76
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('4');
|
|
77
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('5');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('handles copyWithin with overlapping ranges', () => {
|
|
81
|
+
component ArrayTest() {
|
|
82
|
+
let items = new TrackedArray(1, 2, 3, 4, 5);
|
|
83
|
+
let entries = track(() => Array.from(items.entries()));
|
|
84
|
+
|
|
85
|
+
<button onClick={() => items.copyWithin(2, 1, 4)}>{'copy with overlap'}</button>
|
|
86
|
+
<pre>{JSON.stringify(items)}</pre>
|
|
87
|
+
|
|
88
|
+
for (const [i, value] of @entries) {
|
|
89
|
+
<pre>{`items[${i}]: ${value}`}</pre>
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
render(ArrayTest);
|
|
94
|
+
|
|
95
|
+
const copyButton = container.querySelector('button');
|
|
96
|
+
|
|
97
|
+
// Initial state
|
|
98
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,2,3,4,5]');
|
|
99
|
+
|
|
100
|
+
// Test values from reactive bindings
|
|
101
|
+
for (let i = 0; i < 5; i++) {
|
|
102
|
+
expect(container.querySelectorAll('pre')[i + 1].textContent).toBe(`items[${i}]: ${i + 1}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Test copyWithin with overlapping ranges
|
|
106
|
+
copyButton.click();
|
|
107
|
+
flushSync();
|
|
108
|
+
|
|
109
|
+
// copyWithin(2, 1, 4) should copy [2,3,4] to positions [2,3,4]
|
|
110
|
+
// resulting in [1,2,2,3,4]
|
|
111
|
+
expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,2,2,3,4]');
|
|
112
|
+
|
|
113
|
+
// Test that reactive bindings updated
|
|
114
|
+
expect(container.querySelectorAll('pre')[1].textContent).toBe('items[0]: 1');
|
|
115
|
+
expect(container.querySelectorAll('pre')[2].textContent).toBe('items[1]: 2');
|
|
116
|
+
expect(container.querySelectorAll('pre')[3].textContent).toBe('items[2]: 2');
|
|
117
|
+
expect(container.querySelectorAll('pre')[4].textContent).toBe('items[3]: 3');
|
|
118
|
+
expect(container.querySelectorAll('pre')[5].textContent).toBe('items[4]: 4');
|
|
119
|
+
});
|
|
120
|
+
});
|