@esportsplus/reactivity 0.39.2 → 0.41.0

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/README.md +12 -6
  2. package/bench/compiler.bench.ts +115 -0
  3. package/bench/kairo.bench.ts +1 -1
  4. package/bench/reactive/array.bench.ts +1 -0
  5. package/bench/reactive/reactive-object.bench.ts +3 -2
  6. package/build/compiler/array.js +28 -25
  7. package/build/compiler/bindings.d.ts +3 -1
  8. package/build/compiler/bindings.js +32 -9
  9. package/build/compiler/index.d.ts +3 -2
  10. package/build/compiler/index.js +21 -13
  11. package/build/compiler/object.js +12 -13
  12. package/build/compiler/plugins/vite.d.ts +13 -4
  13. package/build/compiler/primitives.js +9 -9
  14. package/build/constants.d.ts +2 -1
  15. package/build/constants.js +2 -1
  16. package/build/index.d.ts +1 -0
  17. package/build/reactive/array.d.ts +40 -1
  18. package/build/reactive/array.js +82 -16
  19. package/build/reactive/index.d.ts +1 -1
  20. package/build/reactive/object.d.ts +3 -3
  21. package/build/reactive/object.js +1 -1
  22. package/build/system.d.ts +3 -2
  23. package/build/system.js +10 -5
  24. package/oxlintrc.json +3 -0
  25. package/package.json +15 -7
  26. package/pnpm-workspace.yaml +4 -7
  27. package/src/compiler/array.ts +30 -27
  28. package/src/compiler/bindings.ts +49 -10
  29. package/src/compiler/index.ts +37 -20
  30. package/src/compiler/object.ts +14 -16
  31. package/src/compiler/primitives.ts +13 -10
  32. package/src/constants.ts +4 -1
  33. package/src/index.ts +1 -0
  34. package/src/reactive/array.ts +133 -22
  35. package/src/reactive/index.ts +3 -3
  36. package/src/reactive/object.ts +4 -4
  37. package/src/system.ts +20 -5
  38. package/test/compiler/__snapshots__/output.test.ts.snap +157 -0
  39. package/test/compiler/compiler.test.ts +51 -9
  40. package/test/compiler/composition.test.ts +110 -0
  41. package/test/compiler/coverage.test.ts +22 -22
  42. package/test/compiler/origins.test.ts +156 -0
  43. package/test/compiler/output.test.ts +116 -0
  44. package/test/ownership.test.ts +100 -1
  45. package/test/reactive/array.test.ts +189 -8
  46. package/test/reactive/reactive.test.ts +4 -4
  47. package/test/system.test.ts +3 -4
  48. package/test/untrack.test.ts +1 -1
  49. package/tsconfig.build.json +3 -0
  50. package/tsconfig.json +2 -2
  51. package/vitest.config.ts +2 -2
  52. package/bench/tsconfig.json +0 -16
  53. package/test/tsconfig.json +0 -16
