ripple 0.2.46 → 0.2.48

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 (38) hide show
  1. package/package.json +1 -1
  2. package/src/compiler/phases/1-parse/index.js +52 -2
  3. package/src/compiler/phases/2-analyze/index.js +640 -667
  4. package/src/compiler/phases/3-transform/index.js +1878 -1879
  5. package/src/compiler/phases/3-transform/segments.js +2 -2
  6. package/src/compiler/utils.js +598 -550
  7. package/src/jsx-runtime.js +12 -12
  8. package/src/runtime/array.js +611 -609
  9. package/src/runtime/index.js +29 -17
  10. package/src/runtime/internal/client/array.js +121 -121
  11. package/src/runtime/internal/client/blocks.js +206 -206
  12. package/src/runtime/internal/client/constants.js +2 -2
  13. package/src/runtime/internal/client/context.js +40 -40
  14. package/src/runtime/internal/client/events.js +191 -191
  15. package/src/runtime/internal/client/for.js +355 -355
  16. package/src/runtime/internal/client/if.js +25 -25
  17. package/src/runtime/internal/client/index.js +57 -56
  18. package/src/runtime/internal/client/operations.js +32 -32
  19. package/src/runtime/internal/client/portal.js +19 -19
  20. package/src/runtime/internal/client/render.js +132 -132
  21. package/src/runtime/internal/client/runtime.js +839 -835
  22. package/src/runtime/internal/client/template.js +36 -36
  23. package/src/runtime/internal/client/try.js +113 -113
  24. package/src/runtime/internal/client/types.d.ts +12 -11
  25. package/src/runtime/internal/client/utils.js +5 -5
  26. package/src/runtime/map.js +139 -139
  27. package/src/runtime/set.js +130 -130
  28. package/src/utils/ast.js +189 -189
  29. package/src/utils/builders.js +244 -244
  30. package/src/utils/sanitize_template_string.js +1 -1
  31. package/tests/__snapshots__/composite.test.ripple.snap +1 -1
  32. package/tests/accessors-props.test.ripple +9 -9
  33. package/tests/basic.test.ripple +4 -4
  34. package/tests/boundaries.test.ripple +17 -17
  35. package/tests/compiler.test.ripple +14 -14
  36. package/tests/composite.test.ripple +43 -72
  37. package/tests/context.test.ripple +35 -12
  38. package/types/index.d.ts +38 -34
@@ -3,5 +3,5 @@
3
3
  * @returns {string}
4
4
  */
5
5
  export function sanitize_template_string(str) {
6
- return str.replace(/(`|\${|\\)/g, '\\$1');
6
+ return str.replace(/(`|\${|\\)/g, '\\$1');
7
7
  }
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`composite components > correct handles passing through component props and $children 1`] = `
3
+ exports[`composite components > correct handles passing through component props and children 1`] = `
4
4
  <div>
5
5
  <!---->
6
6
  <div>
