ripple 0.2.152 → 0.2.154

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 (67) hide show
  1. package/README.md +3 -3
  2. package/package.json +5 -5
  3. package/src/compiler/phases/1-parse/index.js +1 -1
  4. package/src/compiler/phases/3-transform/client/index.js +37 -16
  5. package/src/compiler/phases/3-transform/server/index.js +43 -25
  6. package/src/runtime/internal/client/events.js +5 -1
  7. package/src/runtime/internal/client/index.js +2 -1
  8. package/src/runtime/internal/client/render.js +18 -15
  9. package/src/runtime/internal/client/runtime.js +75 -10
  10. package/src/runtime/internal/server/index.js +51 -11
  11. package/src/server/index.js +1 -1
  12. package/tests/client/array/array.derived.test.ripple +61 -33
  13. package/tests/client/array/array.iteration.test.ripple +3 -1
  14. package/tests/client/array/array.mutations.test.ripple +19 -15
  15. package/tests/client/array/array.static.test.ripple +115 -104
  16. package/tests/client/array/array.to-methods.test.ripple +3 -3
  17. package/tests/client/basic/basic.attributes.test.ripple +110 -57
  18. package/tests/client/basic/basic.collections.test.ripple +41 -22
  19. package/tests/client/basic/basic.errors.test.ripple +12 -6
  20. package/tests/client/basic/basic.events.test.ripple +51 -33
  21. package/tests/client/basic/basic.reactivity.test.ripple +120 -56
  22. package/tests/client/basic/basic.rendering.test.ripple +49 -19
  23. package/tests/client/basic/basic.styling.test.ripple +2 -2
  24. package/tests/client/basic/basic.utilities.test.ripple +1 -1
  25. package/tests/client/boundaries.test.ripple +70 -58
  26. package/tests/client/compiler/compiler.assignments.test.ripple +32 -4
  27. package/tests/client/compiler/compiler.attributes.test.ripple +46 -46
  28. package/tests/client/compiler/compiler.basic.test.ripple +18 -15
  29. package/tests/client/compiler/compiler.tracked-access.test.ripple +53 -42
  30. package/tests/client/compiler/compiler.typescript.test.ripple +1 -2
  31. package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
  32. package/tests/client/composite/composite.generics.test.ripple +39 -36
  33. package/tests/client/composite/composite.props.test.ripple +4 -3
  34. package/tests/client/composite/composite.reactivity.test.ripple +112 -27
  35. package/tests/client/composite/composite.render.test.ripple +9 -8
  36. package/tests/client/computed-properties.test.ripple +24 -24
  37. package/tests/client/context.test.ripple +11 -9
  38. package/tests/client/date.test.ripple +3 -1
  39. package/tests/client/dynamic-elements.test.ripple +103 -78
  40. package/tests/client/for.test.ripple +27 -17
  41. package/tests/client/head.test.ripple +42 -6
  42. package/tests/client/html.test.ripple +42 -32
  43. package/tests/client/input-value.test.ripple +4 -4
  44. package/tests/client/map.test.ripple +140 -141
  45. package/tests/client/media-query.test.ripple +31 -31
  46. package/tests/client/object.test.ripple +148 -112
  47. package/tests/client/portal.test.ripple +29 -15
  48. package/tests/client/ref.test.ripple +9 -3
  49. package/tests/client/set.test.ripple +111 -111
  50. package/tests/client/tracked-expression.test.ripple +16 -17
  51. package/tests/client/url/url.derived.test.ripple +19 -9
  52. package/tests/client/url/url.parsing.test.ripple +24 -8
  53. package/tests/client/url/url.partial-removal.test.ripple +12 -4
  54. package/tests/client/url/url.reactivity.test.ripple +63 -25
  55. package/tests/client/url/url.serialization.test.ripple +18 -6
  56. package/tests/client/url-search-params/url-search-params.derived.test.ripple +10 -6
  57. package/tests/client/url-search-params/url-search-params.iteration.test.ripple +3 -1
  58. package/tests/client/url-search-params/url-search-params.mutation.test.ripple +26 -14
  59. package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -1
  60. package/tests/server/await.test.ripple +23 -22
  61. package/tests/server/basic.test.ripple +1 -1
  62. package/tests/server/compiler.test.ripple +3 -7
  63. package/tests/server/composite.test.ripple +38 -36
  64. package/tests/server/for.test.ripple +9 -5
  65. package/tests/server/if.test.ripple +1 -1
  66. package/tests/server/streaming-ssr.test.ripple +67 -0
  67. package/types/server.d.ts +5 -4
