ngx-easy-state-manager 0.0.4 → 1.0.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.
- package/README.md +120 -52
- package/fesm2022/ngx-easy-state-manager.mjs +92 -5
- package/fesm2022/ngx-easy-state-manager.mjs.map +1 -1
- package/index.d.ts +52 -5
- package/package.json +5 -3
- package/lib/ngx-easy-state-manager.service.d.ts +0 -11
- package/public-api.d.ts +0 -1
package/README.md
CHANGED
|
@@ -11,15 +11,21 @@ npm install ngx-easy-state-manager
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Versions
|
|
14
|
-
| Version | Option |
|
|
15
|
-
|----------|-----------------------------|
|
|
16
|
-
| ^0.0.4 | Angular 19. |
|
|
17
14
|
|
|
15
|
+
| Version | Option |
|
|
16
|
+
| ------- | --------------------------------------------- |
|
|
17
|
+
| ^0.0.4 | Angular 19. |
|
|
18
|
+
| ^1.0.0 | Added angular support from ^18.0.0 to ^21.0.0,|
|
|
19
|
+
| | and converted to use signals. |
|
|
18
20
|
## Usage
|
|
19
21
|
|
|
22
|
+
EasyStateManagerService (Signals Version)
|
|
23
|
+
A lightweight and resilient state management service for Angular using Signals. It supports dynamic keys, immutable updates, and persistent subscriptions.
|
|
24
|
+
|
|
20
25
|
1. **Import the EasyStateManagerService**
|
|
26
|
+
This library now supports Angular Signals for better performance. However, the classic Observable-based version is still available for backward compatibility.
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
Signals Version (Recommended for Angular 16+)
|
|
23
29
|
|
|
24
30
|
app.module.ts
|
|
25
31
|
|
|
@@ -27,111 +33,173 @@ app.module.ts
|
|
|
27
33
|
import { EasyStateManagerService } from "ngx-easy-state-manage";
|
|
28
34
|
|
|
29
35
|
@NgModule({
|
|
30
|
-
providers: [
|
|
36
|
+
providers: [EasyStateManagerService], // Simplified registration
|
|
31
37
|
})
|
|
32
38
|
export class AppModule {}
|
|
33
39
|
```
|
|
40
|
+
Observable Version (Classic)
|
|
41
|
+
If you prefer using RxJS Observables, use the original service:
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
```typescript
|
|
44
|
+
import { EasyStateManagerService } from "ngx-easy-state-manage";
|
|
45
|
+
|
|
46
|
+
@NgModule({
|
|
47
|
+
providers: [EasyStateManagerService],
|
|
48
|
+
})
|
|
49
|
+
export class AppModule {}
|
|
50
|
+
```
|
|
36
51
|
|
|
37
|
-
Inject
|
|
52
|
+
2. **Inject the Service**
|
|
53
|
+
Inject the service into your component or another service:
|
|
38
54
|
|
|
39
55
|
```typescript
|
|
40
56
|
constructor(private easyStateManager: EasyStateManagerService) {}
|
|
41
57
|
```
|
|
42
58
|
|
|
43
59
|
3. **Assign State**
|
|
44
|
-
|
|
45
|
-
You can assign a new state using the assignState method. Optionally, you can also associate the state with a specific component name.
|
|
60
|
+
Create or update state using assignState. It automatically handles Immutable updates for objects and arrays (creating new references to trigger change detection).
|
|
46
61
|
|
|
47
62
|
```typescript
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
// Assign a primitive
|
|
64
|
+
this.easyStateManager.assignState("title", "My App");
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
// Assign/Update an object (performs a shallow merge)
|
|
67
|
+
this.easyStateManager.assignState("user", { id: 1, name: "John" });
|
|
68
|
+
```
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
4. **Retrieve State (Snapshot)**
|
|
71
|
+
To get the current value of a state key once (without subscription), use getState:
|
|
54
72
|
|
|
55
73
|
```typescript
|
|
56
|
-
const
|
|
57
|
-
console.log(
|
|
74
|
+
const currentTitle = this.easyStateManager.getState<string>("title");
|
|
75
|
+
console.log(currentTitle); // Output: 'My App'
|
|
58
76
|
```
|
|
59
77
|
|
|
60
|
-
5. **Subscribe to State Changes**
|
|
61
|
-
|
|
62
|
-
You can subscribe to state changes using the selectStateChange method, which returns an Observable.
|
|
78
|
+
5. **Subscribe to State Changes (Signals)**
|
|
79
|
+
The selectStateChange method returns a Read-only Signal. It is "resilient": if you delete the key and recreate it later, the signal will automatically reconnect and provide the new values.
|
|
63
80
|
|
|
64
81
|
```typescript
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
// In your component
|
|
83
|
+
public title = this.easyStateManager.selectStateChange<string>("title");
|
|
84
|
+
|
|
85
|
+
constructor() {
|
|
86
|
+
effect(() => {
|
|
87
|
+
console.log("Title updated:", this.title());
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
In your HTML template:
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<h1>{{ title() || 'Loading...' }}</h1>
|
|
68
96
|
```
|
|
69
97
|
|
|
70
98
|
6. **Delete State**
|
|
71
99
|
|
|
72
|
-
To
|
|
100
|
+
To remove a state key. All active subscribers to this key will immediately receive null.
|
|
73
101
|
|
|
74
102
|
```typescript
|
|
75
|
-
this.easyStateManager.deleteState("
|
|
103
|
+
this.easyStateManager.deleteState("title");
|
|
76
104
|
```
|
|
77
105
|
|
|
78
|
-
|
|
106
|
+
7. **Clear All**
|
|
107
|
+
To reset the entire store and notify all active subscribers.
|
|
79
108
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
getState(key?: string): any
|
|
84
|
-
Retrieves the current value of the state associated with the specified key.
|
|
109
|
+
```typescript
|
|
110
|
+
this.easyStateManager.clearAll();
|
|
111
|
+
```
|
|
85
112
|
|
|
86
|
-
|
|
87
|
-
Returns an Observable that emits whenever the state associated with the specified key changes.
|
|
113
|
+
## API
|
|
88
114
|
|
|
115
|
+
assignState<T>(key: string, value: T): void
|
|
116
|
+
Assigns a value to the state.
|
|
117
|
+
Immutable updates: If the value is an object or an array, the service creates a new reference (shallow copy) to ensure Angular's change detection is triggered.
|
|
118
|
+
Dynamic: If the key doesn't exist, it will be created.
|
|
119
|
+
selectStateChange<T>(key: string): Signal<T | null>
|
|
120
|
+
Returns a Read-only Signal for the specified key.
|
|
121
|
+
Resilient: If the state is deleted and then recreated with the same key, this signal will automatically "reconnect" to the new value.
|
|
122
|
+
Reactive: Perfect for use in templates or effect(). Returns null if the key does not exist or was deleted.
|
|
123
|
+
getState<T>(key: string): T | null
|
|
124
|
+
Retrieves a snapshot of the current value associated with the specified key.
|
|
125
|
+
Does not create a subscription.
|
|
126
|
+
Returns null if the key is not found.
|
|
89
127
|
deleteState(key: string): void
|
|
90
|
-
|
|
128
|
+
Removes the state associated with the specified key.
|
|
129
|
+
All active signals created via selectStateChange for this key will be updated to null.
|
|
130
|
+
clearAll(): void
|
|
131
|
+
Completely resets the store.
|
|
132
|
+
All keys are removed, and all active subscribers are notified with null.
|
|
133
|
+
|
|
134
|
+
| Feature | EasyStateManagerServiceSignal | EasyStateManagerService |
|
|
135
|
+
|----------------------------------------------------------------------------|
|
|
136
|
+
|Reactive Type | Signal<T> | Observable<T> |
|
|
137
|
+
|Update Logic |Immutable (Shallow Copy) | Direct / Manual |
|
|
138
|
+
|Resilience |Reconnects after deleteState | Subscription ends on delete*|
|
|
139
|
+
|Template Usage| {{ state() }} | `${{state}}` |
|
|
140
|
+
|
|
141
|
+
Note: The new EasyStateManagerServiceSignal is specifically designed to work with Angular's new reactivity model.
|
|
142
|
+
It provides "resilient" connections, meaning if a key is deleted and recreated, your UI components will automatically pick up the new value without needing to re-subscribe.
|
|
91
143
|
|
|
92
144
|
## Example
|
|
93
145
|
|
|
94
|
-
stateTypes
|
|
146
|
+
stateTypes.ts
|
|
95
147
|
|
|
96
148
|
```typescript
|
|
97
149
|
export const SELECTED_EMOJI = "selectedEmoji";
|
|
150
|
+
|
|
151
|
+
export interface EmojiState {
|
|
152
|
+
emoji: string;
|
|
153
|
+
}
|
|
98
154
|
```
|
|
99
155
|
|
|
100
156
|
app.compoinent
|
|
101
157
|
|
|
102
158
|
```typescript
|
|
103
|
-
import { Component,
|
|
159
|
+
import { Component, effect, Signal } from "@angular/core";
|
|
104
160
|
import { EmojiPicker } from "ngx-easy-emoji-picker";
|
|
105
|
-
import { EasyStateManagerService } from "ngx-easy-state-
|
|
106
|
-
|
|
107
|
-
import { SELECTED_EMOJI } from "./stateTypes";
|
|
161
|
+
import { EasyStateManagerService } from "ngx-easy-state-manage";
|
|
162
|
+
import { SELECTED_EMOJI, EmojiState } from "./stateTypes";
|
|
108
163
|
|
|
109
164
|
@Component({
|
|
110
165
|
selector: "app-root",
|
|
111
166
|
standalone: true,
|
|
112
167
|
imports: [EmojiPicker],
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
168
|
+
template: `
|
|
169
|
+
<!-- Direct usage of signal in template -->
|
|
170
|
+
<div class="display">Selected: {{ emojiState()?.emoji || "None" }}</div>
|
|
171
|
+
|
|
172
|
+
<ngx-easy-emoji-picker (onEmojiSelected)="onEmojiSelected($event)">
|
|
173
|
+
</ngx-easy-emoji-picker>
|
|
174
|
+
`,
|
|
175
|
+
// Service is providedIn: 'root', but can be added to providers if needed locally
|
|
116
176
|
})
|
|
117
|
-
export class AppComponent
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
177
|
+
export class AppComponent {
|
|
178
|
+
// 1. Get a Read-only Signal for the state
|
|
179
|
+
public emojiState: Signal<EmojiState | null>;
|
|
180
|
+
|
|
181
|
+
constructor(private _stateManager: EasyStateManagerService) {
|
|
182
|
+
this.emojiState =
|
|
183
|
+
this._stateManager.selectStateChange<EmojiState>(SELECTED_EMOJI);
|
|
184
|
+
|
|
185
|
+
// 2. React to changes in logic (optional)
|
|
186
|
+
effect(() => {
|
|
187
|
+
const current = this.emojiState();
|
|
188
|
+
if (current) {
|
|
189
|
+
console.log("Emoji updated in state:", current.emoji);
|
|
190
|
+
}
|
|
129
191
|
});
|
|
130
192
|
}
|
|
131
193
|
|
|
132
194
|
onEmojiSelected(emoji: string) {
|
|
195
|
+
// 3. Assign new state (it will trigger the signal above)
|
|
133
196
|
this._stateManager.assignState(SELECTED_EMOJI, { emoji: emoji });
|
|
134
197
|
}
|
|
198
|
+
|
|
199
|
+
removeEmoji() {
|
|
200
|
+
// 4. Delete state - emojiState() will automatically become 'null'
|
|
201
|
+
this._stateManager.deleteState(SELECTED_EMOJI);
|
|
202
|
+
}
|
|
135
203
|
}
|
|
136
204
|
```
|
|
137
205
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
2
|
+
import { Injectable, signal, computed } from '@angular/core';
|
|
3
3
|
import { BehaviorSubject } from 'rxjs';
|
|
4
4
|
|
|
5
5
|
class EasyStateManagerService {
|
|
@@ -37,16 +37,103 @@ class EasyStateManagerService {
|
|
|
37
37
|
delete this._store[key];
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
41
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
40
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
41
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerService, providedIn: "root" }); }
|
|
42
42
|
}
|
|
43
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
43
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerService, decorators: [{
|
|
44
44
|
type: Injectable,
|
|
45
45
|
args: [{
|
|
46
46
|
providedIn: "root",
|
|
47
47
|
}]
|
|
48
48
|
}] });
|
|
49
49
|
|
|
50
|
+
class EasyStateManagerServiceSignal {
|
|
51
|
+
constructor() {
|
|
52
|
+
/**
|
|
53
|
+
* Main store holding signals for each state key.
|
|
54
|
+
* Wrapped in a signal to track adding/removing keys dynamically.
|
|
55
|
+
*/
|
|
56
|
+
this._store = signal({}, ...(ngDevMode ? [{ debugName: "_store" }] : []));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sets or updates state for a specific key.
|
|
60
|
+
* Implements immutable update logic for objects and arrays to ensure change detection.
|
|
61
|
+
* @param key Unique identifier for the state slice.
|
|
62
|
+
* @param value New value to assign or merge.
|
|
63
|
+
*/
|
|
64
|
+
assignState(key, value) {
|
|
65
|
+
const currentStore = this._store();
|
|
66
|
+
const existingSignal = currentStore[key];
|
|
67
|
+
if (existingSignal) {
|
|
68
|
+
// If signal exists, update its value using immutable patterns
|
|
69
|
+
existingSignal.update(oldValue => {
|
|
70
|
+
if (Array.isArray(value))
|
|
71
|
+
return [...value];
|
|
72
|
+
if (value !== null && typeof value === 'object') {
|
|
73
|
+
return { ...oldValue, ...value };
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Create a new signal and trigger store structure update
|
|
80
|
+
const newSignal = signal(value, ...(ngDevMode ? [{ debugName: "newSignal" }] : []));
|
|
81
|
+
this._store.update(store => ({
|
|
82
|
+
...store,
|
|
83
|
+
[key]: newSignal
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns a "resilient" Read-only signal for a specific key.
|
|
89
|
+
* It tracks the store structure: if a key is deleted and recreated,
|
|
90
|
+
* the subscriber automatically reconnects to the new signal.
|
|
91
|
+
* @param key Key to watch.
|
|
92
|
+
*/
|
|
93
|
+
selectStateChange(key) {
|
|
94
|
+
return computed(() => {
|
|
95
|
+
// Subscribes to the store's dictionary changes
|
|
96
|
+
const s = this._store()[key];
|
|
97
|
+
// Returns signal value if key exists, otherwise null
|
|
98
|
+
return s ? s() : null;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns a current snapshot of the state without subscription.
|
|
103
|
+
*/
|
|
104
|
+
getState(key) {
|
|
105
|
+
const s = this._store()[key];
|
|
106
|
+
return s ? s() : null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Removes a key from the store.
|
|
110
|
+
* All subscribers to this key will immediately receive 'null'.
|
|
111
|
+
*/
|
|
112
|
+
deleteState(key) {
|
|
113
|
+
if (this._store()[key]) {
|
|
114
|
+
this._store.update(store => {
|
|
115
|
+
const newStore = { ...store };
|
|
116
|
+
delete newStore[key];
|
|
117
|
+
return newStore;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resets the entire store to an empty state.
|
|
123
|
+
*/
|
|
124
|
+
clearAll() {
|
|
125
|
+
this._store.set({});
|
|
126
|
+
}
|
|
127
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerServiceSignal, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
128
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerServiceSignal, providedIn: 'root' }); }
|
|
129
|
+
}
|
|
130
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: EasyStateManagerServiceSignal, decorators: [{
|
|
131
|
+
type: Injectable,
|
|
132
|
+
args: [{
|
|
133
|
+
providedIn: 'root'
|
|
134
|
+
}]
|
|
135
|
+
}] });
|
|
136
|
+
|
|
50
137
|
/*
|
|
51
138
|
* Public API Surface of ngx-easy-state-manager
|
|
52
139
|
*/
|
|
@@ -55,5 +142,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
|
|
|
55
142
|
* Generated bundle index. Do not edit.
|
|
56
143
|
*/
|
|
57
144
|
|
|
58
|
-
export { EasyStateManagerService };
|
|
145
|
+
export { EasyStateManagerService, EasyStateManagerServiceSignal };
|
|
59
146
|
//# sourceMappingURL=ngx-easy-state-manager.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-easy-state-manager.mjs","sources":["../../../projects/ngx-easy-state-manager/src/lib/ngx-easy-state-manager.service.ts","../../../projects/ngx-easy-state-manager/src/public-api.ts","../../../projects/ngx-easy-state-manager/src/ngx-easy-state-manager.ts"],"sourcesContent":["import { Injectable } from \"@angular/core\";\r\nimport { BehaviorSubject
|
|
1
|
+
{"version":3,"file":"ngx-easy-state-manager.mjs","sources":["../../../projects/ngx-easy-state-manager/src/lib/ngx-easy-state-manager.service.ts","../../../projects/ngx-easy-state-manager/src/lib/ngx-easy-state-manager-signal.service.ts","../../../projects/ngx-easy-state-manager/src/public-api.ts","../../../projects/ngx-easy-state-manager/src/ngx-easy-state-manager.ts"],"sourcesContent":["import { Injectable } from \"@angular/core\";\r\nimport { BehaviorSubject } from \"rxjs\";\r\n\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\nexport class EasyStateManagerService {\r\n private _store: Store = {};\r\n\r\n public assignState<T>(key: string, value: T): void {\r\n if (key in this._store) {\r\n const storeValue = this._store[key].value;\r\n // check type mismatch\r\n if (storeValue && typeof storeValue !== typeof value) {\r\n throw new Error(\r\n `Type mismatch: ${typeof this._store[key].value} !== ${typeof value}`\r\n );\r\n }\r\n\r\n this._store[key].next(value);\r\n } else {\r\n this._store[key] = new BehaviorSubject<T>(value);\r\n }\r\n }\r\n\r\n public getState<T>(key?: string): T | undefined {\r\n if (key && key in this._store) {\r\n return this._store[key].value;\r\n }\r\n return undefined;\r\n }\r\n\r\n public selectStateChange<T>(key: string): BehaviorSubject<any> {\r\n if (key in this._store) {\r\n return this._store[key] as BehaviorSubject<T>;\r\n }\r\n\r\n this._store[key] = new BehaviorSubject<T>(null as T);\r\n\r\n return this._store[key];\r\n }\r\n\r\n public deleteState(key: string): void {\r\n if (key in this._store) {\r\n delete this._store[key];\r\n }\r\n }\r\n}\r\n\r\ntype Store = {\r\n [key: string]: BehaviorSubject<any>;\r\n};\r\n","import { Injectable, signal, computed, Signal, WritableSignal } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class EasyStateManagerServiceSignal {\r\n /**\r\n * Main store holding signals for each state key.\r\n * Wrapped in a signal to track adding/removing keys dynamically.\r\n */\r\n private readonly _store = signal<Record<string, WritableSignal<any>>>({});\r\n\r\n /**\r\n * Sets or updates state for a specific key.\r\n * Implements immutable update logic for objects and arrays to ensure change detection.\r\n * @param key Unique identifier for the state slice.\r\n * @param value New value to assign or merge.\r\n */\r\n public assignState<T>(key: string, value: T): void {\r\n const currentStore = this._store();\r\n const existingSignal = currentStore[key];\r\n\r\n if (existingSignal) {\r\n // If signal exists, update its value using immutable patterns\r\n existingSignal.update(oldValue => {\r\n if (Array.isArray(value)) return [...value];\r\n if (value !== null && typeof value === 'object') {\r\n return { ...oldValue, ...value };\r\n }\r\n return value;\r\n });\r\n } else {\r\n // Create a new signal and trigger store structure update\r\n const newSignal = signal(value);\r\n this._store.update(store => ({\r\n ...store,\r\n [key]: newSignal\r\n }));\r\n }\r\n }\r\n\r\n /**\r\n * Returns a \"resilient\" Read-only signal for a specific key.\r\n * It tracks the store structure: if a key is deleted and recreated, \r\n * the subscriber automatically reconnects to the new signal.\r\n * @param key Key to watch.\r\n */\r\n public selectStateChange<T>(key: string): Signal<T | null> {\r\n return computed(() => {\r\n // Subscribes to the store's dictionary changes\r\n const s = this._store()[key];\r\n // Returns signal value if key exists, otherwise null\r\n return s ? s() : null;\r\n });\r\n }\r\n\r\n /**\r\n * Returns a current snapshot of the state without subscription.\r\n */\r\n public getState<T>(key: string): T | null {\r\n const s = this._store()[key];\r\n return s ? s() : null;\r\n }\r\n\r\n /**\r\n * Removes a key from the store.\r\n * All subscribers to this key will immediately receive 'null'.\r\n */\r\n public deleteState(key: string): void {\r\n if (this._store()[key]) {\r\n this._store.update(store => {\r\n const newStore = { ...store };\r\n delete newStore[key];\r\n return newStore;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Resets the entire store to an empty state.\r\n */\r\n public clearAll(): void {\r\n this._store.set({});\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngx-easy-state-manager\r\n */\r\n\r\nexport * from './lib/ngx-easy-state-manager.service';\r\nexport * from './lib/ngx-easy-state-manager-signal.service';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { Signal } from '@angular/core';
|
|
4
|
+
|
|
5
|
+
declare class EasyStateManagerService {
|
|
6
|
+
private _store;
|
|
7
|
+
assignState<T>(key: string, value: T): void;
|
|
8
|
+
getState<T>(key?: string): T | undefined;
|
|
9
|
+
selectStateChange<T>(key: string): BehaviorSubject<any>;
|
|
10
|
+
deleteState(key: string): void;
|
|
11
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EasyStateManagerService, never>;
|
|
12
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<EasyStateManagerService>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare class EasyStateManagerServiceSignal {
|
|
16
|
+
/**
|
|
17
|
+
* Main store holding signals for each state key.
|
|
18
|
+
* Wrapped in a signal to track adding/removing keys dynamically.
|
|
19
|
+
*/
|
|
20
|
+
private readonly _store;
|
|
21
|
+
/**
|
|
22
|
+
* Sets or updates state for a specific key.
|
|
23
|
+
* Implements immutable update logic for objects and arrays to ensure change detection.
|
|
24
|
+
* @param key Unique identifier for the state slice.
|
|
25
|
+
* @param value New value to assign or merge.
|
|
26
|
+
*/
|
|
27
|
+
assignState<T>(key: string, value: T): void;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a "resilient" Read-only signal for a specific key.
|
|
30
|
+
* It tracks the store structure: if a key is deleted and recreated,
|
|
31
|
+
* the subscriber automatically reconnects to the new signal.
|
|
32
|
+
* @param key Key to watch.
|
|
33
|
+
*/
|
|
34
|
+
selectStateChange<T>(key: string): Signal<T | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns a current snapshot of the state without subscription.
|
|
37
|
+
*/
|
|
38
|
+
getState<T>(key: string): T | null;
|
|
39
|
+
/**
|
|
40
|
+
* Removes a key from the store.
|
|
41
|
+
* All subscribers to this key will immediately receive 'null'.
|
|
42
|
+
*/
|
|
43
|
+
deleteState(key: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Resets the entire store to an empty state.
|
|
46
|
+
*/
|
|
47
|
+
clearAll(): void;
|
|
48
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EasyStateManagerServiceSignal, never>;
|
|
49
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<EasyStateManagerServiceSignal>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { EasyStateManagerService, EasyStateManagerServiceSignal };
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-easy-state-manager",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"author": "Alex Voronin <alex.varonin@gmail.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"peerDependencies": {
|
|
7
|
-
"@angular/common": "^19.0.0",
|
|
8
|
-
"@angular/core": "^19.0.0"
|
|
7
|
+
"@angular/common": "^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
8
|
+
"@angular/core": "^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
9
|
+
"rxjs": "^7.8.0",
|
|
10
|
+
"zone.js": "~0.14.0 || ~0.15.0"
|
|
9
11
|
},
|
|
10
12
|
"description": "ngx-easy-state-manager is a lightweight, intuitive library for managing state in Angular applications. It simplifies state management by providing a straightforward API for creating, updating, and accessing state, without the complexity of traditional approaches.",
|
|
11
13
|
"dependencies": {
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BehaviorSubject } from "rxjs";
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export declare class EasyStateManagerService {
|
|
4
|
-
private _store;
|
|
5
|
-
assignState<T>(key: string, value: T): void;
|
|
6
|
-
getState<T>(key?: string): T | undefined;
|
|
7
|
-
selectStateChange<T>(key: string): BehaviorSubject<any>;
|
|
8
|
-
deleteState(key: string): void;
|
|
9
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<EasyStateManagerService, never>;
|
|
10
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<EasyStateManagerService>;
|
|
11
|
-
}
|
package/public-api.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/ngx-easy-state-manager.service';
|