@@ -0,0 +1,116 @@
1
+ import { afterEach, describe, expect, it } from 'vitest';
2
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+
5
+ import vite from '~/compiler/plugins/vite';
6
+
7
+
8
+ // Whole compiled modules, pinned byte for byte: every lowering form the compiler emits, each one
9
+ // alone in its range so no output depends on how nested rewrites compose
10
+ const FILES: Record<string, string> = {
11
+ 'app.ts': [
12
+ "export { reactive as make } from '@esportsplus/reactivity';",
13
+ "export * from './state';",
14
+ "export { default as total } from './state';"
15
+ ].join('\n'),
16
+ 'consumer.ts': [
17
+ "import { count as renamed, later, make, total } from './app';",
18
+ "import * as app from './app';",
19
+ 'export let a = make(0);',
20
+ 'export let b = () => renamed + total + later;',
21
+ 'export let c = () => app.count + app.list.length;',
22
+ "export let d = () => app['count'];",
23
+ 'export let e = () => { app.list[0] = 1; };'
24
+ ].join('\n'),
25
+ 'forms.ts': [
26
+ "import { reactive } from '@esportsplus/reactivity';",
27
+ 'declare function total(): number;',
28
+ 'declare let list: number[];',
29
+ 'declare let n: number;',
30
+ 'let count = reactive(0);',
31
+ 'let doubled = reactive(() => count * 2);',
32
+ 'let typed = reactive(n);',
33
+ 'let fn = reactive(total);',
34
+ 'let runtime = reactive(list);',
35
+ 'let obj = reactive({ a: 1, b: \'x\', items: [1, 2], sum: () => 3, neg: -1, source: list, flag: true });',
36
+ 'let shorthand = reactive({ list });',
37
+ 'let hinted = reactive<{ a: number; items: number[] }>({ a: 1, items: [] });',
38
+ 'let spread = reactive({ ...{ a: 1 }, b: 2 });',
39
+ 'let method = reactive({ m() { return 1; } });',
40
+ 'let arr = reactive([1, 2, 3]);',
41
+ 'let empty = reactive([] as string[]);',
42
+ 'let declared: number[] = reactive([4]);',
43
+ 'count = 5;',
44
+ 'count += 2;',
45
+ 'count ||= 3;',
46
+ 'count++;',
47
+ '--count;',
48
+ 'let p = count++;',
49
+ 'let q = ++count;',
50
+ 'let o = { count };',
51
+ 'let t = typeof count;',
52
+ 'arr[0] = 4;',
53
+ 'arr[1] += 2;',
54
+ 'arr[2]++;',
55
+ 'let r = ++arr[0];',
56
+ 'let size = arr.length;',
57
+ 'arr.length = 1;',
58
+ 'arr.length += 1;',
59
+ 'arr.length++;',
60
+ 'arr = [5, 6];',
61
+ 'arr = [];',
62
+ 'export { count, doubled, typed, fn, runtime, obj, shorthand, hinted, spread, method, empty, declared, p, q, o, t, r, size };',
63
+ 'export default reactive(0);'
64
+ ].join('\n'),
65
+ 'state.ts': [
66
+ "import { reactive } from '@esportsplus/reactivity';",
67
+ 'export let count = reactive(0);',
68
+ 'export let list = reactive([1, 2]);',
69
+ 'export let later: number;',
70
+ 'later = reactive(1);',
71
+ 'export default reactive(() => 2);'
72
+ ].join('\n')
73
+ };
74
+
75
+
76
+ let fixtures: string[] = [];
77
+
78
+
79
+ function compile(name: string): string | null {
80
+ let directory = mkdtempSync(join(process.cwd(), '.fixture-output-')).replace(/\\/g, '/');
81
+
82
+ fixtures.push(directory);
83
+
84
+ for (let [file, code] of Object.entries(FILES)) {
85
+ writeFileSync(join(directory, file), code);
86
+ }
87
+
88
+ writeFileSync(join(directory, 'tsconfig.json'), JSON.stringify({
89
+ compilerOptions: { module: 'esnext', moduleResolution: 'bundler', strict: true, target: 'esnext', types: [] },
90
+ files: Object.keys(FILES).map(file => './' + file)
91
+ }));
92
+
93
+ let plugin = vite({ root: directory });
94
+
95
+ plugin.configResolved({ command: 'build', root: directory });
96
+
97
+ return plugin.transform.handler(FILES[name], directory + '/' + name)?.code ?? null;
98
+ }
99
+
100
+
101
+ afterEach(() => {
102
+ for (let i = 0, n = fixtures.length; i < n; i++) {
103
+ rmSync(fixtures[i], { force: true, recursive: true });
104
+ }
105
+
106
+ fixtures = [];
107
+ });
108
+
109
+
110
+ describe('compiled output', () => {
111
+ for (let name of Object.keys(FILES)) {
112
+ it(name, () => {
113
+ expect(compile(name)).toMatchSnapshot();
114
+ });
115
+ }
116
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { computed, dispose, effect, flush, hasOwner, onCleanup, read, root, signal, untrack, write } from '~/system';
2
+ import { computed, owner as current, dispose, effect, flush, hasOwner, onCleanup, read, root, signal, untrack, write } from '~/system';
3
3
  import type { Computed } from '~/system';
4
4
  import { captureUncaught } from './lib/uncaught';
5
5
 
@@ -584,3 +584,102 @@ describe('hasOwner', () => {
584
584
  });
585
585
  });
586
586
 