@@ -70,10 +70,38 @@ describe('compiler > assignments', () => {
70
70
  render(App);
71
71
 
72
72
  expect(logs).toEqual([
73
- undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined,
74
- 123, 123, 123, 123, 123, 123, 123, 123,
75
- 125, 125, 125, 125, 125, 125, 125, 125,
76
- 124, 123, 124, 123, 124, 123, 124, 123
73
+ undefined,
74
+ undefined,
75
+ undefined,
76
+ undefined,
77
+ undefined,
78
+ undefined,
79
+ undefined,
80
+ undefined,
81
+ 123,
82
+ 123,
83
+ 123,
84
+ 123,
85
+ 123,
86
+ 123,
87
+ 123,
88
+ 123,
89
+ 125,
90
+ 125,
91
+ 125,
92
+ 125,
93
+ 125,
94
+ 125,
95
+ 125,
96
+ 125,
97
+ 124,
98
+ 123,
99
+ 124,
100
+ 123,
101
+ 124,
102
+ 123,
103
+ 124,
104
+ 123,
77
105
  ]);
78
106
  });
79
107
 
@@ -1,8 +1,8 @@
1
1
  import { parse, compile } from 'ripple/compiler';
2
2
 
3
3
  describe('compiler > attributes', () => {
4
- it('generates valid JavaScript for component props with hyphenated attributes', () => {
5
- const source = `
4
+ it('generates valid JavaScript for component props with hyphenated attributes', () => {
5
+ const source = `
6
6
  component Child(props) {
7
7
  <div />
8
8
  }
@@ -11,34 +11,34 @@ describe('compiler > attributes', () => {
11
11
  <Child data-scope="test" aria-label="accessible" class="valid" />
12
12
  }`;
13
13
 
14
- const result = compile(source, 'test.ripple', { mode: 'client' });
14
+ const result = compile(source, 'test.ripple', { mode: 'client' });
15
15
 
16
- // Should contain properly quoted hyphenated properties and unquoted valid identifiers
17
- expect(result.js.code).toMatch(/'data-scope': "test"/);
18
- expect(result.js.code).toMatch(/'aria-label': "accessible"/);
19
- expect(result.js.code).toMatch(/class: "valid"/);
20
- });
16
+ // Should contain properly quoted hyphenated properties and unquoted valid identifiers
17
+ expect(result.js.code).toMatch(/'data-scope': "test"/);
18
+ expect(result.js.code).toMatch(/'aria-label': "accessible"/);
19
+ expect(result.js.code).toMatch(/class: "valid"/);
20
+ });
21
21
 
22
- it('generates valid JavaScript for all types of hyphenated attributes', () => {
23
- const testCases = [
24
- { attr: 'data-testid="value"', expected: /'data-testid': "value"/ },
25
- { attr: 'aria-label="label"', expected: /'aria-label': "label"/ },
26
- { attr: 'data-custom-attr="custom"', expected: /'data-custom-attr': "custom"/ },
27
- { attr: 'ng-if="condition"', expected: /'ng-if': "condition"/ },
28
- ];
22
+ it('generates valid JavaScript for all types of hyphenated attributes', () => {
23
+ const testCases = [
24
+ { attr: 'data-testid="value"', expected: /'data-testid': "value"/ },
25
+ { attr: 'aria-label="label"', expected: /'aria-label': "label"/ },
26
+ { attr: 'data-custom-attr="custom"', expected: /'data-custom-attr': "custom"/ },
27
+ { attr: 'ng-if="condition"', expected: /'ng-if': "condition"/ },
28
+ ];
29
29
 
30
- testCases.forEach(({ attr, expected }) => {
31
- const source = `
30
+ testCases.forEach(({ attr, expected }) => {
31
+ const source = `
32
32
  component Child(props) { <div /> }
33
33
  export default component App() { <Child ${attr} /> }`;
34
34
 
35
- const result = compile(source, 'test.ripple', { mode: 'client' });
36
- expect(result.js.code).toMatch(expected);
37
- });
35
+ const result = compile(source, 'test.ripple', { mode: 'client' });
36
+ expect(result.js.code).toMatch(expected);
38
37
  });
38
+ });
39
39
 
40
- it('handles mixed valid and invalid attribute identifiers correctly', () => {
41
- const source = `
40
+ it('handles mixed valid and invalid attribute identifiers correctly', () => {
41
+ const source = `
42
42
  component Child(props) {
43
43
  <div />
44
44
  }
@@ -54,21 +54,21 @@ describe('compiler > attributes', () => {
54
54
  />
55
55
  }`;
56
56
 
57
- const result = compile(source, 'test.ripple', { mode: 'client' });
57
+ const result = compile(source, 'test.ripple', { mode: 'client' });
58
58
 
59
- // Valid identifiers should not be quoted
60
- expect(result.js.code).toMatch(/validProp: "valid"/);
61
- expect(result.js.code).toMatch(/class: "valid"/);
62
- expect(result.js.code).toMatch(/id: "valid"/);
59
+ // Valid identifiers should not be quoted
60
+ expect(result.js.code).toMatch(/validProp: "valid"/);
61
+ expect(result.js.code).toMatch(/class: "valid"/);
62
+ expect(result.js.code).toMatch(/id: "valid"/);
63
63
 
64
- // Invalid identifiers (with hyphens) should be quoted
65
- expect(result.js.code).toMatch(/'data-invalid': "invalid"/);
66
- expect(result.js.code).toMatch(/'aria-invalid': "invalid"/);
67
- expect(result.js.code).toMatch(/'custom-prop': "invalid"/);
68
- });
64
+ // Invalid identifiers (with hyphens) should be quoted
65
+ expect(result.js.code).toMatch(/'data-invalid': "invalid"/);
66
+ expect(result.js.code).toMatch(/'aria-invalid': "invalid"/);
67
+ expect(result.js.code).toMatch(/'custom-prop': "invalid"/);
68
+ });
69
69
 
70
- it('ensures generated code is syntactically valid JavaScript', () => {
71
- const source = `
70
+ it('ensures generated code is syntactically valid JavaScript', () => {
71
+ const source = `
72
72
  component Child(props) {
73
73
  <div />
74
74
  }
@@ -77,19 +77,19 @@ describe('compiler > attributes', () => {
77
77
  <Child data-scope="test" />
78
78
  }`;
79
79
 
80
- const result = compile(source, 'test.ripple', { mode: 'client' });
80
+ const result = compile(source, 'test.ripple', { mode: 'client' });
81
81
 
82
- // Extract the props object from the generated code and test it's valid JavaScript
83
- const match = result.js.code.match(/Child\([^,]+,\s*(\{[^}]+\})/);
84
- expect(match).toBeTruthy();
82
+ // Extract the props object from the generated code and test it's valid JavaScript
83
+ const match = result.js.code.match(/Child\([^,]+,\s*(\{[^}]+\})/);
84
+ expect(match).toBeTruthy();
85
85
 
86
- const propsObject = match?.[1];
87
- expect(() => {
88
- // Test that the object literal is syntactically valid
89
- new Function(`return ${propsObject}`);
90
- }).not.toThrow();
86
+ const propsObject = match?.[1];
87
+ expect(() => {
88
+ // Test that the object literal is syntactically valid
89
+ new Function(`return ${propsObject}`);
90
+ }).not.toThrow();
91
91
 
92
- // Also verify it contains the expected quoted property
93
- expect(propsObject).toMatch(/'data-scope': "test"/);
94
- });
92
+ // Also verify it contains the expected quoted property
93
+ expect(propsObject).toMatch(/'data-scope': "test"/);
94
+ });
95
95
  });