@@ -71,16 +71,16 @@ describe('prop accessors', () => {
71
71
 
72
72
  component Child(props) {
73
73
  effect(() => {
74
- logs.push('App effect', props.$foo);
74
+ logs.push('App effect', props.foo);
75
75
  });
76
76
 
77
- <button onClick={() => props.$foo++}>{"Increment foo"}</button>
77
+ <button onClick={() => props.foo++}>{"Increment foo"}</button>
78
78
  }
79
79
 
80
80
  component App(props) {
81
81
  let $foo = 0;
82
82
 
83
- <Child $foo:={() => {
83
+ <Child foo:={() => {
84
84
  return $foo;
85
85
  }, v => {
86
86
  // do not update parent
@@ -103,19 +103,19 @@ describe('prop accessors', () => {
103
103
  flushSync();
104
104
 
105
105
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 0');
106
- expect(logs).toEqual(['App effect', 0, 'App effect', 1]);
106
+ expect(logs).toEqual(['App effect', 0]);
107
107
 
108
108
  button2.click();
109
109
  flushSync();
110
110
 
111
111
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 1');
112
- expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 1]);
112
+ expect(logs).toEqual(['App effect', 0, 'App effect', 1]);
113
113
 
114
114
  button2.click();
115
115
  flushSync();
116
116
 
117
117
  expect(container.querySelectorAll('div')[0].textContent).toBe('parent foo: 2');
118
- expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 1, 'App effect', 2]);
118
+ expect(logs).toEqual(['App effect', 0, 'App effect', 1, 'App effect', 2]);
119
119
  });
120
120
 
121
121
 
@@ -123,13 +123,13 @@ describe('prop accessors', () => {
123
123
  component Parent() {
124
124
  let $value = 123;
125
125
 
126
- <Child $value:={() => $value} />
126
+ <Child value:={() => $value} />
127
127
 
128
128
  <button onClick={() => $value++}>{"Increment value"}</button>
129
129
  }
130
130
 
131
- component Child({ $value }) {
132
- <div>{$value}</div>
131
+ component Child({ value }) {
132
+ <div>{value}</div>
133
133
  }
134
134
 
135
135
  render(Parent);
@@ -89,15 +89,15 @@ describe('basic', () => {
89
89
  });
90
90
 
91
91
  it('render tick template literal for nested children', () => {
92
- component Child({ $level, $children }) {
92
+ component Child({ $level, children }) {
93
93
  if($level == 1) {
94
- <h1><$children /></h1>
94
+ <h1><children /></h1>
95
95
  }
96
96
  if($level == 2) {
97
- <h2><$children /></h2>
97
+ <h2><children /></h2>
98
98
  }
99
99
  if($level == 3) {
100
- <h3><$children /></h3>
100
+ <h3><children /></h3>
101
101
  }
102
102
  }
103
103
 
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, flushSync, effect } from 'ripple';
2
+ import { mount, flushSync, effect, track } from 'ripple';
3
3
 
4
4
  describe('passing reactivity between boundaries tests', () => {
5
5
  let container;
@@ -23,23 +23,23 @@ describe('passing reactivity between boundaries tests', () => {
23
23
  it('can pass reactivity between functions with simple arrays and destructuring', () => {
24
24
  let log: string[] = [];
25
25
 
26
- function createDouble([ $count ]) {
27
- const $double = $count * 2;
26
+ function createDouble([ count ]) {
27
+ const double = track(() => @count * 2);
28
28
 
29
29
  effect(() => {
30
- log.push('Count:' + $count);
30
+ log.push('Count:' + @count);
31
31
  });
32
32
 
33
- return [ $double ];
33
+ return [ double ];
34
34
  }
35
35
 
36
36
  component App() {
37
- let $count = 0;
37
+ let count = track(0);
38
38
 
39
- const [ $double ] = createDouble([ $count ]);
39
+ const [ double ] = createDouble([ count ]);
40
40
 
41
- <div>{'Double: ' + $double}</div>
42
- <button onClick={() => { $count++; }}>{'Increment'}</button>
41
+ <div>{'Double: ' + @double}</div>
42
+ <button onClick={() => { @count++; }}>{'Increment'}</button>
43
43
  }
44
44
 
45
45
  render(App);
@@ -66,23 +66,23 @@ describe('passing reactivity between boundaries tests', () => {
66
66
  it('can pass reactivity between functions with simple objects and destructuring', () => {
67
67
  let log: string[] = [];
68
68
 
69
- function createDouble({ $count }) {
70
- const $double = $count * 2;
69
+ function createDouble({ count }) {
70
+ const double = track(() => @count * 2);
71
71
 
72
72
  effect(() => {
73
- log.push('Count:' + $count);
73
+ log.push('Count:' + @count);
74
74
  });
75
75
 
76
- return { $double };
76
+ return { double };
77
77
  }
78
78
 
79
79
  component App() {
80
- let $count = 0;
80
+ let count = track(0);
81
81
 
82
- const { $double } = createDouble({ $count });
82
+ const { double } = createDouble({ count });
83
83
 
84
- <div>{'Double: ' + $double}</div>
85
- <button onClick={() => { $count++; }}>{'Increment'}</button>
84
+ <div>{'Double: ' + @double}</div>
85
+ <button onClick={() => { @count++; }}>{'Increment'}</button>
86
86
  }
87
87
 
88
88
  render(App);
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, RippleArray } from 'ripple';
2
+ import { mount, RippleArray, track } from 'ripple';
3
3
  import { parse } from 'ripple/compiler'
4
4
 
5
5
  describe('compiler success tests', () => {
@@ -109,15 +109,15 @@ describe('compiler success tests', () => {
109
109
 
110
110
  component App() {
111
111
  let items = [];
112
- let $items = [];
112
+ let tracked_items = track([]);
113
113
  let items2 = new Array();
114
114
  let items3 = new RippleArray();
115
115
  let i = 0;
116
116
 
117
117
  logs.push(items[0]);
118
118
  logs.push(items[i]);
119
- logs.push($items[0]);
120
- logs.push($items[i]);
119
+ logs.push(@tracked_items[0]);
120
+ logs.push(@tracked_items[i]);
121
121
  logs.push(items2[0]);
122
122
  logs.push(items2[i]);
123
123
  logs.push(items3[0]);
@@ -125,8 +125,8 @@ describe('compiler success tests', () => {
125
125
 
126
126
  items[0] = 123;
127
127
  items[i] = 123;
128
- $items[0] = 123;
129
- $items[i] = 123;
128
+ @tracked_items[0] = 123;
129
+ @tracked_items[i] = 123;
130
130
  items2[0] = 123;
131
131
  items2[i] = 123;
132
132
  items3[0] = 123;
@@ -134,8 +134,8 @@ describe('compiler success tests', () => {
134
134
 
135
135
  logs.push(items[0]);
136
136
  logs.push(items[i]);
137
- logs.push($items[0]);
138
- logs.push($items[i]);
137
+ logs.push(@tracked_items[0]);
138
+ logs.push(@tracked_items[i]);
139
139
  logs.push(items2[0]);
140
140
  logs.push(items2[i]);
141
141
  logs.push(items3[0]);
@@ -143,8 +143,8 @@ describe('compiler success tests', () => {
143
143
 
144
144
  items[0]++;
145
145
  items[i]++;
146
- $items[0]++;
147
- $items[i]++;
146
+ @tracked_items[0]++;
147
+ @tracked_items[i]++;
148
148
  items2[0]++;
149
149
  items2[i]++;
150
150
  items3[0]++;
@@ -152,8 +152,8 @@ describe('compiler success tests', () => {
152
152
 
153
153
  logs.push(items[0]);
154
154
  logs.push(items[i]);
155
- logs.push($items[0]);
156
- logs.push($items[i]);
155
+ logs.push(@tracked_items[0]);
156
+ logs.push(@tracked_items[i]);
157
157
  logs.push(items2[0]);
158
158
  logs.push(items2[i]);
159
159
  logs.push(items3[0]);
@@ -161,8 +161,8 @@ describe('compiler success tests', () => {
161
161
 
162
162
  logs.push(--items[0]);
163
163
  logs.push(--items[i]);
164
- logs.push(--$items[0]);
165
- logs.push(--$items[i]);
164
+ logs.push(--@tracked_items[0]);
165
+ logs.push(--@tracked_items[i]);
166
166
  logs.push(--items2[0]);
167
167
  logs.push(--items2[i]);
168
168
  logs.push(--items3[0]);
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, flushSync } from 'ripple';
2
+ import { mount, flushSync, track } from 'ripple';
3
3
 
4
4
  describe('composite components', () => {
5
5
  let container;
@@ -21,15 +21,15 @@ describe('composite components', () => {
21
21
  });
22
22
 
23
23
  it('renders composite components', () => {
24
- component Button({ $count }) {
25
- <div>{$count}</div>
24
+ component Button({ count }) {
25
+ <div>{count}</div>
26
26
  }
27
27
 
28
28
  component App() {
29
- let $count = 0;
29
+ let count = track(0);
30
30
 
31
- <button onClick={() => $count++}>{'Increment'}</button>
32
- <Button $count={$count} />
31
+ <button onClick={() => @count++}>{'Increment'}</button>
32
+ <Button {@count} />
33
33
  }
34
34
 
35
35
  render(App);
@@ -50,48 +50,17 @@ describe('composite components', () => {
50
50
  it('renders composite components with object state', () => {
51
51
  component Button({ obj }) {
52
52
  <button class='count2' onClick={() => {
53
- obj.$count++;
54
- }}>{obj.$count}</button>
53
+ obj.@count++;
54
+ }}>{obj.@count}</button>
55
55
  }
56
56
 
57
57
  component App() {
58
58
  <div>
59
59
  let obj = {
60
- $count: 0
60
+ count: track(0)
61
61
  };
62
- let $button = true;
63
62
 
64
- <span class='count'>{obj.$count}</span>
65
- <span>{' '}</span>
66
- <Button obj={obj} />
67
- </div>
68
- }
69
-
70
- render(App);
71
-
72
- const button = container.querySelector('button');
73
-
74
- button.click();
75
- flushSync();
76
-
77
- expect(container.querySelector('.count').textContent).toBe('1');
78
- expect(container.querySelector('.count2').textContent).toBe('1');
79
- });
80
-
81
- it('renders composite components with object state', () => {
82
- component Button({ obj }) {
83
- <button class='count2' onClick={() => {
84
- obj.$count++;
85
- }}>{obj.$count}</button>
86
- }
87
-
88
- component App() {
89
- <div>
90
- let obj = {
91
- $count: 0
92
- };
93
-
94
- <span class='count'>{obj.$count}</span>
63
+ <span class='count'>{obj.@count}</span>
95
64
  <Button obj={obj} />
96
65
  </div>
97
66
  }
@@ -110,21 +79,21 @@ describe('composite components', () => {
110
79
  it('renders composite components with object state wrapped in an if statement', () => {
111
80
  component Button({ obj }) {
112
81
  <button class='count2' onClick={() => {
113
- obj.$count++;
114
- }}>{obj.$count}</button>
82
+ obj.@count++;
83
+ }}>{obj.@count}</button>
115
84
  }
116
85
 
117
86
  component OtherComponent({ obj }) {
118
- <div class='count3'>{obj.$count}</div>
87
+ <div class='count3'>{obj.@count}</div>
119
88
  }
120
89
 
121
90
  component App() {
122
91
  <div>
123
92
  let obj = {
124
- $count: 0
93
+ count: track(0)
125
94
  };
126
95
 
127
- <span class='count'>{obj.$count}</span>
96
+ <span class='count'>{obj.@count}</span>
128
97
  <span>{' '}</span>
129
98
  if (obj) {
130
99
  <Button obj={obj} />
@@ -148,17 +117,18 @@ describe('composite components', () => {
148
117
  expect(container.querySelector('.count3').textContent).toBe('1');
149
118
  });
150
119
 
151
- it('parents and children have isolated but connected state', () => {
120
+ it('parents and children have isolated state', () => {
152
121
  component Button(props) {
153
- <button onClick={() => { props.$count++; } }>{"child: " + props.$count}</button>
122
+ let count = track(() => props.count);
123
+ <button onClick={() => { @count++; } }>{"child: " + @count}</button>
154
124
  }
155
125
 
156
126
  component App() {
157
127
  <div>
158
- let $count = 0;
128
+ let count = track(0);
159
129
 
160
- <button onClick={() => { $count++; } }>{"parent: " + $count}</button>
161
- <Button {$count} />
130
+ <button onClick={() => { @count++; } }>{"parent: " + @count}</button>
131
+ <Button {@count} />
162
132
  </div>
163
133
  }
164
134
 
@@ -182,17 +152,18 @@ describe('composite components', () => {
182
152
  expect(buttons[1].textContent).toBe('child: 2');
183
153
  });
184
154
 
185
- it('parents and children have isolated but connected state (destructured props)', () => {
186
- component Button({$count}) {
187
- <button onClick={() => { $count++; } }>{"child: " + $count}</button>
155
+ it('parents and children have isolated connected state (destructured props)', () => {
156
+ component Button({count}) {
157
+ let local_count = track(() => count);
158
+ <button onClick={() => { @local_count++; } }>{"child: " + @local_count}</button>
188
159
  }
189
160
 
190
161
  component App() {
191
162
  <div>
192
- let $count = 0;
163
+ let count = track(0);
193
164
 
194
- <button onClick={() => { $count++; } }>{"parent: " + $count}</button>
195
- <Button {$count} />
165
+ <button onClick={() => { @count++; } }>{"parent: " + @count}</button>
166
+ <Button {@count} />
196
167
  </div>
197
168
  }
198
169
 
@@ -216,11 +187,11 @@ describe('composite components', () => {
216
187
  expect(buttons[1].textContent).toBe('child: 2');
217
188
  });
218
189
 
219
- it('correct handles passing through component props and $children', () => {
220
- component Button({ A, B, $children }) {
190
+ it('correct handles passing through component props and children', () => {
191
+ component Button({ A, B, children }) {
221
192
  <div>
222
193
  <A />
223
- <$children />
194
+ <children />
224
195
  <B />
225
196
  </div>
226
197
  }
@@ -243,15 +214,15 @@ describe('composite components', () => {
243
214
  });
244
215
 
245
216
  it('correctly handles default prop values', () => {
246
- component Child({ $foo = 456 }) {
247
- <div>{$foo}</div>
217
+ component Child({ foo = 456 }) {
218
+ <div>{foo}</div>
248
219
  }
249
220
 
250
221
  component App(props) {
251
- let $foo = 123;
222
+ let foo = track(123);
252
223
 
253
224
  <Child />
254
- <Child {$foo} />
225
+ <Child {@foo} />
255
226
  }
256
227
 
257
228
  render(App);
@@ -260,7 +231,7 @@ describe('composite components', () => {
260
231
  expect(container.querySelectorAll('div')[1].textContent).toBe('123');
261
232
  });
262
233
 
263
- it('correctly handles default prop values #2', () => {
234
+ it('correctly handles default prop values #2', () => {
264
235
  component Child({ foo = 456 }) {
265
236
  <div>{foo}</div>
266
237
  }
@@ -280,14 +251,14 @@ describe('composite components', () => {
280
251
 
281
252
  it('correctly handles no props', () => {
282
253
  component Child(props) {
283
- <div>{props.$foo}</div>
254
+ <div>{props.@foo}</div>
284
255
  }
285
256
 
286
257
  component App(props) {
287
- let $foo = 123;
258
+ let foo = track(123);
288
259
 
289
260
  <Child />
290
- <Child {$foo} />
261
+ <Child {foo} />
291
262
  }
292
263
 
293
264
  render(App);
@@ -297,15 +268,15 @@ describe('composite components', () => {
297
268
  });
298
269
 
299
270
  it('correctly handles no props #2', () => {
300
- component Child({ $foo }) {
301
- <div>{$foo}</div>
271
+ component Child({ foo }) {
272
+ <div>{foo}</div>
302
273
  }
303
274
 
304
275
  component App(props) {
305
- let $foo = 123;
276
+ let foo = track(123);
306
277
 
307
278
  <Child />
308
- <Child {$foo} />
279
+ <Child {@foo} />
309
280
  }
310
281
 
311
282
  render(App);
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mount, createContext } from 'ripple';
2
+ import { mount, createContext, flushSync, track } from 'ripple';
3
3
 
4
4
  describe('context', () => {
5
5
  let container;
@@ -19,25 +19,48 @@ describe('context', () => {
19
19
  document.body.removeChild(container);
20
20
  });
21
21
 
22
- it('creates a reactive ref with initial value', () => {
23
- const MyContext = createContext(null);
22
+ it('creates a reactive ref with initial value', () => {
23
+ const MyContext = createContext(null);
24
24
 
25
- component Child() {
26
- const value = MyContext.get();
25
+ component Child() {
26
+ const value = MyContext.get();
27
27
 
28
- <div>{value}</div>
29
- }
28
+ <div>{value}</div>
29
+ }
30
30
 
31
- component TestContext() {
32
- const value = MyContext.get();
31
+ component TestContext() {
32
+ const value = MyContext.get();
33
33
 
34
- MyContext.set("Hello from context!");
34
+ MyContext.set("Hello from context!");
35
35
 
36
- <Child />
37
- }
36
+ <Child />
37
+ }
38
38
 
39
39
  render(TestContext);
40
40
 
41
41
  expect(container.querySelector('div').textContent).toBe('Hello from context!');
42
42
  });
43
+
44
+ it('handles context captured inside a computed tracked', () => {
45
+
46
+ const MyContext = createContext(null)
47
+
48
+ const doubleContext = () => {
49
+ const value = MyContext.get()
50
+ return value * 2
51
+ }
52
+
53
+ component App() {
54
+ MyContext.set(4)
55
+
56
+ <h3>{MyContext.get()}</h3>
57
+
58
+ <h4>{'2x:'} {doubleContext()}</h4>
59
+
60
+ MyContext.set(8)
61
+ }
62
+
63
+ render(App);
64
+ flushSync();
65
+ });
43
66
  });
package/types/index.d.ts CHANGED
@@ -16,13 +16,13 @@ export declare class RippleArray<T> extends Array<T> {
16
16
  static from<T, U>(
17
17
  arrayLike: ArrayLike<T>,
18
18
  mapFn: (v: T, k: number) => U,
19
- thisArg?: any
19
+ thisArg?: any,
20
20
  ): RippleArray<U>;
21
21
  static from<T>(iterable: Iterable<T>): RippleArray<T>;
22
22
  static from<T, U>(
23
23
  iterable: Iterable<T>,
24
24
  mapFn: (v: T, k: number) => U,
25
- thisArg?: any
25
+ thisArg?: any,
26
26
  ): RippleArray<U>;
27
27
 
28
28
  static of<T>(...items: T[]): RippleArray<T>;
@@ -40,44 +40,48 @@ export type Context<T> = {
40
40
  export declare function createContext<T>(initialValue: T): Context<T>;
41
41
 
42
42
  export class RippleSet<T> extends Set<T> {
43
- readonly $size: number;
44
- isDisjointFrom(other: RippleSet<T> | Set<T>): boolean;
45
- isSubsetOf(other: RippleSet<T> | Set<T>): boolean;
46
- isSupersetOf(other: RippleSet<T> | Set<T>): boolean;
47
- difference(other: RippleSet<T> | Set<T>): RippleSet<T>;
48
- intersection(other: RippleSet<T> | Set<T>): RippleSet<T>;
49
- symmetricDifference(other: RippleSet<T> | Set<T>): RippleSet<T>;
50
- union(other: RippleSet<T> | Set<T>): RippleSet<T>;
51
- toJSON(): T[];
43
+ readonly $size: number;
44
+ isDisjointFrom(other: RippleSet<T> | Set<T>): boolean;
45
+ isSubsetOf(other: RippleSet<T> | Set<T>): boolean;
46
+ isSupersetOf(other: RippleSet<T> | Set<T>): boolean;
47
+ difference(other: RippleSet<T> | Set<T>): RippleSet<T>;
48
+ intersection(other: RippleSet<T> | Set<T>): RippleSet<T>;
49
+ symmetricDifference(other: RippleSet<T> | Set<T>): RippleSet<T>;
50
+ union(other: RippleSet<T> | Set<T>): RippleSet<T>;
51
+ toJSON(): T[];
52
52
  }
53
53
 
54
54
  export class RippleMap<K, V> extends Map<K, V> {
55
- get $size(): number;
56
- toJSON(): [K, V][];
55
+ get $size(): number;
56
+ toJSON(): [K, V][];
57
57
  }
58
58
 
59
59
  // Compiler-injected runtime symbols (for Ripple component development)
60
60
  declare global {
61
- /**
62
- * Runtime block context injected by the Ripple compiler.
63
- * This is automatically available in component scopes and passed to runtime functions.
64
- */
65
- var __block: any;
66
-
67
- /**
68
- * Ripple runtime namespace - injected by the compiler
69
- * These functions are available in compiled Ripple components for TypeScript analysis
70
- */
71
- var $: {
72
- tracked<T>(value: T, block?: any): T;
73
- tracked_object<T extends Record<string, any>>(obj: T, props: string[], block?: any): T;
74
- computed<T>(fn: () => T, block?: any): T;
75
- scope(): any;
76
- get_tracked(node: any): any;
77
- get_computed(node: any): any;
78
- set(node: any, value: any, block?: any): any;
79
- // Add other runtime functions as needed for TypeScript analysis
80
- };
61
+ /**
62
+ * Runtime block context injected by the Ripple compiler.
63
+ * This is automatically available in component scopes and passed to runtime functions.
64
+ */
65
+ var __block: any;
66
+
67
+ /**
68
+ * Ripple runtime namespace - injected by the compiler
69
+ * These functions are available in compiled Ripple components for TypeScript analysis
70
+ */
71
+ var $: {
72
+ tracked<T>(value: T, block?: any): T;
73
+ tracked_object<T extends Record<string, any>>(obj: T, props: string[], block?: any): T;
74
+ computed<T>(fn: () => T, block?: any): T;
75
+ scope(): any;
76
+ get_tracked(node: any): any;
77
+ get_derived(node: any): any;
78
+ set(node: any, value: any, block?: any): any;
79
+ // Add other runtime functions as needed for TypeScript analysis
80
+ };
81
81
  }
82
82
 
83
- export declare function createRefKey(): symbol;
83
+ export declare function createRefKey(): symbol;
84
+
85
+ type Tracked<V> = { '#v': V };
86
+
87
+ export declare function track<V>(value: V | (() => V)): Tracked<V>;