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.
Files changed (93) hide show
  1. package/package.json +16 -16
  2. package/src/compiler/index.js +20 -1
  3. package/src/compiler/phases/1-parse/index.js +79 -0
  4. package/src/compiler/phases/3-transform/client/index.js +54 -8
  5. package/src/compiler/phases/3-transform/segments.js +107 -60
  6. package/src/compiler/phases/3-transform/server/index.js +21 -11
  7. package/src/compiler/types/index.d.ts +16 -0
  8. package/src/runtime/index-client.js +19 -185
  9. package/src/runtime/index-server.js +24 -0
  10. package/src/runtime/internal/client/bindings.js +443 -0
  11. package/src/runtime/internal/client/index.js +4 -0
  12. package/src/runtime/internal/client/runtime.js +10 -0
  13. package/src/runtime/internal/client/utils.js +0 -8
  14. package/src/runtime/map.js +11 -1
  15. package/src/runtime/set.js +11 -1
  16. package/tests/client/__snapshots__/for.test.ripple.snap +80 -0
  17. package/tests/client/_etc.test.ripple +5 -0
  18. package/tests/client/array/array.copy-within.test.ripple +120 -0
  19. package/tests/client/array/array.derived.test.ripple +495 -0
  20. package/tests/client/array/array.iteration.test.ripple +115 -0
  21. package/tests/client/array/array.mutations.test.ripple +385 -0
  22. package/tests/client/array/array.static.test.ripple +237 -0
  23. package/tests/client/array/array.to-methods.test.ripple +93 -0
  24. package/tests/client/basic/__snapshots__/basic.attributes.test.ripple.snap +60 -0
  25. package/tests/client/basic/__snapshots__/basic.rendering.test.ripple.snap +106 -0
  26. package/tests/client/basic/__snapshots__/basic.text.test.ripple.snap +49 -0
  27. package/tests/client/basic/basic.attributes.test.ripple +474 -0
  28. package/tests/client/basic/basic.collections.test.ripple +94 -0
  29. package/tests/client/basic/basic.components.test.ripple +225 -0
  30. package/tests/client/basic/basic.errors.test.ripple +126 -0
  31. package/tests/client/basic/basic.events.test.ripple +222 -0
  32. package/tests/client/basic/basic.reactivity.test.ripple +476 -0
  33. package/tests/client/basic/basic.rendering.test.ripple +204 -0
  34. package/tests/client/basic/basic.styling.test.ripple +63 -0
  35. package/tests/client/basic/basic.utilities.test.ripple +25 -0
  36. package/tests/client/boundaries.test.ripple +2 -21
  37. package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +12 -0
  38. package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +22 -0
  39. package/tests/client/compiler/compiler.assignments.test.ripple +112 -0
  40. package/tests/client/compiler/compiler.attributes.test.ripple +95 -0
  41. package/tests/client/compiler/compiler.basic.test.ripple +203 -0
  42. package/tests/client/compiler/compiler.regex.test.ripple +87 -0
  43. package/tests/client/compiler/compiler.typescript.test.ripple +29 -0
  44. package/tests/client/{__snapshots__/composite.test.ripple.snap → composite/__snapshots__/composite.render.test.ripple.snap} +2 -2
  45. package/tests/client/composite/composite.dynamic-components.test.ripple +100 -0
  46. package/tests/client/composite/composite.generics.test.ripple +211 -0
  47. package/tests/client/composite/composite.props.test.ripple +106 -0
  48. package/tests/client/composite/composite.reactivity.test.ripple +184 -0
  49. package/tests/client/composite/composite.render.test.ripple +84 -0
  50. package/tests/client/computed-properties.test.ripple +2 -21
  51. package/tests/client/context.test.ripple +5 -22
  52. package/tests/client/date.test.ripple +1 -20
  53. package/tests/client/dynamic-elements.test.ripple +16 -24
  54. package/tests/client/for.test.ripple +4 -23
  55. package/tests/client/head.test.ripple +11 -23
  56. package/tests/client/html.test.ripple +1 -20
  57. package/tests/client/input-value.test.ripple +11 -31
  58. package/tests/client/map.test.ripple +82 -20
  59. package/tests/client/media-query.test.ripple +10 -23
  60. package/tests/client/object.test.ripple +5 -24
  61. package/tests/client/portal.test.ripple +2 -19
  62. package/tests/client/ref.test.ripple +8 -26
  63. package/tests/client/set.test.ripple +84 -22
  64. package/tests/client/svg.test.ripple +1 -22
  65. package/tests/client/switch.test.ripple +6 -25
  66. package/tests/client/tracked-expression.test.ripple +2 -21
  67. package/tests/client/typescript-generics.test.ripple +0 -21
  68. package/tests/client/url/url.derived.test.ripple +83 -0
  69. package/tests/client/url/url.parsing.test.ripple +165 -0
  70. package/tests/client/url/url.partial-removal.test.ripple +198 -0
  71. package/tests/client/url/url.reactivity.test.ripple +449 -0
  72. package/tests/client/url/url.serialization.test.ripple +50 -0
  73. package/tests/client/url-search-params/url-search-params.derived.test.ripple +84 -0
  74. package/tests/client/url-search-params/url-search-params.initialization.test.ripple +61 -0
  75. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +153 -0
  76. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +343 -0
  77. package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +160 -0
  78. package/tests/client/url-search-params/url-search-params.serialization.test.ripple +53 -0
  79. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +55 -0
  80. package/tests/client.d.ts +12 -0
  81. package/tests/server/if.test.ripple +66 -0
  82. package/tests/setup-client.js +28 -0
  83. package/tsconfig.json +4 -2
  84. package/types/index.d.ts +92 -46
  85. package/LICENSE +0 -21
  86. package/tests/client/__snapshots__/basic.test.ripple.snap +0 -117
  87. package/tests/client/__snapshots__/compiler.test.ripple.snap +0 -33
  88. package/tests/client/array.test.ripple +0 -1455
  89. package/tests/client/basic.test.ripple +0 -1892
  90. package/tests/client/compiler.test.ripple +0 -541
  91. package/tests/client/composite.test.ripple +0 -692
  92. package/tests/client/url-search-params.test.ripple +0 -912
  93. 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.
@@ -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
+ }
@@ -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,5 @@
1
+ // This file is for tests that don't fit anywhere else
2
+
3
+ describe('etc', () => {
4
+ it.skip('this is here so the empty test suite does not fail');
5
+ });
@@ -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
+ });