ripple 0.2.72 → 0.2.74
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 +3 -2
- package/src/compiler/phases/3-transform/index.js +2 -0
- package/src/runtime/index.js +1 -13
- package/src/runtime/internal/client/for.js +22 -14
- package/src/runtime/internal/client/runtime.js +61 -1
- package/tests/basic.test.ripple +127 -12
- package/tests/boundaries.test.ripple +1 -1
- package/tsconfig.json +2 -2
- package/types/index.d.ts +53 -4
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.74",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index.js",
|
|
9
9
|
"main": "src/runtime/index.js",
|
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
},
|
|
51
51
|
"imports": {
|
|
52
52
|
"#client": "./src/runtime/internal/client/types.d.ts",
|
|
53
|
-
"#client/constants": "./src/internal/client/constants.js"
|
|
53
|
+
"#client/constants": "./src/internal/client/constants.js",
|
|
54
|
+
"#public": "./types/index.d.ts"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
57
|
"@jridgewell/sourcemap-codec": "^1.5.5",
|
|
@@ -192,6 +192,8 @@ const visitors = {
|
|
|
192
192
|
|
|
193
193
|
if (!context.state.to_ts && is_ripple_track_call(callee, context)) {
|
|
194
194
|
if (node.arguments.length === 0) {
|
|
195
|
+
node.arguments.push(b.void0, b.void0);
|
|
196
|
+
} else if (node.arguments.length === 1) {
|
|
195
197
|
node.arguments.push(b.void0);
|
|
196
198
|
}
|
|
197
199
|
return {
|
package/src/runtime/index.js
CHANGED
|
@@ -36,19 +36,7 @@ export function mount(component, options) {
|
|
|
36
36
|
|
|
37
37
|
export { create_context as createContext } from './internal/client/context.js';
|
|
38
38
|
|
|
39
|
-
export { flush_sync as flushSync, untrack, deferred } from './internal/client/runtime.js';
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @param {any} v
|
|
43
|
-
* @param {Block} b
|
|
44
|
-
* @returns {Tracked | Derived}
|
|
45
|
-
*/
|
|
46
|
-
export function track(v, b) {
|
|
47
|
-
if (typeof v === 'function') {
|
|
48
|
-
return derived(v, b);
|
|
49
|
-
}
|
|
50
|
-
return tracked(v, b);
|
|
51
|
-
}
|
|
39
|
+
export { flush_sync as flushSync, track, untrack, deferred } from './internal/client/runtime.js';
|
|
52
40
|
|
|
53
41
|
export { TrackedArray } from './array.js';
|
|
54
42
|
|
|
@@ -39,10 +39,14 @@ function move(block, anchor) {
|
|
|
39
39
|
anchor.before(node);
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
while (node !==
|
|
42
|
+
while (node !== null) {
|
|
43
43
|
var next_node = /** @type {TemplateNode} */ (next_sibling(node));
|
|
44
44
|
anchor.before(node);
|
|
45
45
|
node = next_node;
|
|
46
|
+
if (node === end) {
|
|
47
|
+
anchor.before(end);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -167,6 +171,8 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
var fast_path_removal = false;
|
|
175
|
+
|
|
170
176
|
if (j > a_end) {
|
|
171
177
|
if (j <= b_end) {
|
|
172
178
|
while (j <= b_end) {
|
|
@@ -185,13 +191,14 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
185
191
|
var b_start = j;
|
|
186
192
|
var a_left = a_end - j + 1;
|
|
187
193
|
var b_left = b_end - j + 1;
|
|
188
|
-
var fast_path_removal = is_controlled && a_left === a_length;
|
|
189
194
|
var sources = new Int32Array(b_left + 1);
|
|
190
195
|
var moved = false;
|
|
191
196
|
var pos = 0;
|
|
192
197
|
var patched = 0;
|
|
193
198
|
var i = 0;
|
|
194
199
|
|
|
200
|
+
fast_path_removal = is_controlled && a_left === a_length;
|
|
201
|
+
|
|
195
202
|
// When sizes are small, just loop them through
|
|
196
203
|
if (b_length < 4 || (a_left | b_left) < 32) {
|
|
197
204
|
for (i = a_start; i <= a_end; ++i) {
|
|
@@ -244,8 +251,8 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
244
251
|
if (j !== undefined) {
|
|
245
252
|
if (fast_path_removal) {
|
|
246
253
|
fast_path_removal = false;
|
|
247
|
-
// while (i >
|
|
248
|
-
//
|
|
254
|
+
// while (i > a_start) {
|
|
255
|
+
// destroy_block(a[a_start++]);
|
|
249
256
|
// }
|
|
250
257
|
}
|
|
251
258
|
sources[j - b_start] = i + 1;
|
|
@@ -272,7 +279,7 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
|
|
|
272
279
|
|
|
273
280
|
if (fast_path_removal) {
|
|
274
281
|
reconcile_fast_clear(anchor, block, []);
|
|
275
|
-
reconcile(anchor, block, b, render_fn, is_controlled);
|
|
282
|
+
reconcile(anchor, block, b, render_fn, is_controlled, is_indexed);
|
|
276
283
|
return;
|
|
277
284
|
} else if (moved) {
|
|
278
285
|
var next_pos = 0;
|
|
@@ -385,6 +392,16 @@ export function keyed(collection, key_fn) {
|
|
|
385
392
|
if (block === null || (block.f & FOR_BLOCK) === 0) {
|
|
386
393
|
throw new Error('keyed() must be used inside a for block');
|
|
387
394
|
}
|
|
395
|
+
|
|
396
|
+
var b_array = collection_to_array(collection);
|
|
397
|
+
var b_keys = b_array.map(key_fn);
|
|
398
|
+
|
|
399
|
+
// We only need to do this in DEV
|
|
400
|
+
var b = new Set(b_keys);
|
|
401
|
+
if (b.size !== b_keys.length) {
|
|
402
|
+
throw new Error('Duplicate keys are not allowed');
|
|
403
|
+
}
|
|
404
|
+
|
|
388
405
|
var state = block.s;
|
|
389
406
|
|
|
390
407
|
if (state === null) {
|
|
@@ -403,15 +420,6 @@ export function keyed(collection, key_fn) {
|
|
|
403
420
|
throw new Error('Duplicate keys are not allowed');
|
|
404
421
|
}
|
|
405
422
|
|
|
406
|
-
var b_array = collection_to_array(collection);
|
|
407
|
-
var b_keys = b_array.map(key_fn);
|
|
408
|
-
|
|
409
|
-
// We only need to do this in DEV
|
|
410
|
-
var b = new Set(b_keys);
|
|
411
|
-
if (b.size !== b_keys.length) {
|
|
412
|
-
throw new Error('Duplicate keys are not allowed');
|
|
413
|
-
}
|
|
414
|
-
|
|
415
423
|
for (let i = 0; i < b_keys.length; i++) {
|
|
416
424
|
var b_val = b_keys[i];
|
|
417
425
|
var index = a.get(b_val);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** @import { Block, Component, Dependency, Derived, Tracked } from '#client' */
|
|
2
|
+
/** @import { TrackOptions } from '#public' */
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
destroy_block,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
REF_PROP,
|
|
27
28
|
} from './constants.js';
|
|
28
29
|
import { capture, suspend } from './try.js';
|
|
29
|
-
import { define_property, is_tracked_object } from './utils.js';
|
|
30
|
+
import { define_property, get_descriptors, is_array, is_tracked_object } from './utils.js';
|
|
30
31
|
|
|
31
32
|
const FLUSH_MICROTASK = 0;
|
|
32
33
|
const FLUSH_SYNC = 1;
|
|
@@ -278,6 +279,65 @@ export function derived(fn, block) {
|
|
|
278
279
|
};
|
|
279
280
|
}
|
|
280
281
|
|
|
282
|
+
/**
|
|
283
|
+
* @param {any} v
|
|
284
|
+
* @param {TrackOptions | undefined} o
|
|
285
|
+
* @param {Block} b
|
|
286
|
+
* @returns {Tracked | Derived | Tracked[]}
|
|
287
|
+
*/
|
|
288
|
+
export function track(v, o, b) {
|
|
289
|
+
var is_tracked = is_tracked_object(v);
|
|
290
|
+
|
|
291
|
+
if (o === undefined) {
|
|
292
|
+
if (is_tracked) {
|
|
293
|
+
return v;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (typeof v === 'function') {
|
|
297
|
+
return derived(v, b);
|
|
298
|
+
}
|
|
299
|
+
return tracked(v, b);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (is_tracked || typeof v !== "object" || v === null || is_array(v)) {
|
|
303
|
+
throw new TypeError('Invalid value: expected a non-tracked object');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
var list = o.split ?? [];
|
|
307
|
+
/** @type {Tracked[]} */
|
|
308
|
+
var out = [];
|
|
309
|
+
/** @type {Record<string|symbol, any>} */
|
|
310
|
+
var rest = {};
|
|
311
|
+
/** @type {Record<PropertyKey, any | null>} */
|
|
312
|
+
var descriptors = get_descriptors(v);
|
|
313
|
+
|
|
314
|
+
for (let i = 0, key, t; i < list.length; i++) {
|
|
315
|
+
key = list[i];
|
|
316
|
+
|
|
317
|
+
if (is_tracked_object(v[key])) {
|
|
318
|
+
t = v[key];
|
|
319
|
+
} else {
|
|
320
|
+
t = define_property(tracked(undefined, b), 'v', descriptors[key]);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
out[i] = t;
|
|
324
|
+
descriptors[key] = null;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
var props = Reflect.ownKeys(descriptors);
|
|
328
|
+
for (let i = 0, key; i < props.length; i++) {
|
|
329
|
+
key = props[i];
|
|
330
|
+
if (descriptors[key] === null) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
define_property(rest, key, descriptors[key]);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
out.push(tracked(rest, b));
|
|
337
|
+
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
|
|
281
341
|
/**
|
|
282
342
|
* @param {Tracked} tracked
|
|
283
343
|
* @returns {Dependency}
|
package/tests/basic.test.ripple
CHANGED
|
@@ -474,13 +474,13 @@ describe('basic', () => {
|
|
|
474
474
|
component Basic() {
|
|
475
475
|
let count = track(0);
|
|
476
476
|
|
|
477
|
-
const minus = {
|
|
477
|
+
const minus = {
|
|
478
478
|
onClick() {
|
|
479
479
|
@count--
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
482
|
|
|
483
|
-
const plus = {
|
|
483
|
+
const plus = {
|
|
484
484
|
onClick() {
|
|
485
485
|
@count++
|
|
486
486
|
}
|
|
@@ -524,7 +524,7 @@ describe('basic', () => {
|
|
|
524
524
|
let clickCount = track(0);
|
|
525
525
|
let focusCount = track(0);
|
|
526
526
|
|
|
527
|
-
const mixedHandler = {
|
|
527
|
+
const mixedHandler = {
|
|
528
528
|
onClick() { // Delegated event
|
|
529
529
|
@clickCount++
|
|
530
530
|
},
|
|
@@ -980,7 +980,7 @@ describe('basic', () => {
|
|
|
980
980
|
div {
|
|
981
981
|
animation-name: anim;
|
|
982
982
|
}
|
|
983
|
-
|
|
983
|
+
|
|
984
984
|
@keyframes anim {}
|
|
985
985
|
|
|
986
986
|
p {
|
|
@@ -1272,18 +1272,133 @@ describe('basic', () => {
|
|
|
1272
1272
|
expect(container).toMatchSnapshot();
|
|
1273
1273
|
});
|
|
1274
1274
|
|
|
1275
|
-
it('
|
|
1275
|
+
it('can retain reactivity for destructure rest via track split', () => {
|
|
1276
|
+
let logs = [];
|
|
1277
|
+
|
|
1276
1278
|
component App() {
|
|
1277
|
-
let
|
|
1278
|
-
let
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1279
|
+
let count = track(0);
|
|
1280
|
+
let name = track('Click Me');
|
|
1281
|
+
|
|
1282
|
+
function buttonRef(el) {
|
|
1283
|
+
logs.push('ref called');
|
|
1284
|
+
return () => {
|
|
1285
|
+
logs.push('cleanup ref');
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
<Child
|
|
1290
|
+
class="my-button"
|
|
1291
|
+
onClick={() => @name === 'Click Me' ? @name = 'Clicked' : @name = 'Click Me'}
|
|
1292
|
+
count:={() => @count, (v) => {logs.push('inside setter'); @count++}}
|
|
1293
|
+
{ref buttonRef}
|
|
1294
|
+
>{@name}</Child>;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
component Child(props: PropsWithChildren<{ count: Tracked<number> }>) {
|
|
1298
|
+
const [children, count, rest] = track(props, {split: ['children', 'count']});
|
|
1299
|
+
|
|
1300
|
+
if (@count < 2) {
|
|
1301
|
+
<button {...@rest}><@children /></button>
|
|
1302
|
+
}
|
|
1303
|
+
<pre>{@count}</pre>
|
|
1304
|
+
<button onClick={() => @count++}>{'Increment Count'}</button>
|
|
1283
1305
|
}
|
|
1284
1306
|
|
|
1285
1307
|
render(App);
|
|
1308
|
+
flushSync();
|
|
1286
1309
|
|
|
1287
|
-
|
|
1310
|
+
const buttonClickMe = container.querySelectorAll('button')[0];
|
|
1311
|
+
const buttonIncrement = container.querySelectorAll('button')[1];
|
|
1312
|
+
const countPre = container.querySelector('pre');
|
|
1313
|
+
|
|
1314
|
+
expect(buttonClickMe.textContent).toBe('Click Me');
|
|
1315
|
+
expect(countPre.textContent).toBe('0');
|
|
1316
|
+
expect(logs).toEqual(['ref called']);
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
buttonClickMe.click();
|
|
1320
|
+
buttonIncrement.click();
|
|
1321
|
+
flushSync();
|
|
1322
|
+
|
|
1323
|
+
expect(buttonClickMe.textContent).toBe('Clicked');
|
|
1324
|
+
expect(countPre.textContent).toBe('1');
|
|
1325
|
+
expect(logs).toEqual(['ref called','inside setter']);
|
|
1326
|
+
|
|
1327
|
+
buttonIncrement.click();
|
|
1328
|
+
flushSync();
|
|
1329
|
+
|
|
1330
|
+
expect(logs).toEqual(['ref called','inside setter','inside setter','cleanup ref']);
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
it('errors on invalid value as null for track with split', () => {
|
|
1334
|
+
component App() {
|
|
1335
|
+
let message = track('');
|
|
1336
|
+
|
|
1337
|
+
try{
|
|
1338
|
+
const [a, b, rest] = track(null, { split: ['a', 'b'] });
|
|
1339
|
+
} catch(e) {
|
|
1340
|
+
@message = e.message;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
<pre>{@message}</pre>
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
render(App);
|
|
1347
|
+
|
|
1348
|
+
const pre = container.querySelectorAll('pre')[0];
|
|
1349
|
+
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
it('errors on invalid value as array for track with split', () => {
|
|
1353
|
+
component App() {
|
|
1354
|
+
let message = track('');
|
|
1355
|
+
|
|
1356
|
+
try{
|
|
1357
|
+
const [a, b, rest] = track([1, 2, 3], { split: ['a', 'b'] });
|
|
1358
|
+
} catch(e) {
|
|
1359
|
+
@message = e.message;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
<pre>{@message}</pre>
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
render(App);
|
|
1366
|
+
|
|
1367
|
+
const pre = container.querySelectorAll('pre')[0];
|
|
1368
|
+
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1371
|
+
it('errors on invalid value as tracked for track with split', () => {
|
|
1372
|
+
component App() {
|
|
1373
|
+
const t = track({a: 1, b: 2, c: 3});
|
|
1374
|
+
let message = track('');
|
|
1375
|
+
|
|
1376
|
+
try{
|
|
1377
|
+
const [a, b, rest] = track(t, { split: ['a', 'b'] });
|
|
1378
|
+
} catch(e) {
|
|
1379
|
+
@message = e.message;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
<pre>{@message}</pre>
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
render(App);
|
|
1386
|
+
|
|
1387
|
+
const pre = container.querySelectorAll('pre')[0];
|
|
1388
|
+
expect(pre.textContent).toBe('Invalid value: expected a non-tracked object');
|
|
1389
|
+
});
|
|
1390
|
+
|
|
1391
|
+
it('returns the same tracked object if plain track is called with a tracked object', () => {
|
|
1392
|
+
component App() {
|
|
1393
|
+
const t = track({a: 1, b: 2, c: 3});
|
|
1394
|
+
const doublet = track(t);
|
|
1395
|
+
|
|
1396
|
+
<pre>{t === doublet}</pre>
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
render(App);
|
|
1400
|
+
|
|
1401
|
+
const pre = container.querySelectorAll('pre')[0];
|
|
1402
|
+
expect(pre.textContent).toBe('true');
|
|
1288
1403
|
});
|
|
1289
1404
|
});
|
package/tsconfig.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"allowSyntheticDefaultImports": true,
|
|
12
12
|
"verbatimModuleSyntax": true,
|
|
13
13
|
"types": ["node"],
|
|
14
|
-
|
|
14
|
+
"jsx": "preserve",
|
|
15
15
|
"jsxImportSource": "ripple",
|
|
16
16
|
"strict": true,
|
|
17
17
|
"allowJs": true,
|
|
@@ -25,4 +25,4 @@
|
|
|
25
25
|
"./src/",
|
|
26
26
|
"./tests/*/test.ripple",
|
|
27
27
|
]
|
|
28
|
-
}
|
|
28
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type Context<T> = {
|
|
|
29
29
|
|
|
30
30
|
export declare function createContext<T>(initialValue: T): Context<T>;
|
|
31
31
|
|
|
32
|
-
export class TrackedSet<T> extends Set<T> {
|
|
32
|
+
export declare class TrackedSet<T> extends Set<T> {
|
|
33
33
|
isDisjointFrom(other: TrackedSet<T> | Set<T>): boolean;
|
|
34
34
|
isSubsetOf(other: TrackedSet<T> | Set<T>): boolean;
|
|
35
35
|
isSupersetOf(other: TrackedSet<T> | Set<T>): boolean;
|
|
@@ -40,7 +40,7 @@ export class TrackedSet<T> extends Set<T> {
|
|
|
40
40
|
toJSON(): T[];
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export class TrackedMap<K, V> extends Map<K, V> {
|
|
43
|
+
export declare class TrackedMap<K, V> extends Map<K, V> {
|
|
44
44
|
toJSON(): [K, V][];
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -56,7 +56,7 @@ declare global {
|
|
|
56
56
|
* Ripple runtime namespace - injected by the compiler
|
|
57
57
|
* These functions are available in compiled Ripple components for TypeScript analysis
|
|
58
58
|
*/
|
|
59
|
-
var
|
|
59
|
+
var _$_: {
|
|
60
60
|
tracked<T>(value: T, block?: any): T;
|
|
61
61
|
computed<T>(fn: () => T, block?: any): T;
|
|
62
62
|
scope(): any;
|
|
@@ -69,10 +69,35 @@ declare global {
|
|
|
69
69
|
|
|
70
70
|
export declare function createRefKey(): symbol;
|
|
71
71
|
|
|
72
|
-
type Tracked<V> = { '#v': V };
|
|
72
|
+
export type Tracked<V> = { '#v': V };
|
|
73
|
+
|
|
74
|
+
export type Props<K extends PropertyKey = any, V = unknown> = Record<K, V>;
|
|
75
|
+
export type PropsWithExtras<T extends object> = Props & T & Record<string, unknown>;
|
|
76
|
+
export type PropsWithChildren<T extends object = {}> =
|
|
77
|
+
Expand<Omit<Props, 'children'> & { children: Component } & T>;
|
|
78
|
+
|
|
79
|
+
type UnwrapTracked<T> = [T] extends [Tracked<infer V>] ? T : Tracked<T>;
|
|
80
|
+
|
|
81
|
+
// force ts to evaluate and expand a type fully
|
|
82
|
+
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
83
|
+
|
|
84
|
+
type PickKeys<T, K extends readonly (keyof T)[]> =
|
|
85
|
+
{ [I in keyof K]: UnwrapTracked<T[K[I] & keyof T]> };
|
|
86
|
+
|
|
87
|
+
type RestKeys<T, K extends readonly (keyof T)[]> = Expand<Omit<T, K[number]>>;
|
|
88
|
+
|
|
89
|
+
type SplitResult<T extends Props, K extends readonly (keyof T)[]> =
|
|
90
|
+
[...PickKeys<T, K>, UnwrapTracked<RestKeys<T, K>>];
|
|
91
|
+
|
|
92
|
+
type TrackOptions = { split?: readonly (string | number | symbol)[] };
|
|
73
93
|
|
|
74
94
|
export declare function track<V>(value?: V | (() => V)): Tracked<V>;
|
|
75
95
|
|
|
96
|
+
export declare function track<V extends Props, const K extends readonly (keyof V)[]>(
|
|
97
|
+
value: V,
|
|
98
|
+
options: TrackOptions
|
|
99
|
+
): SplitResult<V, K>;
|
|
100
|
+
|
|
76
101
|
export function on<Type extends keyof WindowEventMap>(
|
|
77
102
|
window: Window,
|
|
78
103
|
type: Type,
|
|
@@ -107,3 +132,27 @@ export function on(
|
|
|
107
132
|
handler: EventListener,
|
|
108
133
|
options?: AddEventListenerOptions | undefined
|
|
109
134
|
): () => void;
|
|
135
|
+
|
|
136
|
+
export type TrackedObjectShallow<T> = {
|
|
137
|
+
[K in keyof T]: T[K] | Tracked<T[K]>;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export type TrackedObjectDeep<T> =
|
|
141
|
+
T extends string | number | boolean | null | undefined | symbol | bigint
|
|
142
|
+
? T | Tracked<T>
|
|
143
|
+
: T extends TrackedArray<infer U>
|
|
144
|
+
? TrackedArray<U> | Tracked<TrackedArray<U>>
|
|
145
|
+
: T extends TrackedSet<infer U>
|
|
146
|
+
? TrackedSet<U> | Tracked<TrackedSet<U>>
|
|
147
|
+
: T extends TrackedMap<infer K, infer V>
|
|
148
|
+
? TrackedMap<K, V> | Tracked<TrackedMap<K, V>>
|
|
149
|
+
: T extends Array<infer U>
|
|
150
|
+
? Array<TrackedObjectDeep<U>> | Tracked<Array<TrackedObjectDeep<U>>>
|
|
151
|
+
: T extends Set<infer U>
|
|
152
|
+
? Set<TrackedObjectDeep<U>> | Tracked<Set<TrackedObjectDeep<U>>>
|
|
153
|
+
: T extends Map<infer K, infer V>
|
|
154
|
+
? Map<TrackedObjectDeep<K>, TrackedObjectDeep<V>> |
|
|
155
|
+
Tracked<Map<TrackedObjectDeep<K>, TrackedObjectDeep<V>>>
|
|
156
|
+
: T extends object
|
|
157
|
+
? { [K in keyof T]: TrackedObjectDeep<T[K]> | Tracked<TrackedObjectDeep<T[K]>> }
|
|
158
|
+
: T | Tracked<T>;
|