@yiin/reactive-proxy-state 1.0.5 → 1.0.6

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 (2) hide show
  1. package/README.md +56 -17
  2. package/package.json +8 -3
package/README.md CHANGED
@@ -91,60 +91,99 @@ console.log(unref(123)); // 123 (returns non-refs as is)
91
91
  ```
92
92
 
93
93
  ### `computed<T>(getter: () => T): ComputedRef<T>`
94
+ ### `computed<T>(options: { get: () => T, set: (value: T) => void }): WritableComputedRef<T>`
94
95
 
95
- Creates a computed property based on a getter function. The getter tracks reactive dependencies (`ref`s or reactive object properties) and its result is cached. The computed value only recalculates when a dependency changes.
96
- Computed refs are read-only.
96
+ Creates a computed property based on a getter function or a getter/setter pair.
97
+
98
+ - **Getter-only:** The getter tracks reactive dependencies (`ref`s or reactive object properties) and its result is cached. The computed value only recalculates when a dependency changes. Computed refs created this way are **read-only**.
99
+ - **Getter/Setter:** Provides both a getter for deriving the value and a setter for mutating underlying reactive state when the computed ref's `.value` is assigned.
97
100
 
98
101
  ```typescript
99
102
  import { ref, computed, watchEffect, isComputed } from '@yiin/reactive-proxy-state';
100
103
 
104
+ // Read-only computed
101
105
  const firstName = ref('John');
102
106
  const lastName = ref('Doe');
103
107
 
104
- const fullName = computed(() => {
105
- console.log('Computing fullName...');
108
+ const readOnlyFullName = computed(() => {
109
+ console.log('Computing readOnlyFullName...');
106
110
  return `${firstName.value} ${lastName.value}`;
107
111
  });
108
112
 
109
113
  // Accessing .value triggers computation
110
- console.log(fullName.value);
111
- // Output: Computing fullName...
114
+ console.log(readOnlyFullName.value);
115
+ // Output: Computing readOnlyFullName...
112
116
  // Output: John Doe
113
117
 
114
118
  // Accessing again uses the cache
115
- console.log(fullName.value);
119
+ console.log(readOnlyFullName.value);
116
120
  // Output: John Doe
117
121
 
118
122
  watchEffect(() => {
119
- console.log('Full name changed:', fullName.value);
123
+ console.log('Read-only full name changed:', readOnlyFullName.value);
120
124
  });
121
- // Output: Full name changed: John Doe
125
+ // Output: Read-only full name changed: John Doe
122
126
 
123
127
  // Changing a dependency marks computed as dirty
124
128
  firstName.value = 'Jane';
125
129
 
126
130
  // Accessing .value again triggers re-computation and the effect
127
- console.log(fullName.value);
128
- // Output: Computing fullName...
129
- // Output: Full name changed: Jane Doe
131
+ console.log(readOnlyFullName.value);
132
+ // Output: Computing readOnlyFullName...
133
+ // Output: Read-only full name changed: Jane Doe
130
134
  // Output: Jane Doe
131
135
 
132
136
  // Chained computed
133
- const message = computed(() => `User: ${fullName.value}`);
137
+ const message = computed(() => `User: ${readOnlyFullName.value}`);
134
138
  console.log(message.value); // User: Jane Doe
135
139
 
136
140
  lastName.value = 'Smith';
137
- // Output: Computing fullName...
138
- // Output: Full name changed: Jane Smith
141
+ // Output: Computing readOnlyFullName...
142
+ // Output: Read-only full name changed: Jane Smith
139
143
  console.log(message.value); // User: Jane Smith (message recomputed automatically)
140
144
 
141
145
  // Read-only check
146
+ console.warn = () => console.log('Warning triggered!'); // Mock console.warn
142
147
  try {
143
- (fullName as any).value = 'Test'; // Throws warning
148
+ (readOnlyFullName as any).value = 'Test'; // Triggers warning
144
149
  } catch (e) { /* ... */ }
150
+ // Output: Warning triggered!
151
+ console.log(readOnlyFullName.value); // Jane Smith (value unchanged)
152
+
153
+ // Writable computed
154
+ const source = ref(1);
155
+ const plusOne = computed({
156
+ get: () => source.value + 1,
157
+ set: (newValue) => {
158
+ console.log(`Setting source based on new value: ${newValue}`);
159
+ source.value = newValue - 1;
160
+ }
161
+ });
162
+
163
+ console.log(plusOne.value); // 2 (Initial get)
164
+ console.log(source.value); // 1
165
+
166
+ watchEffect(() => {
167
+ console.log('Writable computed changed:', plusOne.value);
168
+ });
169
+ // Output: Writable computed changed: 2
170
+
171
+ // Set the writable computed value
172
+ plusOne.value = 10;
173
+ // Output: Setting source based on new value: 10
174
+ // Output: Writable computed changed: 10
175
+
176
+ console.log(plusOne.value); // 10
177
+ console.log(source.value); // 9 (Source was updated by the setter)
178
+
179
+ // Changing the source ref also updates the computed
180
+ source.value = 20;
181
+ // Output: Writable computed changed: 21
182
+ console.log(plusOne.value); // 21
145
183
 
146
184
  // Helper
147
- console.log(isComputed(fullName)); // true
185
+ console.log(isComputed(readOnlyFullName)); // true
186
+ console.log(isComputed(plusOne)); // true
148
187
  console.log(isComputed(firstName)); // false
149
188
  ```
150
189
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yiin/reactive-proxy-state",
3
3
  "private": false,
4
- "version": "1.0.5",
4
+ "version": "1.0.6",
5
5
  "description": "A simple, standalone reactivity library using Proxies",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -20,7 +20,10 @@
20
20
  "build": "tsc",
21
21
  "test": "bun test",
22
22
  "test:watch": "bun test --watch",
23
- "test:bench": "bun --bun ./benchmarks/state-sync.bench.ts"
23
+ "test:bench": "bun --bun ./benchmarks/state-sync.bench.ts",
24
+ "docs:dev": "vitepress dev docs",
25
+ "docs:build": "vitepress build docs",
26
+ "docs:preview": "vitepress preview docs"
24
27
  },
25
28
  "keywords": [
26
29
  "state",
@@ -47,6 +50,8 @@
47
50
  },
48
51
  "devDependencies": {
49
52
  "bun-types": "^1.2.8",
50
- "typescript": "^5.0.4"
53
+ "typescript": "^5.0.4",
54
+ "vitepress": "^1.6.3",
55
+ "vue": "^3.5.13"
51
56
  }
52
57
  }