@esportsplus/reactivity 0.22.3 → 0.23.1
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/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/reactive/array.d.ts +3 -0
- package/build/reactive/array.js +32 -2
- package/build/reactive/index.d.ts +17 -14
- package/build/reactive/index.js +7 -25
- package/build/system.js +1 -1
- package/build/transformer/detector.d.ts +2 -0
- package/build/transformer/detector.js +38 -0
- package/build/transformer/index.d.ts +10 -0
- package/build/transformer/index.js +55 -0
- package/build/transformer/plugins/esbuild.d.ts +5 -0
- package/build/transformer/plugins/esbuild.js +31 -0
- package/build/transformer/plugins/tsc.d.ts +3 -0
- package/build/transformer/plugins/tsc.js +4 -0
- package/build/transformer/plugins/vite.d.ts +5 -0
- package/build/transformer/plugins/vite.js +28 -0
- package/build/transformer/transforms/auto-dispose.d.ts +3 -0
- package/build/transformer/transforms/auto-dispose.js +119 -0
- package/build/transformer/transforms/reactive-array.d.ts +4 -0
- package/build/transformer/transforms/reactive-array.js +93 -0
- package/build/transformer/transforms/reactive-object.d.ts +4 -0
- package/build/transformer/transforms/reactive-object.js +164 -0
- package/build/transformer/transforms/reactive-primitives.d.ts +4 -0
- package/build/transformer/transforms/reactive-primitives.js +335 -0
- package/build/transformer/transforms/utilities.d.ts +8 -0
- package/build/transformer/transforms/utilities.js +73 -0
- package/build/types.d.ts +14 -4
- package/package.json +30 -3
- package/readme.md +276 -2
- package/src/constants.ts +1 -1
- package/src/index.ts +1 -1
- package/src/reactive/array.ts +49 -2
- package/src/reactive/index.ts +33 -57
- package/src/system.ts +14 -5
- package/src/transformer/detector.ts +65 -0
- package/src/transformer/index.ts +78 -0
- package/src/transformer/plugins/esbuild.ts +47 -0
- package/src/transformer/plugins/tsc.ts +8 -0
- package/src/transformer/plugins/vite.ts +39 -0
- package/src/transformer/transforms/auto-dispose.ts +191 -0
- package/src/transformer/transforms/reactive-array.ts +143 -0
- package/src/transformer/transforms/reactive-object.ts +253 -0
- package/src/transformer/transforms/reactive-primitives.ts +461 -0
- package/src/transformer/transforms/utilities.ts +119 -0
- package/src/types.ts +24 -5
- package/test/arrays.ts +146 -0
- package/test/effects.ts +168 -0
- package/test/index.ts +8 -0
- package/test/nested.ts +201 -0
- package/test/objects.ts +106 -0
- package/test/primitives.ts +171 -0
- package/test/vite.config.ts +40 -0
- package/build/reactive/object.d.ts +0 -7
- package/build/reactive/object.js +0 -79
- package/src/reactive/object.ts +0 -116
package/test/arrays.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Test: Reactive Arrays
|
|
2
|
+
import { effect, reactive } from '@esportsplus/reactivity';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Basic Array Operations
|
|
7
|
+
// =============================================================================
|
|
8
|
+
|
|
9
|
+
console.log('=== Basic Array Operations ===');
|
|
10
|
+
|
|
11
|
+
let numbers = reactive([1, 2, 3]);
|
|
12
|
+
|
|
13
|
+
console.log('Initial:', [...numbers]);
|
|
14
|
+
console.log('Length:', numbers.length);
|
|
15
|
+
|
|
16
|
+
// Push
|
|
17
|
+
numbers.push(4, 5);
|
|
18
|
+
console.log('After push(4, 5):', [...numbers]);
|
|
19
|
+
|
|
20
|
+
// Pop
|
|
21
|
+
let popped = numbers.pop();
|
|
22
|
+
console.log('Popped:', popped);
|
|
23
|
+
console.log('After pop:', [...numbers]);
|
|
24
|
+
|
|
25
|
+
// Shift
|
|
26
|
+
let shifted = numbers.shift();
|
|
27
|
+
console.log('Shifted:', shifted);
|
|
28
|
+
console.log('After shift:', [...numbers]);
|
|
29
|
+
|
|
30
|
+
// Unshift
|
|
31
|
+
numbers.unshift(0);
|
|
32
|
+
console.log('After unshift(0):', [...numbers]);
|
|
33
|
+
|
|
34
|
+
// Index assignment
|
|
35
|
+
numbers[0] = 100;
|
|
36
|
+
console.log('After [0] = 100:', [...numbers]);
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// Splice
|
|
41
|
+
// =============================================================================
|
|
42
|
+
|
|
43
|
+
console.log('\n=== Splice ===');
|
|
44
|
+
|
|
45
|
+
let items = reactive(['a', 'b', 'c', 'd', 'e']);
|
|
46
|
+
console.log('Initial:', [...items]);
|
|
47
|
+
|
|
48
|
+
// Remove 2 items starting at index 1
|
|
49
|
+
let removed = items.splice(1, 2);
|
|
50
|
+
console.log('Removed:', removed);
|
|
51
|
+
console.log('After splice(1, 2):', [...items]);
|
|
52
|
+
|
|
53
|
+
// Insert items
|
|
54
|
+
items.splice(1, 0, 'x', 'y');
|
|
55
|
+
console.log('After splice(1, 0, x, y):', [...items]);
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Sort and Reverse
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
console.log('\n=== Sort and Reverse ===');
|
|
63
|
+
|
|
64
|
+
let sortable = reactive([3, 1, 4, 1, 5, 9, 2, 6]);
|
|
65
|
+
console.log('Initial:', [...sortable]);
|
|
66
|
+
|
|
67
|
+
sortable.sort((a, b) => a - b);
|
|
68
|
+
console.log('After sort (asc):', [...sortable]);
|
|
69
|
+
|
|
70
|
+
sortable.reverse();
|
|
71
|
+
console.log('After reverse:', [...sortable]);
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// Concat
|
|
76
|
+
// =============================================================================
|
|
77
|
+
|
|
78
|
+
console.log('\n=== Concat ===');
|
|
79
|
+
|
|
80
|
+
let base = reactive([1, 2]);
|
|
81
|
+
console.log('Initial:', [...base]);
|
|
82
|
+
|
|
83
|
+
base.concat([3, 4]);
|
|
84
|
+
console.log('After concat([3, 4]):', [...base]);
|
|
85
|
+
|
|
86
|
+
base.concat(5, [6, 7]);
|
|
87
|
+
console.log('After concat(5, [6, 7]):', [...base]);
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
// =============================================================================
|
|
91
|
+
// Reactive Length in Effects
|
|
92
|
+
// =============================================================================
|
|
93
|
+
|
|
94
|
+
console.log('\n=== Reactive Length in Effects ===');
|
|
95
|
+
|
|
96
|
+
let tracked = reactive([1, 2, 3]);
|
|
97
|
+
let lengthReads = 0;
|
|
98
|
+
|
|
99
|
+
effect(() => {
|
|
100
|
+
lengthReads++;
|
|
101
|
+
console.log(`Effect #${lengthReads}: length = ${tracked.length}`);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
tracked.push(4);
|
|
105
|
+
tracked.pop();
|
|
106
|
+
tracked.splice(0, 1);
|
|
107
|
+
|
|
108
|
+
console.log('Total length reads:', lengthReads);
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
// =============================================================================
|
|
112
|
+
// Array Events
|
|
113
|
+
// =============================================================================
|
|
114
|
+
|
|
115
|
+
console.log('\n=== Array Events ===');
|
|
116
|
+
|
|
117
|
+
let observed = reactive([1, 2, 3]);
|
|
118
|
+
|
|
119
|
+
observed.on('push', (data) => {
|
|
120
|
+
console.log('Push event:', data);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
observed.on('pop', (data) => {
|
|
124
|
+
console.log('Pop event:', data);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
observed.on('set', (data) => {
|
|
128
|
+
console.log('Set event:', data);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
observed.push(4, 5);
|
|
132
|
+
observed.pop();
|
|
133
|
+
observed[0] = 100;
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
// =============================================================================
|
|
137
|
+
// Clear and Dispose
|
|
138
|
+
// =============================================================================
|
|
139
|
+
|
|
140
|
+
console.log('\n=== Clear and Dispose ===');
|
|
141
|
+
|
|
142
|
+
let clearable = reactive([1, 2, 3, 4, 5]);
|
|
143
|
+
console.log('Before clear:', [...clearable], 'length:', clearable.length);
|
|
144
|
+
|
|
145
|
+
clearable.clear();
|
|
146
|
+
console.log('After clear:', [...clearable], 'length:', clearable.length);
|
package/test/effects.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Test: Effects and Cleanup
|
|
2
|
+
import { effect, onCleanup, reactive, root } from '@esportsplus/reactivity';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Basic Effect with Object
|
|
7
|
+
// =============================================================================
|
|
8
|
+
|
|
9
|
+
console.log('=== Basic Effect ===');
|
|
10
|
+
|
|
11
|
+
let state = reactive({
|
|
12
|
+
count: 0
|
|
13
|
+
});
|
|
14
|
+
let effectRuns = 0;
|
|
15
|
+
|
|
16
|
+
let dispose = effect(() => {
|
|
17
|
+
effectRuns++;
|
|
18
|
+
console.log(`Effect run #${effectRuns}: count = ${state.count}`);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
state.count = 1;
|
|
22
|
+
state.count = 2;
|
|
23
|
+
state.count = 3;
|
|
24
|
+
|
|
25
|
+
console.log('Total runs before dispose:', effectRuns);
|
|
26
|
+
|
|
27
|
+
dispose();
|
|
28
|
+
|
|
29
|
+
state.count = 4;
|
|
30
|
+
state.count = 5;
|
|
31
|
+
|
|
32
|
+
console.log('Total runs after dispose:', effectRuns);
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// Effect with Cleanup
|
|
37
|
+
// =============================================================================
|
|
38
|
+
|
|
39
|
+
console.log('\n=== Effect with Cleanup ===');
|
|
40
|
+
|
|
41
|
+
let data = reactive({
|
|
42
|
+
value: 0
|
|
43
|
+
});
|
|
44
|
+
let cleanupCalls = 0;
|
|
45
|
+
|
|
46
|
+
let cleanup = effect((onCleanup) => {
|
|
47
|
+
let current = data.value;
|
|
48
|
+
console.log('Effect running with value:', current);
|
|
49
|
+
|
|
50
|
+
onCleanup(() => {
|
|
51
|
+
cleanupCalls++;
|
|
52
|
+
console.log(`Cleanup called (${cleanupCalls}x) for value:`, current);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
data.value = 1;
|
|
57
|
+
data.value = 2;
|
|
58
|
+
|
|
59
|
+
cleanup();
|
|
60
|
+
|
|
61
|
+
console.log('Total cleanup calls:', cleanupCalls);
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// =============================================================================
|
|
65
|
+
// Effect with Computed
|
|
66
|
+
// =============================================================================
|
|
67
|
+
|
|
68
|
+
console.log('\n=== Effect with Computed ===');
|
|
69
|
+
|
|
70
|
+
let counter = reactive({
|
|
71
|
+
count: 10,
|
|
72
|
+
doubled: () => counter.count * 2
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
let computedReads = 0;
|
|
76
|
+
|
|
77
|
+
effect(() => {
|
|
78
|
+
computedReads++;
|
|
79
|
+
console.log(`Effect #${computedReads}: doubled = ${counter.doubled}`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
counter.count = 20;
|
|
83
|
+
counter.count = 30;
|
|
84
|
+
|
|
85
|
+
console.log('Total computed reads:', computedReads);
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
// =============================================================================
|
|
89
|
+
// Root Scope
|
|
90
|
+
// =============================================================================
|
|
91
|
+
|
|
92
|
+
console.log('\n=== Root Scope ===');
|
|
93
|
+
|
|
94
|
+
let rootDisposed = false;
|
|
95
|
+
|
|
96
|
+
let result = root((dispose) => {
|
|
97
|
+
let obj = reactive({
|
|
98
|
+
a: 1,
|
|
99
|
+
b: () => obj.a * 2
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
effect(() => {
|
|
103
|
+
console.log('Root effect: a =', obj.a, 'b =', obj.b);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
obj.a = 5;
|
|
107
|
+
|
|
108
|
+
onCleanup(() => {
|
|
109
|
+
rootDisposed = true;
|
|
110
|
+
console.log('Root cleanup called');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
dispose();
|
|
114
|
+
|
|
115
|
+
return 'root result';
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
console.log('Root returned:', result);
|
|
119
|
+
console.log('Root disposed:', rootDisposed);
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// =============================================================================
|
|
123
|
+
// Multiple Object Dependencies
|
|
124
|
+
// =============================================================================
|
|
125
|
+
|
|
126
|
+
console.log('\n=== Multiple Dependencies ===');
|
|
127
|
+
|
|
128
|
+
let obj1 = reactive({ x: 1 });
|
|
129
|
+
let obj2 = reactive({ y: 2 });
|
|
130
|
+
let obj3 = reactive({ z: 3 });
|
|
131
|
+
let multiRuns = 0;
|
|
132
|
+
|
|
133
|
+
effect(() => {
|
|
134
|
+
multiRuns++;
|
|
135
|
+
let sum = obj1.x + obj2.y + obj3.z;
|
|
136
|
+
console.log(`Multi-dep effect #${multiRuns}: x=${obj1.x}, y=${obj2.y}, z=${obj3.z}, sum=${sum}`);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
obj1.x = 10;
|
|
140
|
+
obj2.y = 20;
|
|
141
|
+
obj3.z = 30;
|
|
142
|
+
|
|
143
|
+
console.log('Total multi-dep runs:', multiRuns);
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
// =============================================================================
|
|
147
|
+
// Effect with Array
|
|
148
|
+
// =============================================================================
|
|
149
|
+
|
|
150
|
+
console.log('\n=== Effect with Array ===');
|
|
151
|
+
|
|
152
|
+
let list = reactive({
|
|
153
|
+
items: [1, 2, 3],
|
|
154
|
+
total: () => list.items.reduce((a, b) => a + b, 0)
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
let arrayRuns = 0;
|
|
158
|
+
|
|
159
|
+
effect(() => {
|
|
160
|
+
arrayRuns++;
|
|
161
|
+
console.log(`Array effect #${arrayRuns}: length=${list.items.length}, total=${list.total}`);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
list.items.push(4);
|
|
165
|
+
list.items.pop();
|
|
166
|
+
list.items[0] = 10;
|
|
167
|
+
|
|
168
|
+
console.log('Total array runs:', arrayRuns);
|
package/test/index.ts
ADDED
package/test/nested.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Test: Nested Reactive Structures
|
|
2
|
+
import { effect, reactive } from '@esportsplus/reactivity';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Object with Computed accessing other objects
|
|
7
|
+
// =============================================================================
|
|
8
|
+
|
|
9
|
+
console.log('=== Nested Object Access ===');
|
|
10
|
+
|
|
11
|
+
let config = reactive({
|
|
12
|
+
debug: true,
|
|
13
|
+
theme: 'dark'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
let settings = reactive({
|
|
17
|
+
notifications: true,
|
|
18
|
+
volume: 80
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
let user = reactive({
|
|
22
|
+
name: 'Alice',
|
|
23
|
+
getTheme: () => config.theme,
|
|
24
|
+
getVolume: () => settings.volume
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
console.log('Initial config:', { debug: config.debug, theme: config.theme });
|
|
28
|
+
console.log('Initial user:', user.name, 'theme:', user.getTheme, 'volume:', user.getVolume);
|
|
29
|
+
|
|
30
|
+
config.theme = 'light';
|
|
31
|
+
settings.volume = 50;
|
|
32
|
+
|
|
33
|
+
console.log('After updates:');
|
|
34
|
+
console.log(' user theme:', user.getTheme);
|
|
35
|
+
console.log(' user volume:', user.getVolume);
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Object with Array of Objects
|
|
40
|
+
// =============================================================================
|
|
41
|
+
|
|
42
|
+
console.log('\n=== Object with Array of Reactive Objects ===');
|
|
43
|
+
|
|
44
|
+
let todo1 = reactive({ done: false, text: 'Learn reactivity' });
|
|
45
|
+
let todo2 = reactive({ done: true, text: 'Build app' });
|
|
46
|
+
let todo3 = reactive({ done: false, text: 'Test everything' });
|
|
47
|
+
|
|
48
|
+
let store = reactive({
|
|
49
|
+
todos: [todo1, todo2, todo3],
|
|
50
|
+
completedCount: () => store.todos.filter(t => t.done).length
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log('Initial todos:');
|
|
54
|
+
for (let i = 0; i < store.todos.length; i++) {
|
|
55
|
+
let todo = store.todos[i];
|
|
56
|
+
console.log(` [${todo.done ? 'x' : ' '}] ${todo.text}`);
|
|
57
|
+
}
|
|
58
|
+
console.log('Completed:', store.completedCount);
|
|
59
|
+
|
|
60
|
+
todo1.done = true;
|
|
61
|
+
console.log('After marking todo1 done:');
|
|
62
|
+
console.log('Completed:', store.completedCount);
|
|
63
|
+
|
|
64
|
+
let todo4 = reactive({ done: false, text: 'Deploy' });
|
|
65
|
+
store.todos.push(todo4);
|
|
66
|
+
|
|
67
|
+
console.log('After adding todo4:');
|
|
68
|
+
for (let i = 0; i < store.todos.length; i++) {
|
|
69
|
+
let todo = store.todos[i];
|
|
70
|
+
console.log(` [${todo.done ? 'x' : ' '}] ${todo.text}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// Array of Arrays (using reactive arrays)
|
|
76
|
+
// =============================================================================
|
|
77
|
+
|
|
78
|
+
console.log('\n=== Array of Arrays ===');
|
|
79
|
+
|
|
80
|
+
let row1 = reactive([1, 2, 3]);
|
|
81
|
+
let row2 = reactive([4, 5, 6]);
|
|
82
|
+
let row3 = reactive([7, 8, 9]);
|
|
83
|
+
|
|
84
|
+
let matrix = reactive([row1, row2, row3]);
|
|
85
|
+
|
|
86
|
+
console.log('Initial matrix:');
|
|
87
|
+
for (let row of matrix) {
|
|
88
|
+
console.log(' ', [...row]);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
row1[0] = 100;
|
|
92
|
+
row2.push(60);
|
|
93
|
+
|
|
94
|
+
let row4 = reactive([10, 11, 12]);
|
|
95
|
+
matrix.push(row4);
|
|
96
|
+
|
|
97
|
+
console.log('After updates:');
|
|
98
|
+
for (let row of matrix) {
|
|
99
|
+
console.log(' ', [...row]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// =============================================================================
|
|
104
|
+
// Cross-Object Computed Dependencies
|
|
105
|
+
// =============================================================================
|
|
106
|
+
|
|
107
|
+
console.log('\n=== Cross-Object Computed Dependencies ===');
|
|
108
|
+
|
|
109
|
+
let data = reactive({
|
|
110
|
+
items: [10, 20, 30],
|
|
111
|
+
multiplier: 2
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
let calcObj = reactive({
|
|
115
|
+
sum: () => data.items.reduce((a: number, b: number) => a + b, 0),
|
|
116
|
+
total: () => calcObj.sum * data.multiplier
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
console.log('Initial sum:', calcObj.sum);
|
|
120
|
+
console.log('Initial total:', calcObj.total);
|
|
121
|
+
|
|
122
|
+
data.items.push(40);
|
|
123
|
+
console.log('After push(40) - sum:', calcObj.sum, 'total:', calcObj.total);
|
|
124
|
+
|
|
125
|
+
data.multiplier = 3;
|
|
126
|
+
console.log('After multiplier = 3 - sum:', calcObj.sum, 'total:', calcObj.total);
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
// =============================================================================
|
|
130
|
+
// Effects Tracking Multiple Objects
|
|
131
|
+
// =============================================================================
|
|
132
|
+
|
|
133
|
+
console.log('\n=== Effects Tracking Multiple Objects ===');
|
|
134
|
+
|
|
135
|
+
let effectRuns = 0;
|
|
136
|
+
|
|
137
|
+
let obj1 = reactive({ value: 1 });
|
|
138
|
+
let obj2 = reactive({ value: 2 });
|
|
139
|
+
let obj3 = reactive({ combined: () => obj1.value + obj2.value });
|
|
140
|
+
|
|
141
|
+
effect(() => {
|
|
142
|
+
effectRuns++;
|
|
143
|
+
console.log(`Effect #${effectRuns}: obj1=${obj1.value}, obj2=${obj2.value}, combined=${obj3.combined}`);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
obj1.value = 10;
|
|
147
|
+
obj2.value = 20;
|
|
148
|
+
|
|
149
|
+
console.log('Total effect runs:', effectRuns);
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
// =============================================================================
|
|
153
|
+
// Primitives Referencing Objects
|
|
154
|
+
// =============================================================================
|
|
155
|
+
|
|
156
|
+
console.log('\n=== Primitives Referencing Objects ===');
|
|
157
|
+
|
|
158
|
+
let source = reactive({
|
|
159
|
+
base: 10,
|
|
160
|
+
items: [1, 2, 3]
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
let derived = reactive(() => source.base * 2);
|
|
164
|
+
let itemSum = reactive(() => source.items.reduce((a: number, b: number) => a + b, 0));
|
|
165
|
+
|
|
166
|
+
console.log('Initial derived:', derived);
|
|
167
|
+
console.log('Initial itemSum:', itemSum);
|
|
168
|
+
|
|
169
|
+
source.base = 20;
|
|
170
|
+
source.items.push(4);
|
|
171
|
+
|
|
172
|
+
console.log('After updates:');
|
|
173
|
+
console.log(' derived:', derived);
|
|
174
|
+
console.log(' itemSum:', itemSum);
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// =============================================================================
|
|
178
|
+
// Dispose Individual Objects
|
|
179
|
+
// =============================================================================
|
|
180
|
+
|
|
181
|
+
console.log('\n=== Dispose Individual Objects ===');
|
|
182
|
+
|
|
183
|
+
let parent = reactive({
|
|
184
|
+
value: 42,
|
|
185
|
+
doubled: () => parent.value * 2
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
let child = reactive({
|
|
189
|
+
parentValue: () => parent.value,
|
|
190
|
+
ownValue: 10
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
console.log('Before dispose - parent.value:', parent.value, 'child.parentValue:', child.parentValue);
|
|
194
|
+
|
|
195
|
+
parent.dispose();
|
|
196
|
+
console.log('Parent disposed');
|
|
197
|
+
|
|
198
|
+
// Child still works with its own value
|
|
199
|
+
console.log('Child ownValue:', child.ownValue);
|
|
200
|
+
child.dispose();
|
|
201
|
+
console.log('Child disposed');
|
package/test/objects.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Test: Reactive Objects
|
|
2
|
+
import { effect, reactive } from '@esportsplus/reactivity';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Basic Object
|
|
7
|
+
// =============================================================================
|
|
8
|
+
|
|
9
|
+
console.log('=== Basic Reactive Object ===');
|
|
10
|
+
|
|
11
|
+
let user = reactive({
|
|
12
|
+
age: 25,
|
|
13
|
+
email: 'test@example.com',
|
|
14
|
+
name: 'John'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
console.log('Initial user:', { age: user.age, email: user.email, name: user.name });
|
|
18
|
+
|
|
19
|
+
user.age = 26;
|
|
20
|
+
user.name = 'Jane';
|
|
21
|
+
|
|
22
|
+
console.log('After updates:', { age: user.age, email: user.email, name: user.name });
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Object with Computed Properties
|
|
27
|
+
// =============================================================================
|
|
28
|
+
|
|
29
|
+
console.log('\n=== Object with Computed Properties ===');
|
|
30
|
+
|
|
31
|
+
let counter = reactive({
|
|
32
|
+
count: 0,
|
|
33
|
+
doubled: () => counter.count * 2,
|
|
34
|
+
message: () => `Count is ${counter.count}`
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
console.log('Initial:', { count: counter.count, doubled: counter.doubled, message: counter.message });
|
|
38
|
+
|
|
39
|
+
counter.count = 5;
|
|
40
|
+
console.log('After count = 5:', { count: counter.count, doubled: counter.doubled, message: counter.message });
|
|
41
|
+
|
|
42
|
+
counter.count = 10;
|
|
43
|
+
console.log('After count = 10:', { count: counter.count, doubled: counter.doubled, message: counter.message });
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// =============================================================================
|
|
47
|
+
// Object with Arrays
|
|
48
|
+
// =============================================================================
|
|
49
|
+
|
|
50
|
+
console.log('\n=== Object with Arrays ===');
|
|
51
|
+
|
|
52
|
+
let state = reactive({
|
|
53
|
+
items: [1, 2, 3],
|
|
54
|
+
total: () => state.items.reduce((a, b) => a + b, 0)
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
console.log('Initial items:', [...state.items]);
|
|
58
|
+
console.log('Initial total:', state.total);
|
|
59
|
+
|
|
60
|
+
state.items.push(4, 5);
|
|
61
|
+
console.log('After push(4, 5):', [...state.items]);
|
|
62
|
+
console.log('Updated total:', state.total);
|
|
63
|
+
|
|
64
|
+
state.items[0] = 10;
|
|
65
|
+
console.log('After items[0] = 10:', [...state.items]);
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Effects with Objects
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
console.log('\n=== Effects with Objects ===');
|
|
73
|
+
|
|
74
|
+
let effectRuns = 0;
|
|
75
|
+
let data = reactive({
|
|
76
|
+
a: 1,
|
|
77
|
+
b: 2,
|
|
78
|
+
sum: () => data.a + data.b
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
effect(() => {
|
|
82
|
+
effectRuns++;
|
|
83
|
+
console.log(`Effect #${effectRuns}: a=${data.a}, b=${data.b}, sum=${data.sum}`);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
data.a = 10;
|
|
87
|
+
data.b = 20;
|
|
88
|
+
|
|
89
|
+
console.log('Total effect runs:', effectRuns);
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
// =============================================================================
|
|
93
|
+
// Dispose
|
|
94
|
+
// =============================================================================
|
|
95
|
+
|
|
96
|
+
console.log('\n=== Dispose ===');
|
|
97
|
+
|
|
98
|
+
let disposable = reactive({
|
|
99
|
+
value: 42,
|
|
100
|
+
computed: () => disposable.value * 2
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
console.log('Before dispose:', disposable.value, disposable.computed);
|
|
104
|
+
|
|
105
|
+
disposable.dispose();
|
|
106
|
+
console.log('Disposed successfully');
|