@ngstato/angular 0.1.5 → 0.3.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 +24 -24
- package/dist/README.md +24 -24
- package/dist/create-angular-store.d.ts +4 -1
- package/dist/esm2022/create-angular-store.mjs +92 -16
- package/dist/esm2022/index.mjs +2 -2
- package/dist/fesm2022/ngstato-angular.mjs +92 -16
- package/dist/fesm2022/ngstato-angular.mjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/ng-package.json +1 -0
- package/package.json +58 -39
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Stato est une librairie de gestion d'état Angular moderne pour remplacer NgRx complètement, avec une API plus simple, Signals-first, sans RxJS obligatoire.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
@@ -77,9 +77,8 @@ export const appConfig: ApplicationConfig = {
|
|
|
77
77
|
|
|
78
78
|
```ts
|
|
79
79
|
// user.store.ts
|
|
80
|
-
import { Injectable, OnDestroy, inject } from '@angular/core'
|
|
81
80
|
import { createStore, http, optimistic, retryable, connectDevTools } from '@ngstato/core'
|
|
82
|
-
import { injectStore } from '@ngstato/angular'
|
|
81
|
+
import { StatoStore, injectStore } from '@ngstato/angular'
|
|
83
82
|
|
|
84
83
|
function createUserStore() {
|
|
85
84
|
const store = createStore({
|
|
@@ -135,20 +134,10 @@ function createUserStore() {
|
|
|
135
134
|
return store
|
|
136
135
|
}
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
export
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
get users() { return this._store.users }
|
|
143
|
-
get isLoading() { return this._store.isLoading }
|
|
144
|
-
get total() { return this._store.total }
|
|
145
|
-
|
|
146
|
-
loadUsers = (...a: any[]) => this._store.loadUsers(...a)
|
|
147
|
-
deleteUser = (...a: any[]) => this._store.deleteUser(...a)
|
|
148
|
-
addUser = (...a: any[]) => this._store.addUser(...a)
|
|
149
|
-
|
|
150
|
-
ngOnDestroy() { this._store.__store__.destroy(this._store) }
|
|
151
|
-
}
|
|
137
|
+
// Injection auto + API classe sans boilerplate
|
|
138
|
+
export const UserStore = StatoStore(() => {
|
|
139
|
+
return createUserStore()
|
|
140
|
+
})
|
|
152
141
|
|
|
153
142
|
// Dans un composant
|
|
154
143
|
@Component({ ... })
|
|
@@ -169,6 +158,7 @@ export class UserListComponent {
|
|
|
169
158
|
| `retryable()` | Retry avec backoff fixe ou exponentiel | retryWhen |
|
|
170
159
|
| `fromStream()` | Écoute Observable/WebSocket/Firebase/Supabase | rxMethod + Effect |
|
|
171
160
|
| `optimistic()` | Update immédiat + rollback automatique si échec | Manuel en NgRx |
|
|
161
|
+
| `withPersist()` | Persistance state (localStorage/sessionStorage) + migration | Meta-reducers custom |
|
|
172
162
|
|
|
173
163
|
```ts
|
|
174
164
|
import { abortable, debounced, throttled, retryable, fromStream, optimistic } from '@ngstato/core'
|
|
@@ -203,6 +193,14 @@ actions: {
|
|
|
203
193
|
|
|
204
194
|
---
|
|
205
195
|
|
|
196
|
+
## Nouveautés v0.2
|
|
197
|
+
|
|
198
|
+
- `selectors` memoïzés avec recalcul ciblé
|
|
199
|
+
- `effects` réactifs explicites avec cleanup
|
|
200
|
+
- `withPersist()` pour hydrate/persist avec versioning
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
206
204
|
## Client HTTP
|
|
207
205
|
|
|
208
206
|
```ts
|
|
@@ -340,7 +338,9 @@ computed: {
|
|
|
340
338
|
|
|
341
339
|
## Demo live
|
|
342
340
|
|
|
343
|
-
|
|
341
|
+
<a href="https://stackblitz.com/github/becher/ngstato-demo" target="_blank" rel="noopener">
|
|
342
|
+
<img src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" alt="Open in StackBlitz">
|
|
343
|
+
</a>
|
|
344
344
|
|
|
345
345
|
---
|
|
346
346
|
|
|
@@ -356,18 +356,18 @@ computed: {
|
|
|
356
356
|
- Protection prod automatique via `isDevMode()`
|
|
357
357
|
- **144 tests — 100% passing**
|
|
358
358
|
|
|
359
|
-
### v0.2 —
|
|
359
|
+
### v0.2 — Selectors / Effects / Persist ✅
|
|
360
|
+
- `selectors` memoïzés
|
|
361
|
+
- `effects` réactifs avec cleanup
|
|
362
|
+
- `withPersist()` — localStorage / sessionStorage + migration
|
|
363
|
+
|
|
364
|
+
### v0.3 — Helpers avancés
|
|
360
365
|
- `exclusive()` — = exhaustMap NgRx
|
|
361
366
|
- `queued()` — = concatMap NgRx
|
|
362
367
|
- `store.on()` — réactions inter-stores
|
|
363
368
|
- Testing utilities
|
|
364
369
|
- DevTools time-travel
|
|
365
370
|
|
|
366
|
-
### v0.3 — Persistance
|
|
367
|
-
- `withPersist()` — localStorage / sessionStorage / IndexedDB
|
|
368
|
-
- `withHistory()` — undo/redo
|
|
369
|
-
- SSR ready
|
|
370
|
-
|
|
371
371
|
### v1.0 — Production ready
|
|
372
372
|
- `withEntities()`, Schematics CLI, ESLint plugin
|
|
373
373
|
- Documentation VitePress complète
|
package/dist/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Stato est une librairie de gestion d'état Angular moderne pour remplacer NgRx complètement, avec une API plus simple, Signals-first, sans RxJS obligatoire.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
@@ -77,9 +77,8 @@ export const appConfig: ApplicationConfig = {
|
|
|
77
77
|
|
|
78
78
|
```ts
|
|
79
79
|
// user.store.ts
|
|
80
|
-
import { Injectable, OnDestroy, inject } from '@angular/core'
|
|
81
80
|
import { createStore, http, optimistic, retryable, connectDevTools } from '@ngstato/core'
|
|
82
|
-
import { injectStore } from '@ngstato/angular'
|
|
81
|
+
import { StatoStore, injectStore } from '@ngstato/angular'
|
|
83
82
|
|
|
84
83
|
function createUserStore() {
|
|
85
84
|
const store = createStore({
|
|
@@ -135,20 +134,10 @@ function createUserStore() {
|
|
|
135
134
|
return store
|
|
136
135
|
}
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
export
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
get users() { return this._store.users }
|
|
143
|
-
get isLoading() { return this._store.isLoading }
|
|
144
|
-
get total() { return this._store.total }
|
|
145
|
-
|
|
146
|
-
loadUsers = (...a: any[]) => this._store.loadUsers(...a)
|
|
147
|
-
deleteUser = (...a: any[]) => this._store.deleteUser(...a)
|
|
148
|
-
addUser = (...a: any[]) => this._store.addUser(...a)
|
|
149
|
-
|
|
150
|
-
ngOnDestroy() { this._store.__store__.destroy(this._store) }
|
|
151
|
-
}
|
|
137
|
+
// Injection auto + API classe sans boilerplate
|
|
138
|
+
export const UserStore = StatoStore(() => {
|
|
139
|
+
return createUserStore()
|
|
140
|
+
})
|
|
152
141
|
|
|
153
142
|
// Dans un composant
|
|
154
143
|
@Component({ ... })
|
|
@@ -169,6 +158,7 @@ export class UserListComponent {
|
|
|
169
158
|
| `retryable()` | Retry avec backoff fixe ou exponentiel | retryWhen |
|
|
170
159
|
| `fromStream()` | Écoute Observable/WebSocket/Firebase/Supabase | rxMethod + Effect |
|
|
171
160
|
| `optimistic()` | Update immédiat + rollback automatique si échec | Manuel en NgRx |
|
|
161
|
+
| `withPersist()` | Persistance state (localStorage/sessionStorage) + migration | Meta-reducers custom |
|
|
172
162
|
|
|
173
163
|
```ts
|
|
174
164
|
import { abortable, debounced, throttled, retryable, fromStream, optimistic } from '@ngstato/core'
|
|
@@ -203,6 +193,14 @@ actions: {
|
|
|
203
193
|
|
|
204
194
|
---
|
|
205
195
|
|
|
196
|
+
## Nouveautés v0.2
|
|
197
|
+
|
|
198
|
+
- `selectors` memoïzés avec recalcul ciblé
|
|
199
|
+
- `effects` réactifs explicites avec cleanup
|
|
200
|
+
- `withPersist()` pour hydrate/persist avec versioning
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
206
204
|
## Client HTTP
|
|
207
205
|
|
|
208
206
|
```ts
|
|
@@ -340,7 +338,9 @@ computed: {
|
|
|
340
338
|
|
|
341
339
|
## Demo live
|
|
342
340
|
|
|
343
|
-
|
|
341
|
+
<a href="https://stackblitz.com/github/becher/ngstato-demo" target="_blank" rel="noopener">
|
|
342
|
+
<img src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" alt="Open in StackBlitz">
|
|
343
|
+
</a>
|
|
344
344
|
|
|
345
345
|
---
|
|
346
346
|
|
|
@@ -356,18 +356,18 @@ computed: {
|
|
|
356
356
|
- Protection prod automatique via `isDevMode()`
|
|
357
357
|
- **144 tests — 100% passing**
|
|
358
358
|
|
|
359
|
-
### v0.2 —
|
|
359
|
+
### v0.2 — Selectors / Effects / Persist ✅
|
|
360
|
+
- `selectors` memoïzés
|
|
361
|
+
- `effects` réactifs avec cleanup
|
|
362
|
+
- `withPersist()` — localStorage / sessionStorage + migration
|
|
363
|
+
|
|
364
|
+
### v0.3 — Helpers avancés
|
|
360
365
|
- `exclusive()` — = exhaustMap NgRx
|
|
361
366
|
- `queued()` — = concatMap NgRx
|
|
362
367
|
- `store.on()` — réactions inter-stores
|
|
363
368
|
- Testing utilities
|
|
364
369
|
- DevTools time-travel
|
|
365
370
|
|
|
366
|
-
### v0.3 — Persistance
|
|
367
|
-
- `withPersist()` — localStorage / sessionStorage / IndexedDB
|
|
368
|
-
- `withHistory()` — undo/redo
|
|
369
|
-
- SSR ready
|
|
370
|
-
|
|
371
371
|
### v1.0 — Production ready
|
|
372
372
|
- `withEntities()`, Schematics CLI, ESLint plugin
|
|
373
373
|
- Documentation VitePress complète
|
|
@@ -9,10 +9,13 @@ export declare class StatoStoreBase implements OnDestroy {
|
|
|
9
9
|
static ɵfac: i0.ɵɵFactoryDeclaration<StatoStoreBase, never>;
|
|
10
10
|
static ɵprov: i0.ɵɵInjectableDeclaration<StatoStoreBase>;
|
|
11
11
|
}
|
|
12
|
-
export declare function
|
|
12
|
+
export declare function StatoStoreOld<S extends object>(config: S & StatoStoreConfig<S>): {
|
|
13
13
|
new (): {
|
|
14
14
|
storeInstance: any;
|
|
15
15
|
initStore<S_1 extends object>(config: S_1 & StatoStoreConfig<S_1>): void;
|
|
16
16
|
ngOnDestroy(): void;
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
+
type ExtractStoreType<T> = Omit<T, '__store__' | '__destroy__'>;
|
|
20
|
+
export declare function StatoStore<S extends object>(factory: () => S): new () => ExtractStoreType<S> & OnDestroy;
|
|
21
|
+
export {};
|
|
@@ -56,11 +56,9 @@ export function createAngularStore(config) {
|
|
|
56
56
|
angularStore[name] = (...args) => coreStore.__store__.dispatch(name, ...args);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
// 8.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
hooks.onInit(angularStore);
|
|
63
|
-
}
|
|
59
|
+
// 8. Unifier le lifecycle avec @ngstato/core
|
|
60
|
+
// (init est idempotent: onInit ne sera appelé qu'une fois)
|
|
61
|
+
coreStore.__store__.init(angularStore);
|
|
64
62
|
// 9. Exposer destroy pour le cleanup
|
|
65
63
|
angularStore.__destroy__ = () => {
|
|
66
64
|
coreStore.__store__.destroy(angularStore);
|
|
@@ -68,8 +66,8 @@ export function createAngularStore(config) {
|
|
|
68
66
|
return angularStore;
|
|
69
67
|
}
|
|
70
68
|
// ─────────────────────────────────────────────────────
|
|
71
|
-
//
|
|
72
|
-
//
|
|
69
|
+
// OLD: StatoStoreBase (remplacée par StatoStore avec Proxy)
|
|
70
|
+
// Gardée pour backward compatibility si besoin
|
|
73
71
|
// ─────────────────────────────────────────────────────
|
|
74
72
|
export class StatoStoreBase {
|
|
75
73
|
storeInstance;
|
|
@@ -107,15 +105,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
107
105
|
type: Injectable
|
|
108
106
|
}] });
|
|
109
107
|
// ─────────────────────────────────────────────────────
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
// Usage :
|
|
113
|
-
// export class UserStore extends StatoStore({
|
|
114
|
-
// user: null,
|
|
115
|
-
// actions: { ... }
|
|
116
|
-
// }) {}
|
|
108
|
+
// OLD: Config-based StatoStore (deprecated)
|
|
109
|
+
// Gardée pour backward compatibility
|
|
117
110
|
// ─────────────────────────────────────────────────────
|
|
118
|
-
export function
|
|
111
|
+
export function StatoStoreOld(config) {
|
|
119
112
|
class ConcreteStore extends StatoStoreBase {
|
|
120
113
|
constructor() {
|
|
121
114
|
super();
|
|
@@ -130,4 +123,87 @@ export function StatoStore(config) {
|
|
|
130
123
|
}], ctorParameters: () => [] });
|
|
131
124
|
return ConcreteStore;
|
|
132
125
|
}
|
|
133
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWFuZ3VsYXItc3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY3JlYXRlLWFuZ3VsYXItc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0RBQXdEO0FBQ3hELDBDQUEwQztBQUMxQyw0REFBNEQ7QUFDNUQsd0RBQXdEO0FBRXhELE9BQU8sRUFDTCxNQUFNLEVBQ04sUUFBUSxFQUNSLFVBQVUsRUFHWCxNQUFNLGVBQWUsQ0FBQTtBQUV0QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFBOztBQUczQyx3REFBd0Q7QUFDeEQsNkNBQTZDO0FBQzdDLHdEQUF3RDtBQUV4RCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLE1BQStCO0lBRS9CLHlCQUF5QjtJQUN6QixNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFckMsb0RBQW9EO0lBQ3BELE1BQU0sT0FBTyxHQUE4QyxFQUFFLENBQUE7SUFDN0QsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBRXpDLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFzQixDQUFDLEVBQUUsQ0FBQztRQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFFLFlBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUNuRCxDQUFDO0lBRUQsaURBQWlEO0lBQ2pELFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFhLEVBQUUsRUFBRTtRQUNwQyxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN4QyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNqQixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1lB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gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBAbmdzdGF0by9hbmd1bGFyIOKAlCBjcmVhdGVBbmd1bGFyU3RvcmUoKVxyXG4vLyBUcmFuc2Zvcm1lIHVuIG5nc3RhdG8gc3RvcmUgZW4gc3RvcmUgQW5ndWxhciBhdmVjIFNpZ25hbHNcclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG5pbXBvcnQge1xyXG4gIHNpZ25hbCxcclxuICBjb21wdXRlZCxcclxuICBJbmplY3RhYmxlLFxyXG4gIE9uRGVzdHJveSxcclxuICBTaWduYWxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5cclxuaW1wb3J0IHsgY3JlYXRlU3RvcmUgfSBmcm9tICdAbmdzdGF0by9jb3JlJ1xyXG5pbXBvcnQgdHlwZSB7IFN0YXRvU3RvcmVDb25maWcgfSBmcm9tICdAbmdzdGF0by9jb3JlJ1xyXG5cclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbi8vIEZPTkNUSU9OIFBSSU5DSVBBTEUg4oCUIGNyZWF0ZUFuZ3VsYXJTdG9yZSgpXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFuZ3VsYXJTdG9yZTxTIGV4dGVuZHMgb2JqZWN0PihcclxuICBjb25maWc6IFMgJiBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbikge1xyXG4gIC8vIDEuIENyw6llciBsZSBzdG9yZSBjb3JlXHJcbiAgY29uc3QgY29yZVN0b3JlID0gY3JlYXRlU3RvcmUoY29uZmlnKVxyXG5cclxuICAvLyAyLiBDcsOpZXIgdW4gU2lnbmFsIHBvdXIgY2hhcXVlIHByb3ByacOpdMOpIGR1IHN0YXRlXHJcbiAgY29uc3Qgc2lnbmFsczogUmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2Ygc2lnbmFsPj4gPSB7fVxyXG4gIGNvbnN0IGluaXRpYWxTdGF0ZSA9IGNvcmVTdG9yZS5nZXRTdGF0ZSgpXHJcblxyXG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGluaXRpYWxTdGF0ZSBhcyBvYmplY3QpKSB7XHJcbiAgICBzaWduYWxzW2tleV0gPSBzaWduYWwoKGluaXRpYWxTdGF0ZSBhcyBhbnkpW2tleV0pXHJcbiAgfVxyXG5cclxuICAvLyAzLiBTeW5jaHJvbmlzZXIgbGVzIFNpZ25hbHMgYXZlYyBsZSBzdGF0ZSBjb3JlXHJcbiAgY29yZVN0b3JlLnN1YnNjcmliZSgobmV3U3RhdGU6IGFueSkgPT4ge1xyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMobmV3U3RhdGUpKSB7XHJcbiAgICAgIGlmIChzaWduYWxzW2tleV0pIHtcclxuICAgICAgICBzaWduYWxzW2tleV0uc2V0KG5ld1N0YXRlW2tleV0pXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KVxyXG5cclxuICAvLyA0LiBDb25zdHJ1aXJlIGwgb2JqZXQgcHVibGljIEFuZ3VsYXJcclxuICBjb25zdCBhbmd1bGFyU3RvcmU6IGFueSA9IHtcclxuICAgIF9fc3RvcmVfXzogY29yZVN0b3JlLl9fc3RvcmVfX1xyXG4gIH1cclxuXHJcbiAgLy8gNS4gRXhwb3NlciBjaGFxdWUgcHJvcHJpw6l0w6kgY29tbWUgU2lnbmFsXHJcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaW5pdGlhbFN0YXRlIGFzIG9iamVjdCkpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhbmd1bGFyU3RvcmUsIGtleSwge1xyXG4gICAgICBnZXQ6ICAgICAgICAgICgpID0+IHNpZ25hbHNba2V5XSxcclxuICAgICAgZW51bWVyYWJsZTogICB0cnVlLFxyXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICAvLyA2LiBFeHBvc2VyIGNoYXF1ZSBjb21wdXRlZCBjb21tZSBTaWduYWwgY29tcHV0ZWRcclxuICBjb25zdCB7IGNvbXB1dGVkOiBjb21wdXRlZENvbmZpZyB9ID0gY29uZmlnIGFzIFN0YXRvU3RvcmVDb25maWc8Uz5cclxuICBpZiAoY29tcHV0ZWRDb25maWcpIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbXB1dGVkQ29uZmlnKSkge1xyXG4gICAgICBjb25zdCBjb21wdXRlZFNpZ25hbCA9IGNvbXB1dGVkKCgpID0+IGNvcmVTdG9yZVtrZXldKVxyXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYW5ndWxhclN0b3JlLCBrZXksIHtcclxuICAgICAgICBnZXQ6ICAgICAgICAgICgpID0+IGNvbXB1dGVkU2lnbmFsLFxyXG4gICAgICAgIGVudW1lcmFibGU6ICAgdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIDcuIEV4cG9zZXIgY2hhcXVlIGFjdGlvbiBkaXJlY3RlbWVudFxyXG4gIGNvbnN0IHsgYWN0aW9ucyB9ID0gY29uZmlnIGFzIFN0YXRvU3RvcmVDb25maWc8Uz5cclxuICBpZiAoYWN0aW9ucykge1xyXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGFjdGlvbnMpKSB7XHJcbiAgICAgIGFuZ3VsYXJTdG9yZVtuYW1lXSA9ICguLi5hcmdzOiB1bmtub3duW10pID0+XHJcbiAgICAgICAgY29yZVN0b3JlLl9fc3RvcmVfXy5kaXNwYXRjaChuYW1lLCAuLi5hcmdzKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gOC4gQXBwZWxlciBvbkluaXQgc2kgZMOpZmluaVxyXG4gIGNvbnN0IHsgaG9va3MgfSA9IGNvbmZpZyBhcyBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbiAgaWYgKGhvb2tzPy5vbkluaXQpIHtcclxuICAgIGhvb2tzLm9uSW5pdChhbmd1bGFyU3RvcmUpXHJcbiAgfVxyXG5cclxuICAvLyA5LiBFeHBvc2VyIGRlc3Ryb3kgcG91ciBsZSBjbGVhbnVwXHJcbiAgYW5ndWxhclN0b3JlLl9fZGVzdHJveV9fID0gKCkgPT4ge1xyXG4gICAgY29yZVN0b3JlLl9fc3RvcmVfXy5kZXN0cm95KGFuZ3VsYXJTdG9yZSlcclxuICB9XHJcblxyXG4gIHJldHVybiBhbmd1bGFyU3RvcmVcclxufVxyXG5cclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbi8vIENMQVNTRSBERSBCQVNFIOKAlCDDqXRlbmR1ZSBwYXIgU3RhdG9TdG9yZSgpXHJcbi8vIFB1YmxpcXVlIOKAlCBwYXMgZGUgbWVtYnJlcyBwcml2w6lzXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBTdGF0b1N0b3JlQmFzZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcbiAgc3RvcmVJbnN0YW5jZTogYW55XHJcblxyXG4gIGluaXRTdG9yZTxTIGV4dGVuZHMgb2JqZWN0Pihjb25maWc6IFMgJiBTdGF0b1N0b3JlQ29uZmlnPFM+KSB7XHJcbiAgICB0aGlzLnN0b3JlSW5zdGFuY2UgPSBjcmVhdGVBbmd1bGFyU3RvcmUoY29uZmlnKVxyXG5cclxuICAgIC8vIENvcGllciB0b3V0ZXMgbGVzIHByb3ByacOpdMOpcyBzdXIgdGhpc1xyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5zdG9yZUluc3RhbmNlKSkge1xyXG4gICAgICBpZiAoa2V5ICE9PSAnX19zdG9yZV9fJyAmJiBrZXkgIT09ICdfX2Rlc3Ryb3lfXycpIHtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XHJcbiAgICAgICAgICBnZXQ6ICAgICAgICAgICgpID0+IHRoaXMuc3RvcmVJbnN0YW5jZVtrZXldLFxyXG4gICAgICAgICAgZW51bWVyYWJsZTogICB0cnVlLFxyXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENvcGllciBsZXMgYWN0aW9uc1xyXG4gICAgY29uc3QgeyBhY3Rpb25zIH0gPSBjb25maWcgYXMgU3RhdG9TdG9yZUNvbmZpZzxTPlxyXG4gICAgaWYgKGFjdGlvbnMpIHtcclxuICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhhY3Rpb25zKSkge1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBuYW1lLCB7XHJcbiAgICAgICAgZ2V0OiAgICAgICAgICAoKSA9PiB0aGlzLnN0b3JlSW5zdGFuY2VbbmFtZV0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogICB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuc3RvcmVJbnN0YW5jZT8uX19kZXN0cm95X18oKVxyXG4gIH1cclxufVxyXG5cclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbi8vIEZBQ1RPUlkg4oCUIFN0YXRvU3RvcmUoKVxyXG4vLyBDcsOpZSB1biBzZXJ2aWNlIEFuZ3VsYXIgaW5qZWN0YWJsZVxyXG4vLyBVc2FnZSA6XHJcbi8vICAgZXhwb3J0IGNsYXNzIFVzZXJTdG9yZSBleHRlbmRzIFN0YXRvU3RvcmUoe1xyXG4vLyAgICAgdXNlcjogbnVsbCxcclxuLy8gICAgIGFjdGlvbnM6IHsgLi4uIH1cclxuLy8gICB9KSB7fVxyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBTdGF0b1N0b3JlPFMgZXh0ZW5kcyBvYmplY3Q+KFxyXG4gIGNvbmZpZzogUyAmIFN0YXRvU3RvcmVDb25maWc8Uz5cclxuKSB7XHJcbiAgQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuICBjbGFzcyBDb25jcmV0ZVN0b3JlIGV4dGVuZHMgU3RhdG9TdG9yZUJhc2Uge1xyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgIHN1cGVyKClcclxuICAgICAgdGhpcy5pbml0U3RvcmUoY29uZmlnKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIENvbmNyZXRlU3RvcmVcclxufSJdfQ==
|
|
126
|
+
// ─────────────────────────────────────────────────────
|
|
127
|
+
// FACTORY — StatoStore()
|
|
128
|
+
// Crée un service Angular injectable avec auto-proxy
|
|
129
|
+
//
|
|
130
|
+
// Type-safe grâce aux génériques avancés — ZÉRO boilerplate!
|
|
131
|
+
//
|
|
132
|
+
// Usage :
|
|
133
|
+
// export class UserStore extends StatoStore(() => {
|
|
134
|
+
// const service = inject(UserService)
|
|
135
|
+
// return createUserStore(service)
|
|
136
|
+
// })
|
|
137
|
+
// // ✅ store.user, store.loadUser(), etc — tous typés auto!
|
|
138
|
+
// // ✅ Aucun "declare readonly" requis
|
|
139
|
+
// ─────────────────────────────────────────────────────
|
|
140
|
+
export function StatoStore(factory) {
|
|
141
|
+
class ConcreteStore {
|
|
142
|
+
_store;
|
|
143
|
+
constructor() {
|
|
144
|
+
// factory() est appelée dans le contexte d'injection Angular.
|
|
145
|
+
// Si factory() retourne déjà un store ngstato (createStore),
|
|
146
|
+
// on l'utilise tel quel. Sinon on le convertit via createAngularStore().
|
|
147
|
+
const produced = factory();
|
|
148
|
+
this._store = produced?.__store__ ? produced : createAngularStore(produced);
|
|
149
|
+
// Proxy dynamique: plus besoin de déclaration manuelle des getters/actions.
|
|
150
|
+
return new Proxy(this, {
|
|
151
|
+
get: (target, prop, receiver) => {
|
|
152
|
+
if (prop in target) {
|
|
153
|
+
return Reflect.get(target, prop, receiver);
|
|
154
|
+
}
|
|
155
|
+
return this._store?.[prop];
|
|
156
|
+
},
|
|
157
|
+
set: (target, prop, value, receiver) => {
|
|
158
|
+
if (prop in target) {
|
|
159
|
+
return Reflect.set(target, prop, value, receiver);
|
|
160
|
+
}
|
|
161
|
+
if (this._store && prop in this._store) {
|
|
162
|
+
this._store[prop] = value;
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
;
|
|
166
|
+
target[prop] = value;
|
|
167
|
+
return true;
|
|
168
|
+
},
|
|
169
|
+
has: (target, prop) => prop in target || prop in (this._store ?? {}),
|
|
170
|
+
ownKeys: (target) => {
|
|
171
|
+
const targetKeys = Reflect.ownKeys(target);
|
|
172
|
+
const storeKeys = this._store ? Reflect.ownKeys(this._store) : [];
|
|
173
|
+
return Array.from(new Set([...targetKeys, ...storeKeys]));
|
|
174
|
+
},
|
|
175
|
+
getOwnPropertyDescriptor: (target, prop) => {
|
|
176
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
177
|
+
if (targetDesc)
|
|
178
|
+
return targetDesc;
|
|
179
|
+
if (this._store && prop in this._store) {
|
|
180
|
+
return {
|
|
181
|
+
configurable: true,
|
|
182
|
+
enumerable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: this._store[prop]
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
ngOnDestroy() {
|
|
192
|
+
if (this._store?.__destroy__) {
|
|
193
|
+
this._store.__destroy__();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (this._store?.__store__?.destroy) {
|
|
197
|
+
this._store.__store__.destroy(this._store);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
201
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, providedIn: 'root' });
|
|
202
|
+
}
|
|
203
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, decorators: [{
|
|
204
|
+
type: Injectable,
|
|
205
|
+
args: [{ providedIn: 'root' }]
|
|
206
|
+
}], ctorParameters: () => [] });
|
|
207
|
+
return ConcreteStore;
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWFuZ3VsYXItc3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY3JlYXRlLWFuZ3VsYXItc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0RBQXdEO0FBQ3hELDBDQUEwQztBQUMxQyw0REFBNEQ7QUFDNUQsd0RBQXdEO0FBRXhELE9BQU8sRUFDTCxNQUFNLEVBQ04sUUFBUSxFQUNSLFVBQVUsRUFHWCxNQUFNLGVBQWUsQ0FBQTtBQUV0QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFBOztBQUczQyx3REFBd0Q7QUFDeEQsNkNBQTZDO0FBQzdDLHdEQUF3RDtBQUV4RCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLE1BQStCO0lBRS9CLHlCQUF5QjtJQUN6QixNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFckMsb0RBQW9EO0lBQ3BELE1BQU0sT0FBTyxHQUE4QyxFQUFFLENBQUE7SUFDN0QsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBRXpDLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFzQixDQUFDLEVBQUUsQ0FBQztRQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFFLFlBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUNuRCxDQUFDO0lBRUQsaURBQWlEO0lBQ2pELFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFhLEVBQUUsRUFBRTtRQUNwQyxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN4QyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNqQixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1lB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QUE7UUFDSixDQUFDO1FBRUQsV0FBVztZQUNULElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQTtnQkFDekIsT0FBTTtZQUNSLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQzVDLENBQUM7UUFDSCxDQUFDOzRHQTVERyxhQUFhO2dIQUFiLGFBQWEsY0FETyxNQUFNOztnR0FDMUIsYUFBYTtzQkFEbEIsVUFBVTt1QkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7O0lBZ0VsQyxPQUFPLGFBQW9CLENBQUE7Q0FDNUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuLy8gQG5nc3RhdG8vYW5ndWxhciDigJQgY3JlYXRlQW5ndWxhclN0b3JlKClcclxuLy8gVHJhbnNmb3JtZSB1biBuZ3N0YXRvIHN0b3JlIGVuIHN0b3JlIEFuZ3VsYXIgYXZlYyBTaWduYWxzXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxuaW1wb3J0IHtcclxuICBzaWduYWwsXHJcbiAgY29tcHV0ZWQsXHJcbiAgSW5qZWN0YWJsZSxcclxuICBPbkRlc3Ryb3ksXHJcbiAgU2lnbmFsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuXHJcbmltcG9ydCB7IGNyZWF0ZVN0b3JlIH0gZnJvbSAnQG5nc3RhdG8vY29yZSdcclxuaW1wb3J0IHR5cGUgeyBTdGF0b1N0b3JlQ29uZmlnIH0gZnJvbSAnQG5nc3RhdG8vY29yZSdcclxuXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBGT05DVElPTiBQUklOQ0lQQUxFIOKAlCBjcmVhdGVBbmd1bGFyU3RvcmUoKVxyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBbmd1bGFyU3RvcmU8UyBleHRlbmRzIG9iamVjdD4oXHJcbiAgY29uZmlnOiBTICYgU3RhdG9TdG9yZUNvbmZpZzxTPlxyXG4pIHtcclxuICAvLyAxLiBDcsOpZXIgbGUgc3RvcmUgY29yZVxyXG4gIGNvbnN0IGNvcmVTdG9yZSA9IGNyZWF0ZVN0b3JlKGNvbmZpZylcclxuXHJcbiAgLy8gMi4gQ3LDqWVyIHVuIFNpZ25hbCBwb3VyIGNoYXF1ZSBwcm9wcmnDqXTDqSBkdSBzdGF0ZVxyXG4gIGNvbnN0IHNpZ25hbHM6IFJlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIHNpZ25hbD4+ID0ge31cclxuICBjb25zdCBpbml0aWFsU3RhdGUgPSBjb3JlU3RvcmUuZ2V0U3RhdGUoKVxyXG5cclxuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhpbml0aWFsU3RhdGUgYXMgb2JqZWN0KSkge1xyXG4gICAgc2lnbmFsc1trZXldID0gc2lnbmFsKChpbml0aWFsU3RhdGUgYXMgYW55KVtrZXldKVxyXG4gIH1cclxuXHJcbiAgLy8gMy4gU3luY2hyb25pc2VyIGxlcyBTaWduYWxzIGF2ZWMgbGUgc3RhdGUgY29yZVxyXG4gIGNvcmVTdG9yZS5zdWJzY3JpYmUoKG5ld1N0YXRlOiBhbnkpID0+IHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG5ld1N0YXRlKSkge1xyXG4gICAgICBpZiAoc2lnbmFsc1trZXldKSB7XHJcbiAgICAgICAgc2lnbmFsc1trZXldLnNldChuZXdTdGF0ZVtrZXldKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSlcclxuXHJcbiAgLy8gNC4gQ29uc3RydWlyZSBsIG9iamV0IHB1YmxpYyBBbmd1bGFyXHJcbiAgY29uc3QgYW5ndWxhclN0b3JlOiBhbnkgPSB7XHJcbiAgICBfX3N0b3JlX186IGNvcmVTdG9yZS5fX3N0b3JlX19cclxuICB9XHJcblxyXG4gIC8vIDUuIEV4cG9zZXIgY2hhcXVlIHByb3ByacOpdMOpIGNvbW1lIFNpZ25hbFxyXG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGluaXRpYWxTdGF0ZSBhcyBvYmplY3QpKSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYW5ndWxhclN0b3JlLCBrZXksIHtcclxuICAgICAgZ2V0OiAgICAgICAgICAoKSA9PiBzaWduYWxzW2tleV0sXHJcbiAgICAgIGVudW1lcmFibGU6ICAgdHJ1ZSxcclxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgLy8gNi4gRXhwb3NlciBjaGFxdWUgY29tcHV0ZWQgY29tbWUgU2lnbmFsIGNvbXB1dGVkXHJcbiAgY29uc3QgeyBjb21wdXRlZDogY29tcHV0ZWRDb25maWcgfSA9IGNvbmZpZyBhcyBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbiAgaWYgKGNvbXB1dGVkQ29uZmlnKSB7XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhjb21wdXRlZENvbmZpZykpIHtcclxuICAgICAgY29uc3QgY29tcHV0ZWRTaWduYWwgPSBjb21wdXRlZCgoKSA9PiBjb3JlU3RvcmVba2V5XSlcclxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFuZ3VsYXJTdG9yZSwga2V5LCB7XHJcbiAgICAgICAgZ2V0OiAgICAgICAgICAoKSA9PiBjb21wdXRlZFNpZ25hbCxcclxuICAgICAgICBlbnVtZXJhYmxlOiAgIHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyA3LiBFeHBvc2VyIGNoYXF1ZSBhY3Rpb24gZGlyZWN0ZW1lbnRcclxuICBjb25zdCB7IGFjdGlvbnMgfSA9IGNvbmZpZyBhcyBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbiAgaWYgKGFjdGlvbnMpIHtcclxuICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhhY3Rpb25zKSkge1xyXG4gICAgICBhbmd1bGFyU3RvcmVbbmFtZV0gPSAoLi4uYXJnczogdW5rbm93bltdKSA9PlxyXG4gICAgICAgIGNvcmVTdG9yZS5fX3N0b3JlX18uZGlzcGF0Y2gobmFtZSwgLi4uYXJncylcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIDguIFVuaWZpZXIgbGUgbGlmZWN5Y2xlIGF2ZWMgQG5nc3RhdG8vY29yZVxyXG4gIC8vIChpbml0IGVzdCBpZGVtcG90ZW50OiBvbkluaXQgbmUgc2VyYSBhcHBlbMOpIHF1J3VuZSBmb2lzKVxyXG4gIGNvcmVTdG9yZS5fX3N0b3JlX18uaW5pdChhbmd1bGFyU3RvcmUpXHJcblxyXG4gIC8vIDkuIEV4cG9zZXIgZGVzdHJveSBwb3VyIGxlIGNsZWFudXBcclxuICBhbmd1bGFyU3RvcmUuX19kZXN0cm95X18gPSAoKSA9PiB7XHJcbiAgICBjb3JlU3RvcmUuX19zdG9yZV9fLmRlc3Ryb3koYW5ndWxhclN0b3JlKVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFuZ3VsYXJTdG9yZVxyXG59XHJcblxyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuLy8gT0xEOiBTdGF0b1N0b3JlQmFzZSAocmVtcGxhY8OpZSBwYXIgU3RhdG9TdG9yZSBhdmVjIFByb3h5KVxyXG4vLyBHYXJkw6llIHBvdXIgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBzaSBiZXNvaW5cclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFN0YXRvU3RvcmVCYXNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuICBzdG9yZUluc3RhbmNlOiBhbnlcclxuXHJcbiAgaW5pdFN0b3JlPFMgZXh0ZW5kcyBvYmplY3Q+KGNvbmZpZzogUyAmIFN0YXRvU3RvcmVDb25maWc8Uz4pIHtcclxuICAgIHRoaXMuc3RvcmVJbnN0YW5jZSA9IGNyZWF0ZUFuZ3VsYXJTdG9yZShjb25maWcpXHJcblxyXG4gICAgLy8gQ29waWVyIHRvdXRlcyBsZXMgcHJvcHJpw6l0w6lzIHN1ciB0aGlzXHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN0b3JlSW5zdGFuY2UpKSB7XHJcbiAgICAgIGlmIChrZXkgIT09ICdfX3N0b3JlX18nICYmIGtleSAhPT0gJ19fZGVzdHJveV9fJykge1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHtcclxuICAgICAgICAgIGdldDogICAgICAgICAgKCkgPT4gdGhpcy5zdG9yZUluc3RhbmNlW2tleV0sXHJcbiAgICAgICAgICBlbnVtZXJhYmxlOiAgIHRydWUsXHJcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29waWVyIGxlcyBhY3Rpb25zXHJcbiAgICBjb25zdCB7IGFjdGlvbnMgfSA9IGNvbmZpZyBhcyBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbiAgICBpZiAoYWN0aW9ucykge1xyXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGFjdGlvbnMpKSB7XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIG5hbWUsIHtcclxuICAgICAgICBnZXQ6ICAgICAgICAgICgpID0+IHRoaXMuc3RvcmVJbnN0YW5jZVtuYW1lXSxcclxuICAgICAgICBlbnVtZXJhYmxlOiAgIHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5zdG9yZUluc3RhbmNlPy5fX2Rlc3Ryb3lfXygpXHJcbiAgfVxyXG59XHJcblxyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuLy8gT0xEOiBDb25maWctYmFzZWQgU3RhdG9TdG9yZSAoZGVwcmVjYXRlZClcclxuLy8gR2FyZMOpZSBwb3VyIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gU3RhdG9TdG9yZU9sZDxTIGV4dGVuZHMgb2JqZWN0PihcclxuICBjb25maWc6IFMgJiBTdGF0b1N0b3JlQ29uZmlnPFM+XHJcbikge1xyXG4gIEBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbiAgY2xhc3MgQ29uY3JldGVTdG9yZSBleHRlbmRzIFN0YXRvU3RvcmVCYXNlIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICBzdXBlcigpXHJcbiAgICAgIHRoaXMuaW5pdFN0b3JlKGNvbmZpZylcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBDb25jcmV0ZVN0b3JlXHJcbn1cclxuXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBIRUxQRVIgVFlQRSDigJQgRXh0cmFpdCBhdXRvbWF0aXF1ZW1lbnQgbGVzIHR5cGVzIGR1IHN0b3JlXHJcbi8vIFBvdXIgYXV0by1pbmbDqXJlciBzdGF0ZSArIGFjdGlvbnMgKyBjb21wdXRlZCBzYW5zIGJvaWxlcnBsYXRlXHJcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG5cclxudHlwZSBFeHRyYWN0U3RvcmVUeXBlPFQ+ID0gT21pdDxULCAnX19zdG9yZV9fJyB8ICdfX2Rlc3Ryb3lfXyc+XHJcblxyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuLy8gRkFDVE9SWSDigJQgU3RhdG9TdG9yZSgpXHJcbi8vIENyw6llIHVuIHNlcnZpY2UgQW5ndWxhciBpbmplY3RhYmxlIGF2ZWMgYXV0by1wcm94eVxyXG4vL1xyXG4vLyBUeXBlLXNhZmUgZ3LDomNlIGF1eCBnw6luw6lyaXF1ZXMgYXZhbmPDqXMg4oCUIFrDiVJPIGJvaWxlcnBsYXRlIVxyXG4vL1xyXG4vLyBVc2FnZSA6XHJcbi8vICAgZXhwb3J0IGNsYXNzIFVzZXJTdG9yZSBleHRlbmRzIFN0YXRvU3RvcmUoKCkgPT4ge1xyXG4vLyAgICAgY29uc3Qgc2VydmljZSA9IGluamVjdChVc2VyU2VydmljZSlcclxuLy8gICAgIHJldHVybiBjcmVhdGVVc2VyU3RvcmUoc2VydmljZSlcclxuLy8gICB9KVxyXG4vLyAgIC8vIOKchSBzdG9yZS51c2VyLCBzdG9yZS5sb2FkVXNlcigpLCBldGMg4oCUIHRvdXMgdHlww6lzIGF1dG8hXHJcbi8vICAgLy8g4pyFIEF1Y3VuIFwiZGVjbGFyZSByZWFkb25seVwiIHJlcXVpc1xyXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBTdGF0b1N0b3JlPFMgZXh0ZW5kcyBvYmplY3Q+KFxyXG4gIGZhY3Rvcnk6ICgpID0+IFNcclxuKTogbmV3KCkgPT4gRXh0cmFjdFN0b3JlVHlwZTxTPiAmIE9uRGVzdHJveSB7XHJcbiAgQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuICBjbGFzcyBDb25jcmV0ZVN0b3JlIGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuICAgIHByaXZhdGUgX3N0b3JlOiBhbnlcclxuICAgIFtrZXk6IHN0cmluZ106IGFueVxyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAvLyBmYWN0b3J5KCkgZXN0IGFwcGVsw6llIGRhbnMgbGUgY29udGV4dGUgZCdpbmplY3Rpb24gQW5ndWxhci5cclxuICAgICAgLy8gU2kgZmFjdG9yeSgpIHJldG91cm5lIGTDqWrDoCB1biBzdG9yZSBuZ3N0YXRvIChjcmVhdGVTdG9yZSksXHJcbiAgICAgIC8vIG9uIGwndXRpbGlzZSB0ZWwgcXVlbC4gU2lub24gb24gbGUgY29udmVydGl0IHZpYSBjcmVhdGVBbmd1bGFyU3RvcmUoKS5cclxuICAgICAgY29uc3QgcHJvZHVjZWQgPSBmYWN0b3J5KCkgYXMgYW55XHJcbiAgICAgIHRoaXMuX3N0b3JlID0gcHJvZHVjZWQ/Ll9fc3RvcmVfXyA/IHByb2R1Y2VkIDogY3JlYXRlQW5ndWxhclN0b3JlKHByb2R1Y2VkKVxyXG5cclxuICAgICAgLy8gUHJveHkgZHluYW1pcXVlOiBwbHVzIGJlc29pbiBkZSBkw6ljbGFyYXRpb24gbWFudWVsbGUgZGVzIGdldHRlcnMvYWN0aW9ucy5cclxuICAgICAgcmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XHJcbiAgICAgICAgZ2V0OiAodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikgPT4ge1xyXG4gICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX3N0b3JlPy5bcHJvcCBhcyBrZXlvZiB0eXBlb2YgdGhpcy5fc3RvcmVdXHJcbiAgICAgICAgfSxcclxuICAgICAgICBzZXQ6ICh0YXJnZXQsIHByb3AsIHZhbHVlLCByZWNlaXZlcikgPT4ge1xyXG4gICAgICAgICAgaWYgKHByb3AgaW4gdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3AsIHZhbHVlLCByZWNlaXZlcilcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICh0aGlzLl9zdG9yZSAmJiBwcm9wIGluIHRoaXMuX3N0b3JlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0b3JlW3Byb3BdID0gdmFsdWVcclxuICAgICAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIDsodGFyZ2V0IGFzIGFueSlbcHJvcF0gPSB2YWx1ZVxyXG4gICAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIGhhczogKHRhcmdldCwgcHJvcCkgPT4gcHJvcCBpbiB0YXJnZXQgfHwgcHJvcCBpbiAodGhpcy5fc3RvcmUgPz8ge30pLFxyXG4gICAgICAgIG93bktleXM6ICh0YXJnZXQpID0+IHtcclxuICAgICAgICAgIGNvbnN0IHRhcmdldEtleXMgPSBSZWZsZWN0Lm93bktleXModGFyZ2V0KVxyXG4gICAgICAgICAgY29uc3Qgc3RvcmVLZXlzID0gdGhpcy5fc3RvcmUgPyBSZWZsZWN0Lm93bktleXModGhpcy5fc3RvcmUpIDogW11cclxuICAgICAgICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLnRhcmdldEtleXMsIC4uLnN0b3JlS2V5c10pKVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAodGFyZ2V0LCBwcm9wKSA9PiB7XHJcbiAgICAgICAgICBjb25zdCB0YXJnZXREZXNjID0gUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKVxyXG4gICAgICAgICAgaWYgKHRhcmdldERlc2MpIHJldHVybiB0YXJnZXREZXNjXHJcbiAgICAgICAgICBpZiAodGhpcy5fc3RvcmUgJiYgcHJvcCBpbiB0aGlzLl9zdG9yZSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICAgIHZhbHVlOiB0aGlzLl9zdG9yZVtwcm9wXVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICBpZiAodGhpcy5fc3RvcmU/Ll9fZGVzdHJveV9fKSB7XHJcbiAgICAgICAgdGhpcy5fc3RvcmUuX19kZXN0cm95X18oKVxyXG4gICAgICAgIHJldHVyblxyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLl9zdG9yZT8uX19zdG9yZV9fPy5kZXN0cm95KSB7XHJcbiAgICAgICAgdGhpcy5fc3RvcmUuX19zdG9yZV9fLmRlc3Ryb3kodGhpcy5fc3RvcmUpXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBDb25jcmV0ZVN0b3JlIGFzIGFueVxyXG59Il19
|
package/dist/esm2022/index.mjs
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
// ─────────────────────────────────────────────────────
|
|
4
4
|
export { injectStore } from './inject-store';
|
|
5
5
|
export { provideStato } from './provide-ngstato';
|
|
6
|
-
export { createAngularStore } from './create-angular-store';
|
|
6
|
+
export { createAngularStore, StatoStore } from './create-angular-store';
|
|
7
7
|
export { StatoDevToolsComponent } from './devtools.component';
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0RBQXdEO0FBQ3hELGtDQUFrQztBQUNsQyx3REFBd0Q7QUFFeEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUF5QixnQkFBZ0IsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQXdCLG1CQUFtQixDQUFBO0FBQ2xFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUV2RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBYyxzQkFBc0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4vLyBAbmdzdGF0by9hbmd1bGFyIOKAlCBBUEkgcHVibGlxdWVcclxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXHJcblxyXG5leHBvcnQgeyBpbmplY3RTdG9yZSB9ICAgICAgICAgICAgICAgICAgICBmcm9tICcuL2luamVjdC1zdG9yZSdcclxuZXhwb3J0IHsgcHJvdmlkZVN0YXRvIH0gICAgICAgICAgICAgICAgICAgZnJvbSAnLi9wcm92aWRlLW5nc3RhdG8nXHJcbmV4cG9ydCB7IGNyZWF0ZUFuZ3VsYXJTdG9yZSwgU3RhdG9TdG9yZSB9IGZyb20gJy4vY3JlYXRlLWFuZ3VsYXItc3RvcmUnXHJcbmV4cG9ydCB0eXBlIHsgU3RhdG9Bbmd1bGFyQ29uZmlnIH0gICAgICAgIGZyb20gJy4vcHJvdmlkZS1uZ3N0YXRvJ1xyXG5leHBvcnQgeyBTdGF0b0RldlRvb2xzQ29tcG9uZW50IH0gICAgICAgICBmcm9tICcuL2RldnRvb2xzLmNvbXBvbmVudCciXX0=
|
|
@@ -86,11 +86,9 @@ function createAngularStore(config) {
|
|
|
86
86
|
angularStore[name] = (...args) => coreStore.__store__.dispatch(name, ...args);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
// 8.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
hooks.onInit(angularStore);
|
|
93
|
-
}
|
|
89
|
+
// 8. Unifier le lifecycle avec @ngstato/core
|
|
90
|
+
// (init est idempotent: onInit ne sera appelé qu'une fois)
|
|
91
|
+
coreStore.__store__.init(angularStore);
|
|
94
92
|
// 9. Exposer destroy pour le cleanup
|
|
95
93
|
angularStore.__destroy__ = () => {
|
|
96
94
|
coreStore.__store__.destroy(angularStore);
|
|
@@ -98,8 +96,8 @@ function createAngularStore(config) {
|
|
|
98
96
|
return angularStore;
|
|
99
97
|
}
|
|
100
98
|
// ─────────────────────────────────────────────────────
|
|
101
|
-
//
|
|
102
|
-
//
|
|
99
|
+
// OLD: StatoStoreBase (remplacée par StatoStore avec Proxy)
|
|
100
|
+
// Gardée pour backward compatibility si besoin
|
|
103
101
|
// ─────────────────────────────────────────────────────
|
|
104
102
|
class StatoStoreBase {
|
|
105
103
|
storeInstance;
|
|
@@ -137,15 +135,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
137
135
|
type: Injectable
|
|
138
136
|
}] });
|
|
139
137
|
// ─────────────────────────────────────────────────────
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
// Usage :
|
|
143
|
-
// export class UserStore extends StatoStore({
|
|
144
|
-
// user: null,
|
|
145
|
-
// actions: { ... }
|
|
146
|
-
// }) {}
|
|
138
|
+
// OLD: Config-based StatoStore (deprecated)
|
|
139
|
+
// Gardée pour backward compatibility
|
|
147
140
|
// ─────────────────────────────────────────────────────
|
|
148
|
-
function
|
|
141
|
+
function StatoStoreOld(config) {
|
|
149
142
|
class ConcreteStore extends StatoStoreBase {
|
|
150
143
|
constructor() {
|
|
151
144
|
super();
|
|
@@ -160,6 +153,89 @@ function StatoStore(config) {
|
|
|
160
153
|
}], ctorParameters: () => [] });
|
|
161
154
|
return ConcreteStore;
|
|
162
155
|
}
|
|
156
|
+
// ─────────────────────────────────────────────────────
|
|
157
|
+
// FACTORY — StatoStore()
|
|
158
|
+
// Crée un service Angular injectable avec auto-proxy
|
|
159
|
+
//
|
|
160
|
+
// Type-safe grâce aux génériques avancés — ZÉRO boilerplate!
|
|
161
|
+
//
|
|
162
|
+
// Usage :
|
|
163
|
+
// export class UserStore extends StatoStore(() => {
|
|
164
|
+
// const service = inject(UserService)
|
|
165
|
+
// return createUserStore(service)
|
|
166
|
+
// })
|
|
167
|
+
// // ✅ store.user, store.loadUser(), etc — tous typés auto!
|
|
168
|
+
// // ✅ Aucun "declare readonly" requis
|
|
169
|
+
// ─────────────────────────────────────────────────────
|
|
170
|
+
function StatoStore(factory) {
|
|
171
|
+
class ConcreteStore {
|
|
172
|
+
_store;
|
|
173
|
+
constructor() {
|
|
174
|
+
// factory() est appelée dans le contexte d'injection Angular.
|
|
175
|
+
// Si factory() retourne déjà un store ngstato (createStore),
|
|
176
|
+
// on l'utilise tel quel. Sinon on le convertit via createAngularStore().
|
|
177
|
+
const produced = factory();
|
|
178
|
+
this._store = produced?.__store__ ? produced : createAngularStore(produced);
|
|
179
|
+
// Proxy dynamique: plus besoin de déclaration manuelle des getters/actions.
|
|
180
|
+
return new Proxy(this, {
|
|
181
|
+
get: (target, prop, receiver) => {
|
|
182
|
+
if (prop in target) {
|
|
183
|
+
return Reflect.get(target, prop, receiver);
|
|
184
|
+
}
|
|
185
|
+
return this._store?.[prop];
|
|
186
|
+
},
|
|
187
|
+
set: (target, prop, value, receiver) => {
|
|
188
|
+
if (prop in target) {
|
|
189
|
+
return Reflect.set(target, prop, value, receiver);
|
|
190
|
+
}
|
|
191
|
+
if (this._store && prop in this._store) {
|
|
192
|
+
this._store[prop] = value;
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
;
|
|
196
|
+
target[prop] = value;
|
|
197
|
+
return true;
|
|
198
|
+
},
|
|
199
|
+
has: (target, prop) => prop in target || prop in (this._store ?? {}),
|
|
200
|
+
ownKeys: (target) => {
|
|
201
|
+
const targetKeys = Reflect.ownKeys(target);
|
|
202
|
+
const storeKeys = this._store ? Reflect.ownKeys(this._store) : [];
|
|
203
|
+
return Array.from(new Set([...targetKeys, ...storeKeys]));
|
|
204
|
+
},
|
|
205
|
+
getOwnPropertyDescriptor: (target, prop) => {
|
|
206
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
207
|
+
if (targetDesc)
|
|
208
|
+
return targetDesc;
|
|
209
|
+
if (this._store && prop in this._store) {
|
|
210
|
+
return {
|
|
211
|
+
configurable: true,
|
|
212
|
+
enumerable: true,
|
|
213
|
+
writable: true,
|
|
214
|
+
value: this._store[prop]
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
ngOnDestroy() {
|
|
222
|
+
if (this._store?.__destroy__) {
|
|
223
|
+
this._store.__destroy__();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (this._store?.__store__?.destroy) {
|
|
227
|
+
this._store.__store__.destroy(this._store);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
231
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, providedIn: 'root' });
|
|
232
|
+
}
|
|
233
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ConcreteStore, decorators: [{
|
|
234
|
+
type: Injectable,
|
|
235
|
+
args: [{ providedIn: 'root' }]
|
|
236
|
+
}], ctorParameters: () => [] });
|
|
237
|
+
return ConcreteStore;
|
|
238
|
+
}
|
|
163
239
|
|
|
164
240
|
class StatoDevToolsComponent {
|
|
165
241
|
unsub;
|
|
@@ -508,5 +584,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
508
584
|
* Generated bundle index. Do not edit.
|
|
509
585
|
*/
|
|
510
586
|
|
|
511
|
-
export { StatoDevToolsComponent, createAngularStore, injectStore, provideStato };
|
|
587
|
+
export { StatoDevToolsComponent, StatoStore, createAngularStore, injectStore, provideStato };
|
|
512
588
|
//# sourceMappingURL=ngstato-angular.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngstato-angular.mjs","sources":["../../src/inject-store.ts","../../src/provide-ngstato.ts","../../src/create-angular-store.ts","../../src/devtools.component.ts","../../src/index.ts","../../src/ngstato-angular.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — injectStore()\r\n// Helper pour injecter un store dans un composant\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport { inject, type Type } from '@angular/core'\r\n\r\nexport function injectStore<T>(store: Type<T>): T {\r\n return inject(store)\r\n}","import {\r\n makeEnvironmentProviders,\r\n InjectionToken,\r\n isDevMode\r\n} from '@angular/core'\r\nimport { configureHttp, devTools } from '@ngstato/core'\r\nimport type { StatoConfig } from '@ngstato/core'\r\n\r\nexport interface StatoAngularConfig {\r\n http?: StatoConfig\r\n devtools?: boolean\r\n}\r\n\r\nexport const STATO_CONFIG = new InjectionToken<StatoAngularConfig>('STATO_CONFIG')\r\n\r\nexport function provideStato(config: StatoAngularConfig = {}) {\r\n\r\n if (config.http) {\r\n configureHttp(config.http)\r\n }\r\n\r\n // DevTools — ignorés automatiquement en production\r\n // isDevMode() est géré par Angular au build\r\n // → false en prod même si devtools: true\r\n if (config.devtools && isDevMode()) {\r\n console.info(\r\n '%c[Stato] 🛠 DevTools activés',\r\n 'background:#1e40af;color:white;padding:4px 8px;border-radius:4px;font-weight:bold'\r\n )\r\n devTools.open()\r\n }\r\n\r\n return makeEnvironmentProviders([\r\n {\r\n provide: STATO_CONFIG,\r\n useValue: config\r\n }\r\n ])\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — createAngularStore()\r\n// Transforme un ngstato store en store Angular avec Signals\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport {\r\n signal,\r\n computed,\r\n Injectable,\r\n OnDestroy,\r\n Signal\r\n} from '@angular/core'\r\n\r\nimport { createStore } from '@ngstato/core'\r\nimport type { StatoStoreConfig } from '@ngstato/core'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FONCTION PRINCIPALE — createAngularStore()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createAngularStore<S extends object>(\r\n config: S & StatoStoreConfig<S>\r\n) {\r\n // 1. Créer le store core\r\n const coreStore = createStore(config)\r\n\r\n // 2. Créer un Signal pour chaque propriété du state\r\n const signals: Record<string, ReturnType<typeof signal>> = {}\r\n const initialState = coreStore.getState()\r\n\r\n for (const key of Object.keys(initialState as object)) {\r\n signals[key] = signal((initialState as any)[key])\r\n }\r\n\r\n // 3. Synchroniser les Signals avec le state core\r\n coreStore.subscribe((newState: any) => {\r\n for (const key of Object.keys(newState)) {\r\n if (signals[key]) {\r\n signals[key].set(newState[key])\r\n }\r\n }\r\n })\r\n\r\n // 4. Construire l objet public Angular\r\n const angularStore: any = {\r\n __store__: coreStore.__store__\r\n }\r\n\r\n // 5. Exposer chaque propriété comme Signal\r\n for (const key of Object.keys(initialState as object)) {\r\n Object.defineProperty(angularStore, key, {\r\n get: () => signals[key],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n\r\n // 6. Exposer chaque computed comme Signal computed\r\n const { computed: computedConfig } = config as StatoStoreConfig<S>\r\n if (computedConfig) {\r\n for (const key of Object.keys(computedConfig)) {\r\n const computedSignal = computed(() => coreStore[key])\r\n Object.defineProperty(angularStore, key, {\r\n get: () => computedSignal,\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n // 7. Exposer chaque action directement\r\n const { actions } = config as StatoStoreConfig<S>\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n angularStore[name] = (...args: unknown[]) =>\r\n coreStore.__store__.dispatch(name, ...args)\r\n }\r\n }\r\n\r\n // 8. Appeler onInit si défini\r\n const { hooks } = config as StatoStoreConfig<S>\r\n if (hooks?.onInit) {\r\n hooks.onInit(angularStore)\r\n }\r\n\r\n // 9. Exposer destroy pour le cleanup\r\n angularStore.__destroy__ = () => {\r\n coreStore.__store__.destroy(angularStore)\r\n }\r\n\r\n return angularStore\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// CLASSE DE BASE — étendue par StatoStore()\r\n// Publique — pas de membres privés\r\n// ─────────────────────────────────────────────────────\r\n@Injectable()\r\nexport class StatoStoreBase implements OnDestroy {\r\n storeInstance: any\r\n\r\n initStore<S extends object>(config: S & StatoStoreConfig<S>) {\r\n this.storeInstance = createAngularStore(config)\r\n\r\n // Copier toutes les propriétés sur this\r\n for (const key of Object.keys(this.storeInstance)) {\r\n if (key !== '__store__' && key !== '__destroy__') {\r\n Object.defineProperty(this, key, {\r\n get: () => this.storeInstance[key],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n // Copier les actions\r\n const { actions } = config as StatoStoreConfig<S>\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n Object.defineProperty(this, name, {\r\n get: () => this.storeInstance[name],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n this.storeInstance?.__destroy__()\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY — StatoStore()\r\n// Crée un service Angular injectable\r\n// Usage :\r\n// export class UserStore extends StatoStore({\r\n// user: null,\r\n// actions: { ... }\r\n// }) {}\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function StatoStore<S extends object>(\r\n config: S & StatoStoreConfig<S>\r\n) {\r\n @Injectable({ providedIn: 'root' })\r\n class ConcreteStore extends StatoStoreBase {\r\n constructor() {\r\n super()\r\n this.initStore(config)\r\n }\r\n }\r\n\r\n return ConcreteStore\r\n}","import {\n Component,\n OnInit,\n OnDestroy,\n signal\n} from '@angular/core'\nimport { devTools } from '@ngstato/core'\nimport type { ActionLog } from '@ngstato/core'\nimport { JsonPipe } from '@angular/common'\n\n@Component({\n selector: 'ngstato-devtools',\n standalone: true,\n imports: [JsonPipe],\n template: `\n <!-- Bouton flottant -->\n @if (!isOpen()) {\n <button class=\"devtools-fab\" (click)=\"toggle()\">\n 🛠 Stato\n </button>\n }\n\n <!-- Panel -->\n @if (isOpen()) {\n <div\n class=\"devtools-panel\"\n [class.devtools-panel--minimized]=\"isMinimized()\"\n [style.left.px]=\"posX()\"\n [style.top.px]=\"posY()\"\n [style.width.px]=\"isMinimized() ? 200 : panelWidth()\"\n [style.height]=\"isMinimized() ? 'auto' : panelHeight() + 'px'\"\n >\n\n <!-- Header — draggable -->\n <div\n class=\"devtools-header\"\n (mousedown)=\"onDragStart($event)\"\n >\n <span class=\"devtools-title\">🛠 Stato</span>\n <div class=\"devtools-header-actions\">\n @if (!isMinimized()) {\n <button class=\"btn-icon\" (click)=\"clear()\" title=\"Vider\">🗑</button>\n }\n <button class=\"btn-icon\" (click)=\"toggleMinimize()\" title=\"Minimiser/Agrandir\">\n {{ isMinimized() ? '▲' : '▼' }}\n </button>\n <button class=\"btn-icon\" (click)=\"toggle()\" title=\"Fermer\">✕</button>\n </div>\n </div>\n\n <!-- Resize handle — coin bas droite -->\n @if (!isMinimized()) {\n <div\n class=\"devtools-resize\"\n (mousedown)=\"onResizeStart($event)\"\n >⊿</div>\n }\n\n @if (!isMinimized()) {\n\n <!-- Tabs -->\n <div class=\"devtools-tabs\">\n <button\n class=\"tab\"\n [class.tab--active]=\"activeTab() === 'actions'\"\n (click)=\"activeTab.set('actions')\"\n >\n Actions ({{ logs().length }})\n </button>\n <button\n class=\"tab\"\n [class.tab--active]=\"activeTab() === 'state'\"\n (click)=\"activeTab.set('state')\"\n >\n State\n </button>\n </div>\n\n <!-- Tab Actions -->\n @if (activeTab() === 'actions') {\n <div class=\"devtools-content\">\n @if (!logs().length) {\n <div class=\"devtools-empty\">Aucune action pour l'instant</div>\n }\n @for (log of logs(); track log.id) {\n <div\n class=\"log-item\"\n [class.log-item--error]=\"log.status === 'error'\"\n (click)=\"selectLog(log)\"\n >\n <div class=\"log-item__left\">\n <span class=\"log-status\">{{ log.status === 'success' ? '✓' : '✗' }}</span>\n <span class=\"log-name\">{{ log.name }}</span>\n </div>\n <div class=\"log-item__right\">\n @if (log.status === 'error') {\n <span class=\"log-error-badge\">erreur</span>\n } @else {\n <span class=\"log-duration\">{{ log.duration }}ms</span>\n }\n <span class=\"log-time\">{{ formatTime(log.at) }}</span>\n </div>\n </div>\n\n @if (selectedLog()?.id === log.id) {\n <div class=\"log-detail\">\n @if (log.error) {\n <div class=\"log-detail__error\">{{ log.error }}</div>\n }\n <div class=\"log-detail__section\">\n <span class=\"log-detail__label\">Avant</span>\n <pre>{{ log.prevState | json }}</pre>\n </div>\n <div class=\"log-detail__section\">\n <span class=\"log-detail__label\">Après</span>\n <pre>{{ log.nextState | json }}</pre>\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Tab State -->\n @if (activeTab() === 'state') {\n <div class=\"devtools-content\">\n @if (logs().length) {\n <pre class=\"state-view\">{{ logs()[0].nextState | json }}</pre>\n } @else {\n <div class=\"devtools-empty\">Aucun state disponible</div>\n }\n </div>\n }\n }\n\n </div>\n }\n `,\n styles: [`\n .devtools-fab {\n position: fixed;\n bottom: 1.5rem;\n left: 1.5rem;\n background: #1e293b;\n color: white;\n border: none;\n border-radius: 999px;\n padding: 0.5rem 1rem;\n font-size: 0.85rem;\n font-weight: 600;\n cursor: pointer;\n z-index: 9999;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transition: background 0.15s;\n }\n .devtools-fab:hover { background: #334155; }\n\n .devtools-panel {\n position: fixed;\n background: #0f172a;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n z-index: 9999;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n font-family: 'Courier New', monospace;\n min-width: 200px;\n min-height: 40px;\n }\n\n .devtools-panel--minimized {\n border-radius: 8px;\n }\n\n .devtools-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.6rem 0.75rem;\n background: #1e293b;\n border-bottom: 1px solid #334155;\n cursor: grab;\n user-select: none;\n }\n .devtools-header:active { cursor: grabbing; }\n\n .devtools-title {\n color: #e2e8f0;\n font-size: 0.82rem;\n font-weight: 600;\n font-family: system-ui;\n }\n\n .devtools-header-actions { display: flex; gap: 0.25rem; }\n\n .btn-icon {\n background: transparent;\n color: #64748b;\n border: none;\n cursor: pointer;\n font-size: 0.8rem;\n padding: 0.15rem 0.35rem;\n border-radius: 4px;\n line-height: 1;\n }\n .btn-icon:hover { background: #334155; color: white; }\n\n .devtools-resize {\n position: absolute;\n bottom: 2px;\n right: 4px;\n color: #334155;\n font-size: 0.9rem;\n cursor: nwse-resize;\n user-select: none;\n line-height: 1;\n }\n .devtools-resize:hover { color: #64748b; }\n\n .devtools-tabs {\n display: flex;\n background: #1e293b;\n border-bottom: 1px solid #334155;\n }\n .tab {\n padding: 0.4rem 0.75rem;\n background: transparent;\n color: #64748b;\n border: none;\n cursor: pointer;\n font-size: 0.78rem;\n font-family: system-ui;\n }\n .tab:hover { color: #e2e8f0; }\n .tab--active { color: #3b82f6; border-bottom: 2px solid #3b82f6; }\n\n .devtools-content {\n overflow-y: auto;\n flex: 1;\n padding: 0.25rem 0;\n }\n\n .devtools-empty {\n padding: 2rem;\n text-align: center;\n color: #475569;\n font-size: 0.78rem;\n font-family: system-ui;\n }\n\n .log-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.35rem 0.75rem;\n cursor: pointer;\n border-bottom: 1px solid #1e293b;\n }\n .log-item:hover { background: #1e293b; }\n .log-item--error { background: #1a0a0a; }\n\n .log-item__left { display: flex; align-items: center; gap: 0.4rem; overflow: hidden; }\n .log-item__right { display: flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }\n\n .log-status { font-size: 0.72rem; color: #22c55e; flex-shrink: 0; }\n .log-item--error .log-status { color: #ef4444; }\n .log-name { color: #e2e8f0; font-size: 0.75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .log-duration { color: #64748b; font-size: 0.7rem; }\n .log-time { color: #475569; font-size: 0.68rem; }\n\n .log-error-badge {\n background: #7f1d1d;\n color: #fca5a5;\n font-size: 0.68rem;\n padding: 0.1rem 0.35rem;\n border-radius: 4px;\n }\n\n .log-detail {\n background: #0a0f1a;\n padding: 0.6rem 0.75rem;\n border-left: 3px solid #3b82f6;\n margin: 0 0.4rem 0.4rem;\n border-radius: 0 4px 4px 0;\n }\n .log-detail__error { color: #fca5a5; font-size: 0.72rem; margin-bottom: 0.4rem; }\n .log-detail__section { margin-bottom: 0.4rem; }\n .log-detail__label {\n color: #64748b;\n font-size: 0.68rem;\n display: block;\n margin-bottom: 0.2rem;\n font-family: system-ui;\n }\n pre {\n color: #86efac;\n font-size: 0.7rem;\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n max-height: 140px;\n overflow-y: auto;\n }\n .state-view {\n color: #86efac;\n font-size: 0.7rem;\n padding: 0.75rem;\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n }\n `]\n})\nexport class StatoDevToolsComponent implements OnInit, OnDestroy {\n\n private unsub?: () => void\n\n // State UI\n isOpen = signal(false)\n isMinimized = signal(false)\n activeTab = signal<'actions' | 'state'>('actions')\n logs = signal<ActionLog[]>([])\n selectedLog = signal<ActionLog | null>(null)\n\n // Position et taille\n posX = signal(24)\n posY = signal(window.innerHeight - 500)\n panelWidth = signal(420)\n panelHeight = signal(460)\n\n // Drag state\n private isDragging = false\n private isResizing = false\n private dragOffsetX = 0\n private dragOffsetY = 0\n private startW = 0\n private startH = 0\n private startX = 0\n private startY = 0\n\n // Bound listeners\n private boundMouseMove = this.onMouseMove.bind(this)\n private boundMouseUp = this.onMouseUp.bind(this)\n\n ngOnInit() {\n this.unsub = devTools.subscribe((state) => {\n this.logs.set(state.logs)\n this.isOpen.set(state.isOpen)\n })\n\n document.addEventListener('mousemove', this.boundMouseMove)\n document.addEventListener('mouseup', this.boundMouseUp)\n }\n\n ngOnDestroy() {\n this.unsub?.()\n document.removeEventListener('mousemove', this.boundMouseMove)\n document.removeEventListener('mouseup', this.boundMouseUp)\n }\n\n // ── Toggle ─────────────────────────────────────────\n toggle() { devTools.toggle() }\n toggleMinimize() { this.isMinimized.update(v => !v) }\n clear() { devTools.clear(); this.selectedLog.set(null) }\n selectLog(log: ActionLog) {\n this.selectedLog.set(this.selectedLog()?.id === log.id ? null : log)\n }\n formatTime(iso: string): string {\n return new Date(iso).toTimeString().slice(0, 8)\n }\n\n // ── Drag ───────────────────────────────────────────\n onDragStart(e: MouseEvent) {\n if ((e.target as HTMLElement).classList.contains('btn-icon')) return\n this.isDragging = true\n this.dragOffsetX = e.clientX - this.posX()\n this.dragOffsetY = e.clientY - this.posY()\n e.preventDefault()\n }\n\n // ── Resize ─────────────────────────────────────────\n onResizeStart(e: MouseEvent) {\n this.isResizing = true\n this.startW = this.panelWidth()\n this.startH = this.panelHeight()\n this.startX = e.clientX\n this.startY = e.clientY\n e.preventDefault()\n e.stopPropagation()\n }\n\n // ── Mouse Move ─────────────────────────────────────\n onMouseMove(e: MouseEvent) {\n if (this.isDragging) {\n this.posX.set(Math.max(0, e.clientX - this.dragOffsetX))\n this.posY.set(Math.max(0, e.clientY - this.dragOffsetY))\n }\n if (this.isResizing) {\n const newW = Math.max(300, this.startW + e.clientX - this.startX)\n const newH = Math.max(200, this.startH + e.clientY - this.startY)\n this.panelWidth.set(newW)\n this.panelHeight.set(newH)\n }\n }\n\n // ── Mouse Up ───────────────────────────────────────\n onMouseUp() {\n this.isDragging = false\n this.isResizing = false\n }\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — API publique\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport { injectStore } from './inject-store'\r\nexport { provideStato } from './provide-ngstato'\r\nexport { createAngularStore} from './create-angular-store'\r\nexport type { StatoAngularConfig } from './provide-ngstato'\r\nexport { StatoDevToolsComponent } from './devtools.component'","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngstato-angular.mjs","sources":["../../src/inject-store.ts","../../src/provide-ngstato.ts","../../src/create-angular-store.ts","../../src/devtools.component.ts","../../src/index.ts","../../src/ngstato-angular.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — injectStore()\r\n// Helper pour injecter un store dans un composant\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport { inject, type Type } from '@angular/core'\r\n\r\nexport function injectStore<T>(store: Type<T>): T {\r\n return inject(store)\r\n}","import {\r\n makeEnvironmentProviders,\r\n InjectionToken,\r\n isDevMode\r\n} from '@angular/core'\r\nimport { configureHttp, devTools } from '@ngstato/core'\r\nimport type { StatoConfig } from '@ngstato/core'\r\n\r\nexport interface StatoAngularConfig {\r\n http?: StatoConfig\r\n devtools?: boolean\r\n}\r\n\r\nexport const STATO_CONFIG = new InjectionToken<StatoAngularConfig>('STATO_CONFIG')\r\n\r\nexport function provideStato(config: StatoAngularConfig = {}) {\r\n\r\n if (config.http) {\r\n configureHttp(config.http)\r\n }\r\n\r\n // DevTools — ignorés automatiquement en production\r\n // isDevMode() est géré par Angular au build\r\n // → false en prod même si devtools: true\r\n if (config.devtools && isDevMode()) {\r\n console.info(\r\n '%c[Stato] 🛠 DevTools activés',\r\n 'background:#1e40af;color:white;padding:4px 8px;border-radius:4px;font-weight:bold'\r\n )\r\n devTools.open()\r\n }\r\n\r\n return makeEnvironmentProviders([\r\n {\r\n provide: STATO_CONFIG,\r\n useValue: config\r\n }\r\n ])\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — createAngularStore()\r\n// Transforme un ngstato store en store Angular avec Signals\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport {\r\n signal,\r\n computed,\r\n Injectable,\r\n OnDestroy,\r\n Signal\r\n} from '@angular/core'\r\n\r\nimport { createStore } from '@ngstato/core'\r\nimport type { StatoStoreConfig } from '@ngstato/core'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FONCTION PRINCIPALE — createAngularStore()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createAngularStore<S extends object>(\r\n config: S & StatoStoreConfig<S>\r\n) {\r\n // 1. Créer le store core\r\n const coreStore = createStore(config)\r\n\r\n // 2. Créer un Signal pour chaque propriété du state\r\n const signals: Record<string, ReturnType<typeof signal>> = {}\r\n const initialState = coreStore.getState()\r\n\r\n for (const key of Object.keys(initialState as object)) {\r\n signals[key] = signal((initialState as any)[key])\r\n }\r\n\r\n // 3. Synchroniser les Signals avec le state core\r\n coreStore.subscribe((newState: any) => {\r\n for (const key of Object.keys(newState)) {\r\n if (signals[key]) {\r\n signals[key].set(newState[key])\r\n }\r\n }\r\n })\r\n\r\n // 4. Construire l objet public Angular\r\n const angularStore: any = {\r\n __store__: coreStore.__store__\r\n }\r\n\r\n // 5. Exposer chaque propriété comme Signal\r\n for (const key of Object.keys(initialState as object)) {\r\n Object.defineProperty(angularStore, key, {\r\n get: () => signals[key],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n\r\n // 6. Exposer chaque computed comme Signal computed\r\n const { computed: computedConfig } = config as StatoStoreConfig<S>\r\n if (computedConfig) {\r\n for (const key of Object.keys(computedConfig)) {\r\n const computedSignal = computed(() => coreStore[key])\r\n Object.defineProperty(angularStore, key, {\r\n get: () => computedSignal,\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n // 7. Exposer chaque action directement\r\n const { actions } = config as StatoStoreConfig<S>\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n angularStore[name] = (...args: unknown[]) =>\r\n coreStore.__store__.dispatch(name, ...args)\r\n }\r\n }\r\n\r\n // 8. Unifier le lifecycle avec @ngstato/core\r\n // (init est idempotent: onInit ne sera appelé qu'une fois)\r\n coreStore.__store__.init(angularStore)\r\n\r\n // 9. Exposer destroy pour le cleanup\r\n angularStore.__destroy__ = () => {\r\n coreStore.__store__.destroy(angularStore)\r\n }\r\n\r\n return angularStore\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// OLD: StatoStoreBase (remplacée par StatoStore avec Proxy)\r\n// Gardée pour backward compatibility si besoin\r\n// ─────────────────────────────────────────────────────\r\n@Injectable()\r\nexport class StatoStoreBase implements OnDestroy {\r\n storeInstance: any\r\n\r\n initStore<S extends object>(config: S & StatoStoreConfig<S>) {\r\n this.storeInstance = createAngularStore(config)\r\n\r\n // Copier toutes les propriétés sur this\r\n for (const key of Object.keys(this.storeInstance)) {\r\n if (key !== '__store__' && key !== '__destroy__') {\r\n Object.defineProperty(this, key, {\r\n get: () => this.storeInstance[key],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n // Copier les actions\r\n const { actions } = config as StatoStoreConfig<S>\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n Object.defineProperty(this, name, {\r\n get: () => this.storeInstance[name],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n }\r\n\r\n ngOnDestroy() {\r\n this.storeInstance?.__destroy__()\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// OLD: Config-based StatoStore (deprecated)\r\n// Gardée pour backward compatibility\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function StatoStoreOld<S extends object>(\r\n config: S & StatoStoreConfig<S>\r\n) {\r\n @Injectable({ providedIn: 'root' })\r\n class ConcreteStore extends StatoStoreBase {\r\n constructor() {\r\n super()\r\n this.initStore(config)\r\n }\r\n }\r\n\r\n return ConcreteStore\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// HELPER TYPE — Extrait automatiquement les types du store\r\n// Pour auto-inférer state + actions + computed sans boilerplate\r\n// ─────────────────────────────────────────────────────\r\n\r\ntype ExtractStoreType<T> = Omit<T, '__store__' | '__destroy__'>\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY — StatoStore()\r\n// Crée un service Angular injectable avec auto-proxy\r\n//\r\n// Type-safe grâce aux génériques avancés — ZÉRO boilerplate!\r\n//\r\n// Usage :\r\n// export class UserStore extends StatoStore(() => {\r\n// const service = inject(UserService)\r\n// return createUserStore(service)\r\n// })\r\n// // ✅ store.user, store.loadUser(), etc — tous typés auto!\r\n// // ✅ Aucun \"declare readonly\" requis\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function StatoStore<S extends object>(\r\n factory: () => S\r\n): new() => ExtractStoreType<S> & OnDestroy {\r\n @Injectable({ providedIn: 'root' })\r\n class ConcreteStore implements OnDestroy {\r\n private _store: any\r\n [key: string]: any\r\n\r\n constructor() {\r\n // factory() est appelée dans le contexte d'injection Angular.\r\n // Si factory() retourne déjà un store ngstato (createStore),\r\n // on l'utilise tel quel. Sinon on le convertit via createAngularStore().\r\n const produced = factory() as any\r\n this._store = produced?.__store__ ? produced : createAngularStore(produced)\r\n\r\n // Proxy dynamique: plus besoin de déclaration manuelle des getters/actions.\r\n return new Proxy(this, {\r\n get: (target, prop, receiver) => {\r\n if (prop in target) {\r\n return Reflect.get(target, prop, receiver)\r\n }\r\n return this._store?.[prop as keyof typeof this._store]\r\n },\r\n set: (target, prop, value, receiver) => {\r\n if (prop in target) {\r\n return Reflect.set(target, prop, value, receiver)\r\n }\r\n if (this._store && prop in this._store) {\r\n this._store[prop] = value\r\n return true\r\n }\r\n ;(target as any)[prop] = value\r\n return true\r\n },\r\n has: (target, prop) => prop in target || prop in (this._store ?? {}),\r\n ownKeys: (target) => {\r\n const targetKeys = Reflect.ownKeys(target)\r\n const storeKeys = this._store ? Reflect.ownKeys(this._store) : []\r\n return Array.from(new Set([...targetKeys, ...storeKeys]))\r\n },\r\n getOwnPropertyDescriptor: (target, prop) => {\r\n const targetDesc = Reflect.getOwnPropertyDescriptor(target, prop)\r\n if (targetDesc) return targetDesc\r\n if (this._store && prop in this._store) {\r\n return {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: this._store[prop]\r\n }\r\n }\r\n return undefined\r\n }\r\n })\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this._store?.__destroy__) {\r\n this._store.__destroy__()\r\n return\r\n }\r\n if (this._store?.__store__?.destroy) {\r\n this._store.__store__.destroy(this._store)\r\n }\r\n }\r\n }\r\n\r\n return ConcreteStore as any\r\n}","import {\n Component,\n OnInit,\n OnDestroy,\n signal\n} from '@angular/core'\nimport { devTools } from '@ngstato/core'\nimport type { ActionLog } from '@ngstato/core'\nimport { JsonPipe } from '@angular/common'\n\n@Component({\n selector: 'ngstato-devtools',\n standalone: true,\n imports: [JsonPipe],\n template: `\n <!-- Bouton flottant -->\n @if (!isOpen()) {\n <button class=\"devtools-fab\" (click)=\"toggle()\">\n 🛠 Stato\n </button>\n }\n\n <!-- Panel -->\n @if (isOpen()) {\n <div\n class=\"devtools-panel\"\n [class.devtools-panel--minimized]=\"isMinimized()\"\n [style.left.px]=\"posX()\"\n [style.top.px]=\"posY()\"\n [style.width.px]=\"isMinimized() ? 200 : panelWidth()\"\n [style.height]=\"isMinimized() ? 'auto' : panelHeight() + 'px'\"\n >\n\n <!-- Header — draggable -->\n <div\n class=\"devtools-header\"\n (mousedown)=\"onDragStart($event)\"\n >\n <span class=\"devtools-title\">🛠 Stato</span>\n <div class=\"devtools-header-actions\">\n @if (!isMinimized()) {\n <button class=\"btn-icon\" (click)=\"clear()\" title=\"Vider\">🗑</button>\n }\n <button class=\"btn-icon\" (click)=\"toggleMinimize()\" title=\"Minimiser/Agrandir\">\n {{ isMinimized() ? '▲' : '▼' }}\n </button>\n <button class=\"btn-icon\" (click)=\"toggle()\" title=\"Fermer\">✕</button>\n </div>\n </div>\n\n <!-- Resize handle — coin bas droite -->\n @if (!isMinimized()) {\n <div\n class=\"devtools-resize\"\n (mousedown)=\"onResizeStart($event)\"\n >⊿</div>\n }\n\n @if (!isMinimized()) {\n\n <!-- Tabs -->\n <div class=\"devtools-tabs\">\n <button\n class=\"tab\"\n [class.tab--active]=\"activeTab() === 'actions'\"\n (click)=\"activeTab.set('actions')\"\n >\n Actions ({{ logs().length }})\n </button>\n <button\n class=\"tab\"\n [class.tab--active]=\"activeTab() === 'state'\"\n (click)=\"activeTab.set('state')\"\n >\n State\n </button>\n </div>\n\n <!-- Tab Actions -->\n @if (activeTab() === 'actions') {\n <div class=\"devtools-content\">\n @if (!logs().length) {\n <div class=\"devtools-empty\">Aucune action pour l'instant</div>\n }\n @for (log of logs(); track log.id) {\n <div\n class=\"log-item\"\n [class.log-item--error]=\"log.status === 'error'\"\n (click)=\"selectLog(log)\"\n >\n <div class=\"log-item__left\">\n <span class=\"log-status\">{{ log.status === 'success' ? '✓' : '✗' }}</span>\n <span class=\"log-name\">{{ log.name }}</span>\n </div>\n <div class=\"log-item__right\">\n @if (log.status === 'error') {\n <span class=\"log-error-badge\">erreur</span>\n } @else {\n <span class=\"log-duration\">{{ log.duration }}ms</span>\n }\n <span class=\"log-time\">{{ formatTime(log.at) }}</span>\n </div>\n </div>\n\n @if (selectedLog()?.id === log.id) {\n <div class=\"log-detail\">\n @if (log.error) {\n <div class=\"log-detail__error\">{{ log.error }}</div>\n }\n <div class=\"log-detail__section\">\n <span class=\"log-detail__label\">Avant</span>\n <pre>{{ log.prevState | json }}</pre>\n </div>\n <div class=\"log-detail__section\">\n <span class=\"log-detail__label\">Après</span>\n <pre>{{ log.nextState | json }}</pre>\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Tab State -->\n @if (activeTab() === 'state') {\n <div class=\"devtools-content\">\n @if (logs().length) {\n <pre class=\"state-view\">{{ logs()[0].nextState | json }}</pre>\n } @else {\n <div class=\"devtools-empty\">Aucun state disponible</div>\n }\n </div>\n }\n }\n\n </div>\n }\n `,\n styles: [`\n .devtools-fab {\n position: fixed;\n bottom: 1.5rem;\n left: 1.5rem;\n background: #1e293b;\n color: white;\n border: none;\n border-radius: 999px;\n padding: 0.5rem 1rem;\n font-size: 0.85rem;\n font-weight: 600;\n cursor: pointer;\n z-index: 9999;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transition: background 0.15s;\n }\n .devtools-fab:hover { background: #334155; }\n\n .devtools-panel {\n position: fixed;\n background: #0f172a;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n z-index: 9999;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n font-family: 'Courier New', monospace;\n min-width: 200px;\n min-height: 40px;\n }\n\n .devtools-panel--minimized {\n border-radius: 8px;\n }\n\n .devtools-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.6rem 0.75rem;\n background: #1e293b;\n border-bottom: 1px solid #334155;\n cursor: grab;\n user-select: none;\n }\n .devtools-header:active { cursor: grabbing; }\n\n .devtools-title {\n color: #e2e8f0;\n font-size: 0.82rem;\n font-weight: 600;\n font-family: system-ui;\n }\n\n .devtools-header-actions { display: flex; gap: 0.25rem; }\n\n .btn-icon {\n background: transparent;\n color: #64748b;\n border: none;\n cursor: pointer;\n font-size: 0.8rem;\n padding: 0.15rem 0.35rem;\n border-radius: 4px;\n line-height: 1;\n }\n .btn-icon:hover { background: #334155; color: white; }\n\n .devtools-resize {\n position: absolute;\n bottom: 2px;\n right: 4px;\n color: #334155;\n font-size: 0.9rem;\n cursor: nwse-resize;\n user-select: none;\n line-height: 1;\n }\n .devtools-resize:hover { color: #64748b; }\n\n .devtools-tabs {\n display: flex;\n background: #1e293b;\n border-bottom: 1px solid #334155;\n }\n .tab {\n padding: 0.4rem 0.75rem;\n background: transparent;\n color: #64748b;\n border: none;\n cursor: pointer;\n font-size: 0.78rem;\n font-family: system-ui;\n }\n .tab:hover { color: #e2e8f0; }\n .tab--active { color: #3b82f6; border-bottom: 2px solid #3b82f6; }\n\n .devtools-content {\n overflow-y: auto;\n flex: 1;\n padding: 0.25rem 0;\n }\n\n .devtools-empty {\n padding: 2rem;\n text-align: center;\n color: #475569;\n font-size: 0.78rem;\n font-family: system-ui;\n }\n\n .log-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.35rem 0.75rem;\n cursor: pointer;\n border-bottom: 1px solid #1e293b;\n }\n .log-item:hover { background: #1e293b; }\n .log-item--error { background: #1a0a0a; }\n\n .log-item__left { display: flex; align-items: center; gap: 0.4rem; overflow: hidden; }\n .log-item__right { display: flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }\n\n .log-status { font-size: 0.72rem; color: #22c55e; flex-shrink: 0; }\n .log-item--error .log-status { color: #ef4444; }\n .log-name { color: #e2e8f0; font-size: 0.75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .log-duration { color: #64748b; font-size: 0.7rem; }\n .log-time { color: #475569; font-size: 0.68rem; }\n\n .log-error-badge {\n background: #7f1d1d;\n color: #fca5a5;\n font-size: 0.68rem;\n padding: 0.1rem 0.35rem;\n border-radius: 4px;\n }\n\n .log-detail {\n background: #0a0f1a;\n padding: 0.6rem 0.75rem;\n border-left: 3px solid #3b82f6;\n margin: 0 0.4rem 0.4rem;\n border-radius: 0 4px 4px 0;\n }\n .log-detail__error { color: #fca5a5; font-size: 0.72rem; margin-bottom: 0.4rem; }\n .log-detail__section { margin-bottom: 0.4rem; }\n .log-detail__label {\n color: #64748b;\n font-size: 0.68rem;\n display: block;\n margin-bottom: 0.2rem;\n font-family: system-ui;\n }\n pre {\n color: #86efac;\n font-size: 0.7rem;\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n max-height: 140px;\n overflow-y: auto;\n }\n .state-view {\n color: #86efac;\n font-size: 0.7rem;\n padding: 0.75rem;\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n }\n `]\n})\nexport class StatoDevToolsComponent implements OnInit, OnDestroy {\n\n private unsub?: () => void\n\n // State UI\n isOpen = signal(false)\n isMinimized = signal(false)\n activeTab = signal<'actions' | 'state'>('actions')\n logs = signal<ActionLog[]>([])\n selectedLog = signal<ActionLog | null>(null)\n\n // Position et taille\n posX = signal(24)\n posY = signal(window.innerHeight - 500)\n panelWidth = signal(420)\n panelHeight = signal(460)\n\n // Drag state\n private isDragging = false\n private isResizing = false\n private dragOffsetX = 0\n private dragOffsetY = 0\n private startW = 0\n private startH = 0\n private startX = 0\n private startY = 0\n\n // Bound listeners\n private boundMouseMove = this.onMouseMove.bind(this)\n private boundMouseUp = this.onMouseUp.bind(this)\n\n ngOnInit() {\n this.unsub = devTools.subscribe((state) => {\n this.logs.set(state.logs)\n this.isOpen.set(state.isOpen)\n })\n\n document.addEventListener('mousemove', this.boundMouseMove)\n document.addEventListener('mouseup', this.boundMouseUp)\n }\n\n ngOnDestroy() {\n this.unsub?.()\n document.removeEventListener('mousemove', this.boundMouseMove)\n document.removeEventListener('mouseup', this.boundMouseUp)\n }\n\n // ── Toggle ─────────────────────────────────────────\n toggle() { devTools.toggle() }\n toggleMinimize() { this.isMinimized.update(v => !v) }\n clear() { devTools.clear(); this.selectedLog.set(null) }\n selectLog(log: ActionLog) {\n this.selectedLog.set(this.selectedLog()?.id === log.id ? null : log)\n }\n formatTime(iso: string): string {\n return new Date(iso).toTimeString().slice(0, 8)\n }\n\n // ── Drag ───────────────────────────────────────────\n onDragStart(e: MouseEvent) {\n if ((e.target as HTMLElement).classList.contains('btn-icon')) return\n this.isDragging = true\n this.dragOffsetX = e.clientX - this.posX()\n this.dragOffsetY = e.clientY - this.posY()\n e.preventDefault()\n }\n\n // ── Resize ─────────────────────────────────────────\n onResizeStart(e: MouseEvent) {\n this.isResizing = true\n this.startW = this.panelWidth()\n this.startH = this.panelHeight()\n this.startX = e.clientX\n this.startY = e.clientY\n e.preventDefault()\n e.stopPropagation()\n }\n\n // ── Mouse Move ─────────────────────────────────────\n onMouseMove(e: MouseEvent) {\n if (this.isDragging) {\n this.posX.set(Math.max(0, e.clientX - this.dragOffsetX))\n this.posY.set(Math.max(0, e.clientY - this.dragOffsetY))\n }\n if (this.isResizing) {\n const newW = Math.max(300, this.startW + e.clientX - this.startX)\n const newH = Math.max(200, this.startH + e.clientY - this.startY)\n this.panelWidth.set(newW)\n this.panelHeight.set(newH)\n }\n }\n\n // ── Mouse Up ───────────────────────────────────────\n onMouseUp() {\n this.isDragging = false\n this.isResizing = false\n }\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/angular — API publique\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport { injectStore } from './inject-store'\r\nexport { provideStato } from './provide-ngstato'\r\nexport { createAngularStore, StatoStore } from './create-angular-store'\r\nexport type { StatoAngularConfig } from './provide-ngstato'\r\nexport { StatoDevToolsComponent } from './devtools.component'","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { injectStore } from './inject-store';
|
|
2
2
|
export { provideStato } from './provide-ngstato';
|
|
3
|
-
export { createAngularStore } from './create-angular-store';
|
|
3
|
+
export { createAngularStore, StatoStore } from './create-angular-store';
|
|
4
4
|
export type { StatoAngularConfig } from './provide-ngstato';
|
|
5
5
|
export { StatoDevToolsComponent } from './devtools.component';
|
package/ng-package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,40 +1,59 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@ngstato/angular",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"private": false,
|
|
5
|
-
"description": "ngStato — Angular adapter with native Signals",
|
|
6
|
-
"main": "./dist/fesm2022/ngstato-angular.mjs",
|
|
7
|
-
"module": "./dist/fesm2022/ngstato-angular.mjs",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/fesm2022/ngstato-angular.mjs",
|
|
13
|
-
"default": "./dist/fesm2022/ngstato-angular.mjs"
|
|
14
|
-
},
|
|
15
|
-
"./package.json": {
|
|
16
|
-
"default": "./package.json"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "ng-packagr -p ng-package.json",
|
|
21
|
-
"test": "vitest run",
|
|
22
|
-
"dev": "ng-packagr -p ng-package.json --watch"
|
|
23
|
-
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"@ngstato/core": "
|
|
26
|
-
},
|
|
27
|
-
"peerDependencies": {
|
|
28
|
-
"@angular/core": ">=17.0.0",
|
|
29
|
-
"@angular/common": ">=17.0.0"
|
|
30
|
-
},
|
|
31
|
-
"devDependencies": {
|
|
32
|
-
"ng-packagr": "^18.0.0",
|
|
33
|
-
"@angular/compiler-cli": "^18.0.0",
|
|
34
|
-
"@angular/compiler": "^18.0.0",
|
|
35
|
-
"@angular/common": "^18.0.0",
|
|
36
|
-
"typescript": "~5.5.0",
|
|
37
|
-
"tsup": "^8.0.0",
|
|
38
|
-
"vitest": "^1.6.0"
|
|
39
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngstato/angular",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "ngStato — Angular adapter with native Signals",
|
|
6
|
+
"main": "./dist/fesm2022/ngstato-angular.mjs",
|
|
7
|
+
"module": "./dist/fesm2022/ngstato-angular.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/fesm2022/ngstato-angular.mjs",
|
|
13
|
+
"default": "./dist/fesm2022/ngstato-angular.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": {
|
|
16
|
+
"default": "./package.json"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "ng-packagr -p ng-package.json",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"dev": "ng-packagr -p ng-package.json --watch"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@ngstato/core": "workspace:*"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@angular/core": ">=17.0.0",
|
|
29
|
+
"@angular/common": ">=17.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"ng-packagr": "^18.0.0",
|
|
33
|
+
"@angular/compiler-cli": "^18.0.0",
|
|
34
|
+
"@angular/compiler": "^18.0.0",
|
|
35
|
+
"@angular/common": "^18.0.0",
|
|
36
|
+
"typescript": "~5.5.0",
|
|
37
|
+
"tsup": "^8.0.0",
|
|
38
|
+
"vitest": "^1.6.0"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/becher/ngStato.git",
|
|
44
|
+
"directory": "packages/angular"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/becher/ngStato#readme",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/becher/ngStato/issues"
|
|
49
|
+
},
|
|
50
|
+
"author": "becher",
|
|
51
|
+
"keywords": [
|
|
52
|
+
"angular",
|
|
53
|
+
"state-management",
|
|
54
|
+
"signals",
|
|
55
|
+
"store",
|
|
56
|
+
"ngrx-alternative",
|
|
57
|
+
"ngstato"
|
|
58
|
+
]
|
|
40
59
|
}
|