587
+ describe('owner', () => {
588
+ it('is the running computation, else the running root scope, else null', () => {
589
+ let running: Computed<unknown> | null = null,
590
+ scope: Computed<unknown> | null = null,
591
+ seen: unknown[] = [];
592
+
593
+ seen.push(current());
594
+
595
+ let stop = root((dispose) => {
596
+ scope = current();
597
+
598
+ effect(() => {
599
+ running = current();
600
+ seen.push(untrack(() => current()) === running);
601
+ });
602
+
603
+ return dispose;
604
+ });
605
+
606
+ seen.push(current());
607
+
608
+ expect(scope).not.toBeNull();
609
+ expect(running).not.toBe(scope);
610
+ // An effect is owned once its first run returns
611
+ expect(running!.owner).toBe(scope);
612
+
613
+ stop();
614
+
615
+ expect(seen).toEqual([null, true, null]);
616
+ });
617
+ });
618
+
619
+ describe('root with an owner', () => {
620
+ it('runs fn owned by the given node, its reads untracked', async () => {
621
+ let cleaned = 0,
622
+ s = signal(0),
623
+ node: Computed<unknown> | null = null,
624
+ runs = 0,
625
+ stop = root((dispose) => {
626
+ node = current();
627
+
628
+ return dispose;
629
+ });
630
+
631
+ root(() => {
632
+ runs++;
633
+ read(s);
634
+ onCleanup(() => cleaned++);
635
+ effect(() => { read(s); });
636
+ }, node);
637
+
638
+ expect(hasOwner()).toBe(false);
639
+ expect(registrations(node!)).toBe(2);
640
+
641
+ write(s, 1);
642
+ await Promise.resolve();
643
+
644
+ expect(runs).toBe(1);
645
+
646
+ stop();
647
+
648
+ expect(cleaned).toBe(1);
649
+ expect(registrations(node!)).toBe(0);
650
+ });
651
+
652
+ it('creates a child root of the given node instead of whatever is running', () => {
653
+ let a: Computed<unknown> | null = null,
654
+ b: Computed<unknown> | null = null,
655
+ child: Computed<unknown> | null = null,
656
+ stopA = root((dispose) => { a = current(); return dispose; }),
657
+ stopB = root((dispose) => { b = current(); return dispose; });
658
+
659
+ root(() => {
660
+ root((dispose) => {
661
+ child = current();
662
+
663
+ return dispose;
664
+ }, a);
665
+ }, b);
666
+
667
+ expect(child!.owner).toBe(a);
668
+ expect(registrations(b!)).toBe(0);
669
+
670
+ stopA();
671
+
672
+ expect(child!.owner).toBe(null);
673
+
674
+ stopB();
675
+ });
676
+
677
+ it('throws on a disposed owner', () => {
678
+ let node: Computed<unknown> | null = null,
679
+ stop = root((dispose) => { node = current(); return dispose; });
680
+
681
+ stop();
682
+
683
+ expect(() => root(() => {}, node)).toThrow('@esportsplus/reactivity: root() was given a disposed owner');
684
+ });
685
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
- import { effect, read, signal, write } from '~/system';
2
+ import { effect, flush, owner, read, root, signal, write } from '~/system';
3
3
  import { ReactiveArray } from '~/reactive/array';
4
4
  import { ReactiveObject } from '~/reactive/object';
5
5
  import reactive from '~/reactive/index';
@@ -54,7 +54,7 @@ describe('ReactiveArray', () => {
54
54
  });
55
55
 
56
56
  it('does not overflow the stack for a large array', () => {
57
- let arr = new ReactiveArray(new Array(500000).fill(0));
57
+ let arr = new ReactiveArray(Array.from({ length: 500000 }, () => 0));
58
58
 
59
59
  expect(arr.length).toBe(500000);
60
60
  expect(arr.$length).toBe(500000);
@@ -463,7 +463,7 @@ describe('ReactiveArray', () => {
463
463
  arr.on('splice', (e) => { events.push(e); });
464
464
  arr.splice(1, 1, 20, 30);
465
465
 
466
- expect(events).toEqual([{ start: 1, deleteCount: 1, items: [20, 30] }]);
466
+ expect(events).toEqual([{ deleteCount: 1, items: [20, 30], start: 1 }]);
467
467
  });
468
468
 
469
469
  it('no event when nothing changes', () => {
@@ -499,7 +499,7 @@ describe('ReactiveArray', () => {
499
499
 
500
500
  expect([...removed]).toEqual([4]);
501
501
  expect([...arr]).toEqual([1, 2, 3, 5]);
502
- expect(events).toEqual([{ start: 3, deleteCount: 1, items: [] }]);
502
+ expect(events).toEqual([{ deleteCount: 1, items: [], start: 3 }]);
503
503
  });
504
504
 
505
505
  it('splice dispatches the count actually removed, not the requested count', () => {
@@ -510,7 +510,7 @@ describe('ReactiveArray', () => {
510
510
  arr.splice(1, 100);
511
511
 
512
512
  expect([...arr]).toEqual([1]);
513
- expect(events).toEqual([{ start: 1, deleteCount: 2, items: [] }]);
513
+ expect(events).toEqual([{ deleteCount: 2, items: [], start: 1 }]);
514
514
  });
515
515
 
516
516
  it('splice clamps an out-of-range or fractional start the way Array.prototype.splice does', () => {
@@ -524,9 +524,9 @@ describe('ReactiveArray', () => {
524
524
 
525
525
  expect([...arr]).toEqual([0, 9, 1, 2, 3, 4]);
526
526
  expect(events).toEqual([
527
- { start: 3, deleteCount: 0, items: [4] },
528
- { start: 0, deleteCount: 0, items: [0] },
529
- { start: 1, deleteCount: 0, items: [9] }
527
+ { deleteCount: 0, items: [4], start: 3 },
528
+ { deleteCount: 0, items: [0], start: 0 },
529
+ { deleteCount: 0, items: [9], start: 1 }
530
530
  ]);
531
531
  });
532
532
  });
@@ -652,6 +652,7 @@ describe('ReactiveArray', () => {
652
652
  arr.sort((a, b) => a - b);
653
653
 
654
654
  expect([...arr]).toEqual([1, 2, 2]);
655
+ expect(order).toEqual([1, 0, 2]);
655
656
  });
656
657
 
657
658
  it('order maps duplicate values stably (first stays first)', () => {
@@ -1226,3 +1227,183 @@ describe('ReactiveArray', () => {
1226
1227
  });
1227
1228
  });
1228
1229
  });
1230
+
1231
+ describe('ReactiveArray batch', () => {
1232
+ // Disposed links go back to a shared pool; a node disposed mid-run then walks pooled links
1233
+ let pool = () => {
1234
+ let a = signal(0),
1235
+ b = signal(0),
1236
+ c = signal(0);
1237
+
1238
+ root(() => effect(() => read(a) + read(b) + read(c)))();
1239
+ };
1240
+
1241
+ it('delivers every mutation of a task once, in order, in the pass that follows', async () => {
1242
+ let arr = new ReactiveArray([1, 2, 3]),
1243
+ batches: unknown[][] = [];
1244
+
1245
+ arr.on('batch', (ops) => batches.push(ops));
1246
+ arr.push(4);
1247
+ arr.$set(0, 9);
1248
+ arr.splice(1, 1, 7, 8);
1249
+ arr.pop();
1250
+
1251
+ expect(batches).toEqual([]);
1252
+
1253
+ await Promise.resolve();
1254
+
1255
+ expect(batches).toEqual([[
1256
+ { items: [4], op: 'push' },
1257
+ { index: 0, item: 9, op: 'set' },
1258
+ { deleteCount: 1, items: [7, 8], op: 'splice', start: 1 },
1259
+ { item: 4, op: 'pop' }
1260
+ ]]);
1261
+ });
1262
+
1263
+ it('settles through flush()', () => {
1264
+ let arr = new ReactiveArray<number>(),
1265
+ batches: unknown[][] = [];
1266
+
1267
+ arr.on('batch', (ops) => batches.push(ops));
1268
+ arr.push(1, 2);
1269
+ flush();
1270
+
1271
+ expect(batches).toEqual([[{ items: [1, 2], op: 'push' }]]);
1272
+ });
1273
+
1274
+ it('drops the mutations before a clear', () => {
1275
+ let arr = new ReactiveArray([1]),
1276
+ batches: unknown[][] = [];
1277
+
1278
+ arr.on('batch', (ops) => batches.push(ops));
1279
+ arr.push(2);
1280
+ arr.clear();
1281
+ arr.unshift(5);
1282
+ flush();
1283
+
1284
+ expect(batches).toEqual([[{ op: 'clear' }, { items: [5], op: 'unshift' }]]);
1285
+ });
1286
+
1287
+ it('reports the order of a sort, and reverse, shift and concat', () => {
1288
+ let arr = new ReactiveArray([3, 1, 2]),
1289
+ batches: unknown[][] = [];
1290
+
1291
+ arr.on('batch', (ops) => batches.push(ops));
1292
+ arr.sort((a, b) => a - b);
1293
+ arr.reverse();
1294
+ arr.shift();
1295
+ arr.concat([9]);
1296
+ flush();
1297
+
1298
+ expect(batches).toEqual([[
1299
+ { op: 'sort', order: [1, 2, 0] },
1300
+ { op: 'reverse' },
1301
+ { item: 3, op: 'shift' },
1302
+ { items: [9], op: 'concat' }
1303
+ ]]);
1304
+ });
1305
+
1306
+ it('runs listeners outside any owner, and stops delivering once the last one leaves', () => {
1307
+ let arr = new ReactiveArray<number>(),
1308
+ seen: unknown[] = [],
1309
+ stop = arr.on('batch', () => seen.push(owner()));
1310
+
1311
+ arr.push(1);
1312
+ flush();
1313
+ stop();
1314
+ arr.push(2);
1315
+ flush();
1316
+
1317
+ expect(seen).toEqual([null]);
1318
+ });
1319
+
1320
+ it('delivers mutations made inside an effect within the same pass', () => {
1321
+ let arr = new ReactiveArray<number>(),
1322
+ batches: unknown[][] = [],
1323
+ s = signal(0);
1324
+
1325
+ arr.on('batch', (ops) => batches.push(ops));
1326
+
1327
+ let stop = root(() => effect(() => {
1328
+ if (read(s)) {
1329
+ arr.push(read(s));
1330
+ }
1331
+ }));
1332
+
1333
+ write(s, 5);
1334
+ flush();
1335
+ stop();
1336
+
1337
+ expect(batches).toEqual([[{ items: [5], op: 'push' }]]);
1338
+ });
1339
+
1340
+ it('keeps delivering to later listeners after the last one throws and is dropped', async () => {
1341
+ pool();
1342
+
1343
+ let arr = new ReactiveArray<number>(),
1344
+ batches: unknown[][] = [],
1345
+ lengths: number[] = [],
1346
+ stop = root(() => effect(() => { lengths.push(arr.$length); }));
1347
+
1348
+ let captured = await captureUncaught(() => {
1349
+ arr.on('batch', () => { throw new Error('reactivity: batch'); });
1350
+ arr.push(1);
1351
+ flush();
1352
+ });
1353
+
1354
+ arr.on('batch', (ops) => batches.push(ops));
1355
+ arr.push(2);
1356
+ flush();
1357
+ stop();
1358
+
1359
+ expect(captured.map((e) => (e as Error).message)).toEqual(['reactivity: batch']);
1360
+ expect(batches).toEqual([[{ items: [2], op: 'push' }]]);
1361
+ expect(lengths).toEqual([0, 1, 2]);
1362
+ });
1363
+
1364
+ it('keeps delivering to later listeners after the last one unsubscribes itself during dispatch', async () => {
1365
+ pool();
1366
+
1367
+ let arr = new ReactiveArray<number>(),
1368
+ batches: unknown[][] = [],
1369
+ first: unknown[][] = [],
1370
+ lengths: number[] = [],
1371
+ stop = root(() => effect(() => { lengths.push(arr.$length); })),
1372
+ unsubscribe = arr.on('batch', (ops) => {
1373
+ first.push(ops);
1374
+ unsubscribe();
1375
+ });
1376
+
1377
+ arr.push(1);
1378
+ flush();
1379
+ await Promise.resolve();
1380
+
1381
+ arr.push(2);
1382
+ flush();
1383
+
1384
+ arr.on('batch', (ops) => batches.push(ops));
1385
+ arr.push(3);
1386
+ flush();
1387
+ stop();
1388
+
1389
+ expect(first).toEqual([[{ items: [1], op: 'push' }]]);
1390
+ expect(batches).toEqual([[{ items: [3], op: 'push' }]]);
1391
+ expect(lengths).toEqual([0, 1, 2, 3]);
1392
+ });
1393
+
1394
+ it('keeps the delivering effect when a listener joins before the stop runs', () => {
1395
+ let arr = new ReactiveArray<number>(),
1396
+ batches: unknown[][] = [],
1397
+ unsubscribe = arr.on('batch', () => {
1398
+ unsubscribe();
1399
+ arr.on('batch', (ops) => batches.push(ops));
1400
+ });
1401
+
1402
+ arr.push(1);
1403
+ flush();
1404
+ arr.push(2);
1405
+ flush();
1406
+
1407
+ expect(batches).toEqual([[{ items: [2], op: 'push' }]]);
1408
+ });
1409
+ });
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
- import { computed, effect, onCleanup, read, root, signal, write } from '~/system';
2
+ import { computed, effect, onCleanup, read, signal, write } from '~/system';
3
3
  import { SIGNAL } from '~/constants';
4
- import { ReactiveObject, isReactiveObject } from '~/reactive/object';
4
+ import { isReactiveObject, ReactiveObject } from '~/reactive/object';
5
5
  import reactive from '~/reactive/index';
6
6
  import { ReactiveArray } from '~/reactive/array';
7
7
  import { tick, waitFor } from '../lib/wait-for';
@@ -348,7 +348,7 @@ describe('isReactiveObject', () => {
348
348
  describe('reactive()', () => {
349
349
  describe('objects', () => {
350
350
  it('creates reactive object', () => {
351
- let obj = reactive({ name: 'John', age: 25 });
351
+ let obj = reactive({ age: 25, name: 'John' });
352
352
 
353
353
  expect((obj as any).name).toBe('John');
354
354
  expect((obj as any).age).toBe(25);
@@ -515,7 +515,7 @@ describe('integration', () => {
515
515
 
516
516
  it('large dependency chain', async () => {
517
517
  let s = signal(0),
518
- chain: ReturnType<typeof computed>[] = [computed(() => read(s))];
518
+ chain: ReturnType<typeof computed<number>>[] = [computed(() => read(s))];
519
519
 
520
520
  for (let i = 1; i < 50; i++) {
521
521
  let prev = chain[i - 1];
@@ -584,8 +584,7 @@ describe('root', () => {
584
584
  stop = dispose;
585
585
 
586
586
  try {
587
- root((inner) => {
588
- inner;
587
+ root((_inner) => {
589
588
  throw new Error('reactivity: inner boom');
590
589
  });
591
590
  }
@@ -1224,7 +1223,7 @@ describe('edge cases', () => {
1224
1223
 
1225
1224
  it('heap auto-resizes for computed chain deeper than 64', async () => {
1226
1225
  let s = signal(0),
1227
- chain: ReturnType<typeof computed>[] = [computed(() => read(s) + 1)];
1226
+ chain: ReturnType<typeof computed<number>>[] = [computed(() => read(s) + 1)];
1228
1227
 
1229
1228
  for (let i = 1; i < 80; i++) {
1230
1229
  let prev = chain[i - 1];
@@ -1416,7 +1415,7 @@ describe('edge cases', () => {
1416
1415
  });
1417
1416
 
1418
1417
  it('link pool handles >1000 dependencies with disposal and reuse', async () => {
1419
- let signals: ReturnType<typeof signal>[] = [],
1418
+ let signals: ReturnType<typeof signal<number>>[] = [],
1420
1419
  stops: (() => void)[] = [];
1421
1420
 
1422
1421
  for (let i = 0; i < 1100; i++) {
@@ -137,7 +137,7 @@ describe('untrack ownership', () => {
137
137
  });
138
138
  onCleanup(() => { log.push('c'); });
139
139
  });
140
- root((d) => {
140
+ root((_d) => {
141
141
  onCleanup(() => { log.push('d'); });
142
142
  });
143
143
  });
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "@esportsplus/typescript/tsconfig.package.json"
3
+ }
package/tsconfig.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "extends": "@esportsplus/typescript/tsconfig.package.json"
3
- }
2
+ "extends": "@esportsplus/typescript/tsconfig.package.dev.json"
3
+ }
package/vitest.config.ts CHANGED
@@ -5,8 +5,8 @@ import { resolve } from 'path';
5
5
  export default defineConfig({
6
6
  resolve: {
7
7
  alias: {
8
- '~': resolve(import.meta.dirname, 'src'),
9
- '@esportsplus/reactivity': resolve(import.meta.dirname, 'src/index.ts')
8
+ '@esportsplus/reactivity': resolve(import.meta.dirname, 'src/index.ts'),
9
+ '~': resolve(import.meta.dirname, 'src')
10
10
  }
11
11
  },
12
12
  test: {
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": true,
5
- "paths": {
6
- "~/*": [
7
- "../src/*"
8
- ]
9
- },
10
- "rootDir": ".."
11
- },
12
- "include": [
13
- "./**/*",
14
- "../src/**/*"
15
- ]
16
- }
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": true,
5
- "paths": {
6
- "~/*": [
7
- "../src/*"
8
- ]
9
- },
10
- "rootDir": ".."
11
- },
12
- "include": [
13
- "./**/*",
14
- "../src/**/*"
15
- ]
16
- }