@view-models/core 2.1.0 → 2.1.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/README.md +2 -102
- package/dist/ViewModel.d.ts +1 -1
- package/dist/ViewModel.d.ts.map +1 -1
- package/dist/ViewModel.js +1 -1
- package/dist/ViewModelWithDerivedState.d.ts +4 -5
- package/dist/ViewModelWithDerivedState.d.ts.map +1 -1
- package/dist/ViewModelWithDerivedState.js +4 -4
- package/package.json +4 -1
- package/src/ViewModel.ts +1 -1
- package/src/ViewModelWithDerivedState.ts +4 -5
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ class TodoViewModel extends ViewModelWithDerivedState<
|
|
|
118
118
|
toggleTodo(id: string) {
|
|
119
119
|
this.update(({ items }) => ({
|
|
120
120
|
items: items.map((item) =>
|
|
121
|
-
item.id === id ? { ...item, done: !item.done } : item
|
|
121
|
+
item.id === id ? { ...item, done: !item.done } : item,
|
|
122
122
|
),
|
|
123
123
|
}));
|
|
124
124
|
}
|
|
@@ -160,107 +160,7 @@ function Counter({ model }) {
|
|
|
160
160
|
|
|
161
161
|
## API Reference
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
Abstract base class for creating view models.
|
|
166
|
-
|
|
167
|
-
#### Constructor
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
constructor(initialState: T)
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Initialize the view model with an initial state.
|
|
174
|
-
|
|
175
|
-
#### Methods
|
|
176
|
-
|
|
177
|
-
##### `subscribe(listener: ViewModelListener): () => void`
|
|
178
|
-
|
|
179
|
-
Subscribe to state changes. The listener will be called whenever `update()` is called. Returns a function to unsubscribe.
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
const unsubscribe = viewModel.subscribe(() => {
|
|
183
|
-
console.log("State changed:", viewModel.state);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Later, to unsubscribe:
|
|
187
|
-
unsubscribe();
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
##### `update(updater: Updater<T>): void` (protected)
|
|
191
|
-
|
|
192
|
-
Update the state and notify all subscribers. This method is protected and should only be called from within your view model subclass.
|
|
193
|
-
|
|
194
|
-
```typescript
|
|
195
|
-
protected update(updater: (currentState: T) => T): void
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
The updater function receives the current state and should return the new state.
|
|
199
|
-
|
|
200
|
-
##### `state: T` (getter)
|
|
201
|
-
|
|
202
|
-
Access the current state.
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
const currentState = viewModel.state;
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### `ViewModelWithDerivedState<S, D>`
|
|
209
|
-
|
|
210
|
-
Abstract base class for creating view models with derived state. Use this when you need computed properties that are automatically recalculated when the internal state changes.
|
|
211
|
-
|
|
212
|
-
#### Constructor
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
constructor(initialState: S)
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Initialize the view model with an initial internal state. The derived state is automatically computed during construction.
|
|
219
|
-
|
|
220
|
-
#### Methods
|
|
221
|
-
|
|
222
|
-
##### `subscribe(listener: ViewModelListener): () => void`
|
|
223
|
-
|
|
224
|
-
Subscribe to state changes. The listener will be called whenever the derived state changes. Returns a function to unsubscribe.
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
const unsubscribe = viewModel.subscribe(() => {
|
|
228
|
-
console.log("State changed:", viewModel.state);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Later, to unsubscribe:
|
|
232
|
-
unsubscribe();
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
##### `update(updater: Updater<S>): void` (protected)
|
|
236
|
-
|
|
237
|
-
Update the internal state, automatically recompute derived state, and notify all subscribers. This method is protected and should only be called from within your view model subclass.
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
protected update(updater: (currentState: S) => S): void
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
##### `computeDerivedState(state: S): D` (abstract)
|
|
244
|
-
|
|
245
|
-
Abstract method that must be implemented to compute the derived state from the internal state. This is called automatically after each update and during initialization.
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
computeDerivedState({ items }: InternalState): DerivedState {
|
|
249
|
-
return {
|
|
250
|
-
items,
|
|
251
|
-
count: items.length,
|
|
252
|
-
hasItems: items.length > 0,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
##### `state: D` (getter)
|
|
258
|
-
|
|
259
|
-
Access the current derived state.
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
const currentState = viewModel.state;
|
|
263
|
-
```
|
|
163
|
+
For detailed API documentation, see [docs](./docs).
|
|
264
164
|
|
|
265
165
|
## Patterns and Best Practices
|
|
266
166
|
|
package/dist/ViewModel.d.ts
CHANGED
package/dist/ViewModel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewModel.d.ts","sourceRoot":"","sources":["../src/ViewModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ViewModel.d.ts","sourceRoot":"","sources":["../src/ViewModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,8BAAsB,SAAS,CAAC,CAAC,CAAE,SAAQ,yBAAyB,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE;;;;OAIG;gBACS,YAAY,EAAE,CAAC;IAI3B,mBAAmB,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;CAGjC"}
|
package/dist/ViewModel.js
CHANGED
|
@@ -11,7 +11,6 @@ export type Updater<T> = (currentState: T) => T;
|
|
|
11
11
|
* Function that gets called when the state changes.
|
|
12
12
|
*
|
|
13
13
|
* @template T - The state type
|
|
14
|
-
* @param state - The new state
|
|
15
14
|
*/
|
|
16
15
|
export type ViewModelListener = () => void;
|
|
17
16
|
/**
|
|
@@ -27,22 +26,22 @@ export type ViewModelListener = () => void;
|
|
|
27
26
|
*
|
|
28
27
|
* @example
|
|
29
28
|
* ```typescript
|
|
30
|
-
* type
|
|
29
|
+
* type TodoState = {
|
|
31
30
|
* items: Array<{ id: string; text: string; done: boolean }>;
|
|
32
31
|
* };
|
|
33
32
|
*
|
|
34
|
-
* type TodoDerivedState =
|
|
33
|
+
* type TodoDerivedState = TodoState & {
|
|
35
34
|
* totalCount: number;
|
|
36
35
|
* completedCount: number;
|
|
37
36
|
* remainingCount: number;
|
|
38
37
|
* };
|
|
39
38
|
*
|
|
40
|
-
* class TodoViewModel extends ViewModelWithDerivedState<
|
|
39
|
+
* class TodoViewModel extends ViewModelWithDerivedState<TodoState, TodoDerivedState> {
|
|
41
40
|
* constructor() {
|
|
42
41
|
* super({ items: [] });
|
|
43
42
|
* }
|
|
44
43
|
*
|
|
45
|
-
* computeDerivedState({ items }:
|
|
44
|
+
* computeDerivedState({ items }: TodoState): TodoDerivedState {
|
|
46
45
|
* return {
|
|
47
46
|
* items,
|
|
48
47
|
* totalCount: items.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewModelWithDerivedState.d.ts","sourceRoot":"","sources":["../src/ViewModelWithDerivedState.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"ViewModelWithDerivedState.d.ts","sourceRoot":"","sources":["../src/ViewModelWithDerivedState.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC;AAEhD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,8BAAsB,yBAAyB,CAAC,CAAC,EAAE,CAAC;IAClD,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,MAAM,CAAI;IAElB;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAOlD;;;;;;;OAOG;gBACS,YAAY,EAAE,CAAC;IAK3B;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IASpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;IAEzC;;;;;;;OAOG;IACH,IAAI,KAAK,IAAI,CAAC,CAEb;CACF"}
|
|
@@ -11,22 +11,22 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
-
* type
|
|
14
|
+
* type TodoState = {
|
|
15
15
|
* items: Array<{ id: string; text: string; done: boolean }>;
|
|
16
16
|
* };
|
|
17
17
|
*
|
|
18
|
-
* type TodoDerivedState =
|
|
18
|
+
* type TodoDerivedState = TodoState & {
|
|
19
19
|
* totalCount: number;
|
|
20
20
|
* completedCount: number;
|
|
21
21
|
* remainingCount: number;
|
|
22
22
|
* };
|
|
23
23
|
*
|
|
24
|
-
* class TodoViewModel extends ViewModelWithDerivedState<
|
|
24
|
+
* class TodoViewModel extends ViewModelWithDerivedState<TodoState, TodoDerivedState> {
|
|
25
25
|
* constructor() {
|
|
26
26
|
* super({ items: [] });
|
|
27
27
|
* }
|
|
28
28
|
*
|
|
29
|
-
* computeDerivedState({ items }:
|
|
29
|
+
* computeDerivedState({ items }: TodoState): TodoDerivedState {
|
|
30
30
|
* return {
|
|
31
31
|
* items,
|
|
32
32
|
* totalCount: items.length,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@view-models/core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "A lightweight, framework-agnostic library for building reactive view models with TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"view",
|
|
@@ -43,11 +43,14 @@
|
|
|
43
43
|
"test:coverage": "vitest run --coverage",
|
|
44
44
|
"format": "prettier --write \"**/*.{ts,js,json,md}\"",
|
|
45
45
|
"format:check": "prettier --check \"**/*.{ts,js,json,md}\"",
|
|
46
|
+
"docs": "typedoc && npm run format",
|
|
46
47
|
"prepublishOnly": "npm run build"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@vitest/coverage-v8": "^4.0.16",
|
|
50
51
|
"prettier": "^3.7.4",
|
|
52
|
+
"typedoc": "^0.28.16",
|
|
53
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
51
54
|
"typescript": "^5.7.3",
|
|
52
55
|
"vitest": "^4.0.16"
|
|
53
56
|
},
|
package/src/ViewModel.ts
CHANGED
|
@@ -12,7 +12,6 @@ export type Updater<T> = (currentState: T) => T;
|
|
|
12
12
|
* Function that gets called when the state changes.
|
|
13
13
|
*
|
|
14
14
|
* @template T - The state type
|
|
15
|
-
* @param state - The new state
|
|
16
15
|
*/
|
|
17
16
|
export type ViewModelListener = () => void;
|
|
18
17
|
|
|
@@ -29,22 +28,22 @@ export type ViewModelListener = () => void;
|
|
|
29
28
|
*
|
|
30
29
|
* @example
|
|
31
30
|
* ```typescript
|
|
32
|
-
* type
|
|
31
|
+
* type TodoState = {
|
|
33
32
|
* items: Array<{ id: string; text: string; done: boolean }>;
|
|
34
33
|
* };
|
|
35
34
|
*
|
|
36
|
-
* type TodoDerivedState =
|
|
35
|
+
* type TodoDerivedState = TodoState & {
|
|
37
36
|
* totalCount: number;
|
|
38
37
|
* completedCount: number;
|
|
39
38
|
* remainingCount: number;
|
|
40
39
|
* };
|
|
41
40
|
*
|
|
42
|
-
* class TodoViewModel extends ViewModelWithDerivedState<
|
|
41
|
+
* class TodoViewModel extends ViewModelWithDerivedState<TodoState, TodoDerivedState> {
|
|
43
42
|
* constructor() {
|
|
44
43
|
* super({ items: [] });
|
|
45
44
|
* }
|
|
46
45
|
*
|
|
47
|
-
* computeDerivedState({ items }:
|
|
46
|
+
* computeDerivedState({ items }: TodoState): TodoDerivedState {
|
|
48
47
|
* return {
|
|
49
48
|
* items,
|
|
50
49
|
* totalCount: items.length,
|