@@ -247,8 +247,10 @@ component App() {
247
247
  expect(count_occurrences(result, 'createRefKey')).toBe(2);
248
248
  });
249
249
 
250
- it('doesn\'t add duplicate imports for renamed imports when encountering shorthand syntax', () => {
251
- const source = `
250
+ it(
251
+ 'doesn\'t add duplicate imports for renamed imports when encountering shorthand syntax',
252
+ () => {
253
+ const source = `
252
254
  import {
253
255
  TrackedArray as TA,
254
256
  TrackedObject as TO,
@@ -266,19 +268,20 @@ component App() {
266
268
  <div {ref () => {}} />
267
269
  }
268
270
  `;
269
- const result = compile_to_volar_mappings(source, 'test.ripple').code;
270
-
271
- expect(count_occurrences(result, 'TrackedArray')).toBe(1);
272
- expect(count_occurrences(result, 'TA')).toBe(2);
273
- expect(count_occurrences(result, 'TrackedObject')).toBe(1);
274
- expect(count_occurrences(result, 'TO')).toBe(2);
275
- expect(count_occurrences(result, 'TrackedSet')).toBe(1);
276
- expect(count_occurrences(result, 'TS')).toBe(2);
277
- expect(count_occurrences(result, 'TrackedMap')).toBe(1);
278
- expect(count_occurrences(result, 'TM')).toBe(2);
279
- expect(count_occurrences(result, 'createRefKey')).toBe(1);
280
- expect(count_occurrences(result, 'crk')).toBe(2);
281
- });
271
+ const result = compile_to_volar_mappings(source, 'test.ripple').code;
272
+
273
+ expect(count_occurrences(result, 'TrackedArray')).toBe(1);
274
+ expect(count_occurrences(result, 'TA')).toBe(2);
275
+ expect(count_occurrences(result, 'TrackedObject')).toBe(1);
276
+ expect(count_occurrences(result, 'TO')).toBe(2);
277
+ expect(count_occurrences(result, 'TrackedSet')).toBe(1);
278
+ expect(count_occurrences(result, 'TS')).toBe(2);
279
+ expect(count_occurrences(result, 'TrackedMap')).toBe(1);
280
+ expect(count_occurrences(result, 'TM')).toBe(2);
281
+ expect(count_occurrences(result, 'createRefKey')).toBe(1);
282
+ expect(count_occurrences(result, 'crk')).toBe(2);
283
+ },
284
+ );
282
285
 
283
286
  it('adds missing imports for shorthand syntax', () => {
284
287
  const source = `
@@ -2,107 +2,118 @@ import { compile } from 'ripple/compiler';
2
2
  import { track } from 'ripple';
3
3
 
4
4
  describe('Compiler: Tracked Object Direct Access Checks', () => {
5
-
6
- it('should error on direct access to __v of a tracked object', () => {
7
- const code = `
5
+ it('should error on direct access to __v of a tracked object', () => {
6
+ const code = `
8
7
  export default component App() {
9
8
  let count = track(0);
10
9
  console.log(count.__v);
11
10
  }
12
11
  `;
13
- expect(() => compile(code, 'test.ripple')).toThrow(/Directly accessing internal property "__v" of a tracked object is not allowed/);
14
- });
12
+ expect(() => compile(code, 'test.ripple')).toThrow(
13
+ /Directly accessing internal property "__v" of a tracked object is not allowed/,
14
+ );
15
+ });
15
16
 
16
- it('should error on direct access to "a" (get/set config) of a tracked object', () => {
17
- const code = `
17
+ it('should error on direct access to "a" (get/set config) of a tracked object', () => {
18
+ const code = `
18
19
  export default component App() {
19
20
  let myTracked = track(0);
20
21
  console.log(myTracked.a);
21
22
  }
22
23
  `;
23
- expect(() => compile(code, 'test.ripple')).toThrow(/Directly accessing internal property "a" of a tracked object is not allowed/);
24
- });
24
+ expect(() => compile(code, 'test.ripple')).toThrow(
25
+ /Directly accessing internal property "a" of a tracked object is not allowed/,
26
+ );
27
+ });
25
28
 
26
- it('should error on direct access to "b" (block) of a tracked object', () => {
27
- const code = `
29
+ it('should error on direct access to "b" (block) of a tracked object', () => {
30
+ const code = `
28
31
  export default component App() {
29
32
  let myTracked = track(0);
30
33
  console.log(myTracked.b);
31
34
  }
32
35
  `;
33
- expect(() => compile(code, 'test.ripple')).toThrow(/Directly accessing internal property "b" of a tracked object is not allowed/);
34
- });
36
+ expect(() => compile(code, 'test.ripple')).toThrow(
37
+ /Directly accessing internal property "b" of a tracked object is not allowed/,
38
+ );
39
+ });
35
40
 
36
- it('should error on direct access to "c" (clock) of a tracked object', () => {
37
- const code = `
41
+ it('should error on direct access to "c" (clock) of a tracked object', () => {
42
+ const code = `
38
43
  export default component App() {
39
44
  let myTracked = track(0);
40
45
  console.log(myTracked.c);
41
46
  }
42
47
  `;
43
- expect(() => compile(code, 'test.ripple')).toThrow(/Directly accessing internal property "c" of a tracked object is not allowed/);
44
- });
48
+ expect(() => compile(code, 'test.ripple')).toThrow(
49
+ /Directly accessing internal property "c" of a tracked object is not allowed/,
50
+ );
51
+ });
45
52
 
46
- it('should error on direct access to "f" (flags) of a tracked object', () => {
47
- const code = `
53
+ it('should error on direct access to "f" (flags) of a tracked object', () => {
54
+ const code = `
48
55
  export default component App() {
49
56
  let myTracked = track(0);
50
57
  console.log(myTracked.f);
51
58
  }
52
59
  `;
53
- expect(() => compile(code, 'test.ripple')).toThrow(/Directly accessing internal property "f" of a tracked object is not allowed/);
54
- });
60
+ expect(() => compile(code, 'test.ripple')).toThrow(
61
+ /Directly accessing internal property "f" of a tracked object is not allowed/,
62
+ );
63
+ });
55
64
 
56
- it('should compile successfully with correct @ syntax access', () => {
57
- const code = `
65
+ it('should compile successfully with correct @ syntax access', () => {
66
+ const code = `
58
67
  export default component App() {
59
68
  let count = track(0);
60
69
  console.log(@count);
61
70
  }
62
71
  `;
63
- expect(() => compile(code, 'test.ripple')).not.toThrow();
64
- });
72
+ expect(() => compile(code, 'test.ripple')).not.toThrow();
73
+ });
65
74
 
66
- it('should compile successfully with correct get() function access', () => {
67
- const code = `
75
+ it('should compile successfully with correct get() function access', () => {
76
+ const code = `
68
77
  import { get, track } from 'ripple';
69
78
  export default component App() {
70
79
  let count = track(0);
71
80
  console.log(get(count));
72
81
  }
73
82
  `;
74
- expect(() => compile(code, 'test.ripple')).not.toThrow();
75
- });
83
+ expect(() => compile(code, 'test.ripple')).not.toThrow();
84
+ });
76
85
 
77
- it('should not error on accessing __v of a non-tracked object', () => {
78
- const code = `
86
+ it('should not error on accessing __v of a non-tracked object', () => {
87
+ const code = `
79
88
  export default component App() {
80
89
  let obj = { __v: 123 };
81
90
  console.log(obj.__v);
82
91
  }
83
92
  `;
84
- expect(() => compile(code, 'test.ripple')).not.toThrow();
85
- });
93
+ expect(() => compile(code, 'test.ripple')).not.toThrow();
94
+ });
86
95
 
87
- it('should not error on accessing __v of a non-tracked object (member expression)', () => {
88
- const code = `
96
+ it('should not error on accessing __v of a non-tracked object (member expression)', () => {
97
+ const code = `
89
98
  export default component App() {
90
99
  let data = { value: { __v: 456 } };
91
100
  console.log(data.value.__v);
92
101
  }
93
102
  `;
94
- expect(() => compile(code, 'test.ripple')).not.toThrow();
95
- });
103
+ expect(() => compile(code, 'test.ripple')).not.toThrow();
104
+ });
96
105
 
97
- it('should not error on accessing a property named like an internal one on a non-tracked object', () => {
98
- const code = `
106
+ it(
107
+ 'should not error on accessing a property named like an internal one on a non-tracked object',
108
+ () => {
109
+ const code = `
99
110
  export default component App() {
100
111
  let config = { a: 'some_value', b: 'another_value' };
101
112
  console.log(config.a);
102
113
  console.log(config.b);
103
114
  }
104
115
  `;
105
- expect(() => compile(code, 'test.ripple')).not.toThrow();
106
- });
107
-
116
+ expect(() => compile(code, 'test.ripple')).not.toThrow();
117
+ },
118
+ );
108
119
  });
@@ -2,8 +2,7 @@ import { compile } from 'ripple/compiler';
2
2
 
3
3
  describe('compiler > typescript', () => {
4
4
  it('compiles TSInstantiationExpression', () => {
5
- const source =
6
- `function makeBox<T>(value: T) {
5
+ const source = `function makeBox<T,>(value: T) {
7
6
  return { value };
8
7
  }
9
8
  const makeStringBox = makeBox<string>;
@@ -28,7 +28,7 @@ describe('composite > dynamic components', () => {
28
28
 
29
29
  const obj = {
30
30
  tracked_basic,
31
- }
31
+ };
32
32
 
33
33
  <obj.@tracked_basic />
34
34
  }
@@ -49,7 +49,7 @@ describe('composite > dynamic components', () => {
49
49
 
50
50
  const obj = {
51
51
  tracked_basic,
52
- }
52
+ };
53
53
 
54
54
  const tracked_object = track(obj);
55
55
 
@@ -64,21 +64,21 @@ describe('composite > dynamic components', () => {
64
64
 
65
65
  it('handles dynamic component switching', () => {
66
66
  component Child1() {
67
- <div>{"I am child 1"}</div>
67
+ <div>{'I am child 1'}</div>
68
68
  }
69
69
 
70
70
  component Child2() {
71
- <div>{"I am child 2"}</div>
71
+ <div>{'I am child 2'}</div>
72
72
  }
73
73
 
74
74
  component App() {
75
- let thing = track(() => Child1)
75
+ let thing = track(() => Child1);
76
76
 
77
77
  <div id="container">
78
78
  <@thing />
79
79
  </div>
80
80
 
81
- <button onClick={() => @thing = @thing === Child1 ? Child2 : Child1}>{"Change Child"}</button>
81
+ <button onClick={() => @thing = @thing === Child1 ? Child2 : Child1}>{'Change Child'}</button>
82
82
  }
83
83
 
84
84
  render(App);
@@ -7,32 +7,36 @@ describe('composite > generics', () => {
7
7
 
8
8
  // 7. Generic following optional chaining
9
9
  const maybe = {
10
- factory<T>() {
10
+ factory: function <T>() {
11
11
  return {
12
- make<U>() {
12
+ make: function <U>() {
13
13
  return 1;
14
- }
14
+ },
15
15
  };
16
- }
16
+ },
17
17
  };
18
18
  const g = maybe?.factory<number>()?.make<boolean>();
19
19
 
20
20
  // 8. Comparison operator (ensure '<' here NOT misparsed as generics)
21
21
  let x = 10, y = 20;
22
- const h = x < y ? 'lt' : 'ge';
22
+ const h =
23
+ x < y ? 'lt' : 'ge';
23
24
 
24
25
  // 9. Chained comparisons with intervening generics
25
26
  class Box<T> {
26
27
  value: T;
27
- constructor(value?: T) {
28
+
29
+ constructor(value: T) {
28
30
  this.value = value;
29
31
  }
32
+
30
33
  open<U>() {
31
34
  return new Box<U>();
32
35
  }
33
36
  }
34
37
  const limit = 100;
35
- const i = new Box<number>().value < limit ? 'ok' : 'no';
38
+ const i =
39
+ new Box<number>().value < limit ? 'ok' : 'no';
36
40
 
37
41
  // 10. JSX / Element should still work
38
42
  <div class="still-works">
@@ -57,13 +61,13 @@ describe('composite > generics', () => {
57
61
  // 13. Multiple generic segments in chain
58
62
  function foo<T>() {
59
63
  return {
60
- bar<U>() {
64
+ bar: function <U>() {
61
65
  return {
62
- baz<V>() {
66
+ baz: function <V>() {
63
67
  return true;
64
- }
68
+ },
65
69
  };
66
- }
70
+ },
67
71
  };
68
72
  }
69
73
  const l = foo<number>().bar<string>().baz<boolean>();
@@ -75,9 +79,11 @@ describe('composite > generics', () => {
75
79
  // 15. Generic in angle after "new" + trailing call
76
80
  class Wrapper<T> {
77
81
  value: T;
82
+
78
83
  constructor() {
79
84
  this.value = null as unknown as T;
80
85
  }
86
+
81
87
  unwrap<U>() {
82
88
  return null as unknown as U;
83
89
  }
@@ -88,11 +94,11 @@ describe('composite > generics', () => {
88
94
  function getUnknown(): unknown {
89
95
  return new Map<string, number>([['a', 1]]);
90
96
  }
91
- getUnknown.factory = function<T>() {
97
+ getUnknown.factory = function <T>() {
92
98
  return {
93
- make<U>() {
99
+ make: function <U>() {
94
100
  return 2;
95
- }
101
+ },
96
102
  };
97
103
  };
98
104
  const raw = getUnknown();
@@ -101,14 +107,17 @@ describe('composite > generics', () => {
101
107
  // 17. Generic with comma + trailing less-than comparison on next token
102
108
  class Pair<T1, T2> {
103
109
  first: T1;
110
+
104
111
  second: T2;
112
+
105
113
  constructor() {
106
114
  this.first = null as unknown as T1;
107
115
  this.second = null as unknown as T2;
108
116
  }
109
117
  }
110
118
  const p = new Pair<number, string>();
111
- const q = 1 < 2 ? p : null;
119
+ const q =
120
+ 1 < 2 ? p : null;
112
121
 
113
122
  // 18. Nested generics with line breaks resembling JSX indentation
114
123
  interface Node<T> {
@@ -119,16 +128,15 @@ describe('composite > generics', () => {
119
128
  }
120
129
  class Graph<N, E> {
121
130
  nodes: N[];
131
+
122
132
  edges: E[];
133
+
123
134
  constructor() {
124
135
  this.nodes = [];
125
136
  this.edges = [];
126
137
  }
127
138
  }
128
- const r = new Graph<
129
- Node<string>,
130
- Edge<number>
131
- >();
139
+ const r = new Graph<Node<string>, Edge<number>>();
132
140
 
133
141
  // 19. Ternary containing generics in both branches
134
142
  let flag = true;
@@ -148,18 +156,17 @@ describe('composite > generics', () => {
148
156
  const v = make<number>()(10);
149
157
 
150
158
  // 23. Generic followed by tagged template (ensure not confused with JSX)
151
- function tagFn<T>(strings: TemplateStringsArray, ...values: T[]) {
159
+ function tagFn<T>(strings: TemplateStringsArray, ...values) {
152
160
  return values[0];
153
161
  }
154
- const tagResult = tagFn<number>`value`;
162
+ const tagResult = tagFn`value`;
155
163
 
156
164
  // 24. Sequence mixing: (a < b) + generic call in same statement
157
165
  function compute<T>(x: T, y: T): T {
158
166
  return y;
159
167
  }
160
168
 
161
- const w = (x < y) && compute<number>(x, y);
162
-
169
+ const w = x < y && compute<number>(x, y);
163
170
 
164
171
  // Additional component focusing on edge crankers
165
172
 
@@ -170,37 +177,33 @@ describe('composite > generics', () => {
170
177
  class Builder<Kind> {
171
178
  finalize<Result>() {
172
179
  return {
173
- result: null as unknown as Result
180
+ result: null as unknown as Result,
174
181
  };
175
182
  }
176
183
  }
177
184
  const builder = new Builder<Number>();
178
- const result = ((function(){ return builder; })() as Builder<Number>).finalize<boolean>();
185
+ const result = (function () {
186
+ return builder;
187
+ }() as Builder<Number>).finalize<boolean>();
179
188
 
180
189
  // 30. Angle bracket start of conditional expression line
181
190
  function adjust<T>(value: T): T {
182
191
  return value;
183
192
  }
184
193
  const val =
185
- new Wrapper<number>()
186
- .value < 100
187
- ? adjust<number>(10)
188
- : adjust<number>(20);
189
-
194
+ new Wrapper<number>().value < 100 ? adjust<number>(10) : adjust<number>(20);
190
195
 
191
196
  // 32. Generic with comments inside angle list
192
197
  class Mapper<Key, Value> {
193
198
  map: Map<Key, Value>;
199
+
194
200
  constructor() {
195
201
  this.map = new Map<Key, Value>();
196
202
  }
197
203
  }
198
- const gg = new Mapper<
199
- // key type
200
- string,
201
- /* value type */
202
- number
203
- >();
204
+ const gg = new Mapper<// key type
205
+ string, /* value type */
206
+ number>();
204
207
 
205
208
  // 33. Map of generic instance as key
206
209
  const mm = new Map<TrackedArray<number>, TrackedArray<string>>();
@@ -76,7 +76,7 @@ describe('composite > props', () => {
76
76
  it('mutating a tracked value prop should work as intended', () => {
77
77
  const logs: number[] = [];
78
78
 
79
- component Counter({count}) {
79
+ component Counter({ count }) {
80
80
  effect(() => {
81
81
  logs.push(@count);
82
82
  });
@@ -88,7 +88,7 @@ describe('composite > props', () => {
88
88
  const count = track(0);
89
89
 
90
90
  <div>
91
- <Counter count={count} />
91
+ <Counter {count} />
92
92
  </div>
93
93
  }
94
94
 
@@ -133,7 +133,8 @@ describe('composite > props', () => {
133
133
  }
134
134
 
135
135
  render(App);
136
- const button1 = container.querySelectorAll('button')[0];;
136
+ const button1 = container.querySelectorAll('button')[0];
137
+
137
138
  const button2 = container.querySelectorAll('button')[1];
138
139
 
139
140
  expect(button1.className).toContain('on');