ripple 0.3.84 → 0.3.85

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 (53) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/package.json +3 -3
  3. package/src/constants.js +4 -0
  4. package/src/runtime/internal/client/component.js +3 -3
  5. package/src/runtime/internal/client/constants.js +4 -0
  6. package/src/runtime/internal/client/for.js +22 -1
  7. package/src/runtime/internal/client/if.js +18 -2
  8. package/src/runtime/internal/client/index.js +1 -0
  9. package/src/runtime/internal/client/operations.js +25 -0
  10. package/src/runtime/internal/client/runtime.js +62 -10
  11. package/src/runtime/internal/client/switch.js +16 -2
  12. package/src/runtime/internal/client/template.js +10 -2
  13. package/src/runtime/internal/client/try.js +12 -2
  14. package/src/runtime/internal/client/types.d.ts +4 -0
  15. package/tests/client/__snapshots__/for.test.tsrx.snap +0 -2
  16. package/tests/client/compiler/compiler.basic.test.tsrx +5 -2
  17. package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -4
  18. package/tests/client/scoped-flush.test.tsrx +105 -0
  19. package/tests/hydration/compiled/client/basic.js +198 -214
  20. package/tests/hydration/compiled/client/composite.js +23 -72
  21. package/tests/hydration/compiled/client/for.js +66 -72
  22. package/tests/hydration/compiled/client/hmr.js +2 -13
  23. package/tests/hydration/compiled/client/html.js +619 -479
  24. package/tests/hydration/compiled/client/if-children.js +72 -84
  25. package/tests/hydration/compiled/client/if.js +87 -92
  26. package/tests/hydration/compiled/client/mixed-control-flow.js +120 -160
  27. package/tests/hydration/compiled/client/nested-control-flow.js +288 -360
  28. package/tests/hydration/compiled/client/portal.js +15 -21
  29. package/tests/hydration/compiled/client/reactivity.js +7 -12
  30. package/tests/hydration/compiled/client/switch.js +113 -115
  31. package/tests/hydration/compiled/client/track-async-serialization.js +71 -122
  32. package/tests/hydration/compiled/client/try.js +26 -41
  33. package/tests/hydration/compiled/server/basic.js +268 -556
  34. package/tests/hydration/compiled/server/composite.js +31 -50
  35. package/tests/hydration/compiled/server/events.js +37 -173
  36. package/tests/hydration/compiled/server/for.js +236 -847
  37. package/tests/hydration/compiled/server/head.js +110 -241
  38. package/tests/hydration/compiled/server/hmr.js +14 -41
  39. package/tests/hydration/compiled/server/html-in-template.js +14 -38
  40. package/tests/hydration/compiled/server/html.js +951 -1176
  41. package/tests/hydration/compiled/server/if-children.js +59 -493
  42. package/tests/hydration/compiled/server/if.js +57 -209
  43. package/tests/hydration/compiled/server/mixed-control-flow.js +144 -250
  44. package/tests/hydration/compiled/server/nested-control-flow.js +309 -559
  45. package/tests/hydration/compiled/server/portal.js +94 -156
  46. package/tests/hydration/compiled/server/reactivity.js +23 -65
  47. package/tests/hydration/compiled/server/return.js +6 -16
  48. package/tests/hydration/compiled/server/switch.js +91 -219
  49. package/tests/hydration/compiled/server/track-async-serialization.js +211 -256
  50. package/tests/hydration/compiled/server/try.js +67 -126
  51. package/tests/hydration/components/html.tsrx +75 -0
  52. package/tests/hydration/html.test.js +50 -0
  53. package/tests/server/compiler.test.tsrx +6 -2
@@ -0,0 +1,105 @@
1
+ import { flushSync, track, Context } from 'ripple';
2
+
3
+ describe('scoped flush', () => {
4
+ // Scoped descent must not change observable behaviour: a tracked shared across
5
+ // sibling subtrees via a module-level variable (escaping its owner subtree)
6
+ // must still update its out-of-subtree subscriber.
7
+ it('updates a sibling subtree that reads a module-smuggled tracked', () => {
8
+ let shared = null;
9
+ let bump = null;
10
+
11
+ function Producer() @{
12
+ let &[v, vT] = track(0);
13
+ shared = vT;
14
+ bump = () => {
15
+ v += 1;
16
+ };
17
+ <div class="producer">{'producer'}</div>
18
+ }
19
+
20
+ function Consumer() @{
21
+ <div class="consumer">
22
+ {shared ? shared.value : -1}
23
+ </div>
24
+ }
25
+
26
+ function App() @{
27
+ <>
28
+ <Producer />
29
+ <Consumer />
30
+ </>
31
+ }
32
+
33
+ render(App);
34
+
35
+ expect(container.querySelector('.consumer').textContent).toBe('0');
36
+
37
+ flushSync(() => bump());
38
+
39
+ expect(container.querySelector('.consumer').textContent).toBe('1');
40
+
41
+ flushSync(() => bump());
42
+
43
+ expect(container.querySelector('.consumer').textContent).toBe('2');
44
+ });
45
+
46
+ // The common, scope-safe case: a Context-provided tracked read at many leaves.
47
+ // A root update must fan out to all leaves; a scoped update must reach only the
48
+ // targeted subtree's leaf and leave the others untouched.
49
+ it('fans out a root update and scopes a nested update', () => {
50
+ const Ctx = new Context(null);
51
+ let bumpRoot = null;
52
+ let bumpLeftLocal = null;
53
+
54
+ function Leaf(props) @{
55
+ const rootT = Ctx.get();
56
+ <span class={'leaf-' + props.id}>
57
+ {rootT ? rootT.value : -1}
58
+ </span>
59
+ }
60
+
61
+ function Branch(props) @{
62
+ let &[local, localT] = track(0);
63
+ if (props.side === 'L') {
64
+ bumpLeftLocal = () => {
65
+ local += 1;
66
+ };
67
+ }
68
+ <div class={'branch-' + props.side}>
69
+ <Leaf id={props.side + '0'} />
70
+ <Leaf id={props.side + '1'} />
71
+ </div>
72
+ }
73
+
74
+ function App() @{
75
+ let &[root, rootT] = track(0);
76
+ Ctx.set(rootT);
77
+ bumpRoot = () => {
78
+ root += 1;
79
+ };
80
+ <div>
81
+ <Branch side="L" />
82
+ <Branch side="R" />
83
+ </div>
84
+ }
85
+
86
+ render(App);
87
+
88
+ const leaves = () => ['L0', 'L1', 'R0', 'R1'].map(
89
+ (id) => container.querySelector('.leaf-' + id).textContent,
90
+ );
91
+
92
+ expect(leaves()).toEqual(['0', '0', '0', '0']);
93
+
94
+ flushSync(() => bumpRoot());
95
+ expect(leaves()).toEqual(['1', '1', '1', '1']);
96
+
97
+ flushSync(() => bumpLeftLocal());
98
+ // Local bump touches no Context value, so leaf text is unchanged, but the
99
+ // update must flush without error and not disturb sibling subtrees.
100
+ expect(leaves()).toEqual(['1', '1', '1', '1']);
101
+
102
+ flushSync(() => bumpRoot());
103
+ expect(leaves()).toEqual(['2', '2', '2', '2']);
104
+ });
105
+ });