@ngstato/angular 0.1.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 +388 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +542 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +538 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# ngStato
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## La même action. Deux approches.
|
|
14
|
+
|
|
15
|
+
| ❌ NgRx v20 (officiel, MIT) | ✅ ngStato |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `loadStudents: rxMethod<void>(` | `async loadStudents(state) {` |
|
|
18
|
+
| ` pipe(` | ` state.isLoading = true` |
|
|
19
|
+
| ` tap(() => patchState(store, { isLoading: true })),` | ` state.students = await service.getAll()` |
|
|
20
|
+
| ` switchMap(() =>` | ` state.isLoading = false` |
|
|
21
|
+
| ` from(service.getAll()).pipe(` | `}` |
|
|
22
|
+
| ` tapResponse({` | |
|
|
23
|
+
| ` next: (s) => patchState(store, { students: s, isLoading: false }),` | **1 concept : async/await** |
|
|
24
|
+
| ` error: (e) => patchState(store, { error: e.message, isLoading: false })` | **5 lignes** |
|
|
25
|
+
| ` })` | |
|
|
26
|
+
| ` )` | |
|
|
27
|
+
| ` )` | |
|
|
28
|
+
| ` )` | |
|
|
29
|
+
| `)` | |
|
|
30
|
+
| **9 concepts RxJS/NgRx — 14 lignes** | |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Pourquoi switcher vers ngStato ?
|
|
35
|
+
|
|
36
|
+
**1 concept au lieu de 9 pour écrire une action async**
|
|
37
|
+
NgRx nécessite rxMethod, pipe, tap, switchMap, from, tapResponse, patchState... ngStato nécessite uniquement async/await — natif JavaScript.
|
|
38
|
+
|
|
39
|
+
**2x moins de code pour le même résultat**
|
|
40
|
+
Sur un store CRUD complet (5 actions), NgRx v20 nécessite ~90 lignes. ngStato nécessite ~45 lignes.
|
|
41
|
+
|
|
42
|
+
**DevTools sans extension browser**
|
|
43
|
+
NgRx DevTools nécessite l'extension Chrome Redux DevTools. ngStato intègre ses DevTools directement dans l'app — fonctionnels sur tous les browsers et mobile.
|
|
44
|
+
|
|
45
|
+
**Protection production automatique**
|
|
46
|
+
ngStato utilise `isDevMode()` d'Angular — les DevTools sont physiquement impossibles à activer en prod.
|
|
47
|
+
|
|
48
|
+
**38x plus léger — ~3 KB vs ~50 KB gzip**
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install @ngstato/core @ngstato/angular
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// app.config.ts
|
|
60
|
+
import { provideStato } from '@ngstato/angular'
|
|
61
|
+
import { isDevMode } from '@angular/core'
|
|
62
|
+
|
|
63
|
+
export const appConfig: ApplicationConfig = {
|
|
64
|
+
providers: [
|
|
65
|
+
provideRouter(routes),
|
|
66
|
+
provideStato({
|
|
67
|
+
http: { baseUrl: 'https://api.monapp.com', timeout: 8000 },
|
|
68
|
+
devtools: isDevMode()
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Créer un store
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// user.store.ts
|
|
80
|
+
import { Injectable, OnDestroy, inject } from '@angular/core'
|
|
81
|
+
import { createStore, http, optimistic, retryable, connectDevTools } from '@ngstato/core'
|
|
82
|
+
import { injectStore } from '@ngstato/angular'
|
|
83
|
+
|
|
84
|
+
function createUserStore() {
|
|
85
|
+
const store = createStore({
|
|
86
|
+
|
|
87
|
+
// State
|
|
88
|
+
users: [] as User[],
|
|
89
|
+
isLoading: false,
|
|
90
|
+
error: null as string | null,
|
|
91
|
+
|
|
92
|
+
// Computed — recalculés automatiquement
|
|
93
|
+
computed: {
|
|
94
|
+
total: (state) => state.users.length,
|
|
95
|
+
admins: (state) => state.users.filter(u => u.role === 'admin')
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// Actions
|
|
99
|
+
actions: {
|
|
100
|
+
|
|
101
|
+
// Chargement avec retry automatique
|
|
102
|
+
loadUsers: retryable(
|
|
103
|
+
async (state) => {
|
|
104
|
+
state.isLoading = true
|
|
105
|
+
state.users = await http.get('/users')
|
|
106
|
+
state.isLoading = false
|
|
107
|
+
},
|
|
108
|
+
{ attempts: 3, backoff: 'exponential', delay: 1000 }
|
|
109
|
+
),
|
|
110
|
+
|
|
111
|
+
// Suppression avec rollback automatique
|
|
112
|
+
deleteUser: optimistic(
|
|
113
|
+
(state, id: string) => {
|
|
114
|
+
state.users = state.users.filter(u => u.id !== id)
|
|
115
|
+
},
|
|
116
|
+
async (_, id: string) => {
|
|
117
|
+
await http.delete(`/users/${id}`)
|
|
118
|
+
}
|
|
119
|
+
),
|
|
120
|
+
|
|
121
|
+
// Action simple
|
|
122
|
+
async addUser(state, user: UserCreate) {
|
|
123
|
+
const created = await http.post('/users', user)
|
|
124
|
+
state.users = [...state.users, created]
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
// Hooks lifecycle
|
|
129
|
+
hooks: {
|
|
130
|
+
onError: (err, name) => console.error(`[UserStore] ${name}:`, err.message)
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
connectDevTools(store, 'UserStore') // ← une seule ligne
|
|
135
|
+
return store
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@Injectable({ providedIn: 'root' })
|
|
139
|
+
export class UserStore implements OnDestroy {
|
|
140
|
+
private _store = createUserStore()
|
|
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
|
+
}
|
|
152
|
+
|
|
153
|
+
// Dans un composant
|
|
154
|
+
@Component({ ... })
|
|
155
|
+
export class UserListComponent {
|
|
156
|
+
store = injectStore(UserStore) // ou inject(UserStore)
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Helpers
|
|
163
|
+
|
|
164
|
+
| Helper | Description | Équivalent NgRx |
|
|
165
|
+
|--------|-------------|-----------------|
|
|
166
|
+
| `abortable()` | Annule la requête précédente automatiquement | switchMap |
|
|
167
|
+
| `debounced()` | Debounce sans RxJS — défaut 300ms | debounceTime |
|
|
168
|
+
| `throttled()` | Throttle sans RxJS | throttleTime |
|
|
169
|
+
| `retryable()` | Retry avec backoff fixe ou exponentiel | retryWhen |
|
|
170
|
+
| `fromStream()` | Écoute Observable/WebSocket/Firebase/Supabase | rxMethod + Effect |
|
|
171
|
+
| `optimistic()` | Update immédiat + rollback automatique si échec | Manuel en NgRx |
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { abortable, debounced, throttled, retryable, fromStream, optimistic } from '@ngstato/core'
|
|
175
|
+
|
|
176
|
+
actions: {
|
|
177
|
+
// Annulation auto — comme switchMap
|
|
178
|
+
search: abortable(async (state, q: string, { signal }) => {
|
|
179
|
+
state.results = await fetch(`/api/search?q=${q}`, { signal }).then(r => r.json())
|
|
180
|
+
}),
|
|
181
|
+
|
|
182
|
+
// Debounce 300ms
|
|
183
|
+
filter: debounced((state, q: string) => { state.query = q }, 300),
|
|
184
|
+
|
|
185
|
+
// Retry x3 avec backoff exponentiel
|
|
186
|
+
load: retryable(async (state) => {
|
|
187
|
+
state.data = await http.get('/data')
|
|
188
|
+
}, { attempts: 3, backoff: 'exponential' }),
|
|
189
|
+
|
|
190
|
+
// Realtime WebSocket
|
|
191
|
+
listen: fromStream(
|
|
192
|
+
() => webSocket('wss://api.monapp.com/ws'),
|
|
193
|
+
(state, msg) => { state.messages = [...state.messages, msg] }
|
|
194
|
+
),
|
|
195
|
+
|
|
196
|
+
// Optimistic + rollback auto
|
|
197
|
+
delete: optimistic(
|
|
198
|
+
(state, id) => { state.items = state.items.filter(i => i.id !== id) },
|
|
199
|
+
async (_, id) => { await http.delete(`/items/${id}`) }
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Client HTTP
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
import { http } from '@ngstato/core'
|
|
210
|
+
|
|
211
|
+
// Configurer via provideStato() — une seule fois
|
|
212
|
+
provideStato({
|
|
213
|
+
http: {
|
|
214
|
+
baseUrl: 'https://api.monapp.com',
|
|
215
|
+
timeout: 8000,
|
|
216
|
+
headers: { 'X-App-Version': '1.0' },
|
|
217
|
+
auth: () => localStorage.getItem('token')
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Utiliser partout dans les actions
|
|
222
|
+
await http.get('/users')
|
|
223
|
+
await http.get('/users', { params: { page: 1, limit: 10 } })
|
|
224
|
+
await http.post('/users', { name: 'Alice' })
|
|
225
|
+
await http.put('/users/1', { name: 'Bob' })
|
|
226
|
+
await http.patch('/users/1', { active: false })
|
|
227
|
+
await http.delete('/users/1')
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## DevTools
|
|
233
|
+
|
|
234
|
+
Panel intégré dans l'app — sans extension browser, sans installation supplémentaire.
|
|
235
|
+
|
|
236
|
+
- Panel déplaçable à la souris
|
|
237
|
+
- Redimensionnable — coin bas-droite
|
|
238
|
+
- Minimisable — bouton ▼/▲
|
|
239
|
+
- Historique des actions avec durées et timestamps
|
|
240
|
+
- Diff Avant/Après pour chaque action
|
|
241
|
+
- Onglet State — state actuel complet
|
|
242
|
+
- **Désactivé automatiquement en production via `isDevMode()`**
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
// app.config.ts
|
|
246
|
+
provideStato({ devtools: isDevMode() })
|
|
247
|
+
|
|
248
|
+
// app.component.ts
|
|
249
|
+
import { StatoDevToolsComponent } from '@ngstato/angular'
|
|
250
|
+
|
|
251
|
+
@Component({
|
|
252
|
+
imports: [RouterOutlet, StatoDevToolsComponent],
|
|
253
|
+
template: `<router-outlet /><stato-devtools />`
|
|
254
|
+
})
|
|
255
|
+
export class AppComponent {}
|
|
256
|
+
|
|
257
|
+
// mon-store.ts
|
|
258
|
+
connectDevTools(store, 'MonStore') // une seule ligne
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
| | NgRx DevTools | ngStato DevTools |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| Installation | Extension Chrome | Zéro installation |
|
|
264
|
+
| Browser support | Chrome/Firefox | Tous browsers |
|
|
265
|
+
| Mobile | ❌ | ✅ |
|
|
266
|
+
| Désactivé en prod | Manuel | `isDevMode()` auto |
|
|
267
|
+
| State visible en prod | Oui si oubli | Jamais |
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Guide de migration NgRx → ngStato
|
|
272
|
+
|
|
273
|
+
La migration est progressive — store par store.
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
// withState → state initial
|
|
277
|
+
// NgRx
|
|
278
|
+
withState({ users: [] as User[], isLoading: false })
|
|
279
|
+
// ngStato
|
|
280
|
+
users: [] as User[], isLoading: false,
|
|
281
|
+
|
|
282
|
+
// withMethods + rxMethod → actions
|
|
283
|
+
// NgRx
|
|
284
|
+
withMethods((store) => ({
|
|
285
|
+
load: rxMethod<void>(pipe(
|
|
286
|
+
tap(() => patchState(store, { isLoading: true })),
|
|
287
|
+
switchMap(() => from(service.get()).pipe(
|
|
288
|
+
tapResponse({
|
|
289
|
+
next: (d) => patchState(store, { data: d, isLoading: false }),
|
|
290
|
+
error: (e) => patchState(store, { error: e.message })
|
|
291
|
+
})
|
|
292
|
+
))
|
|
293
|
+
))
|
|
294
|
+
}))
|
|
295
|
+
// ngStato
|
|
296
|
+
actions: {
|
|
297
|
+
async load(state) {
|
|
298
|
+
state.isLoading = true
|
|
299
|
+
state.data = await service.get()
|
|
300
|
+
state.isLoading = false
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// withComputed → computed
|
|
305
|
+
// NgRx
|
|
306
|
+
withComputed((store) => ({
|
|
307
|
+
total: computed(() => store.users().length)
|
|
308
|
+
}))
|
|
309
|
+
// ngStato
|
|
310
|
+
computed: {
|
|
311
|
+
total: (state) => state.users.length
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Comparaison NgRx SignalStore v20 vs ngStato
|
|
318
|
+
|
|
319
|
+
| Feature | NgRx SignalStore v20 | ngStato v0.1 |
|
|
320
|
+
|---------|---------------------|--------------|
|
|
321
|
+
| withState | ✅ | ✅ |
|
|
322
|
+
| withMethods / actions | ✅ rxMethod requis | ✅ async/await |
|
|
323
|
+
| withComputed | ✅ | ✅ |
|
|
324
|
+
| patchState | ✅ obligatoire | ✅ state.x = y |
|
|
325
|
+
| provideStore | ✅ | ✅ provideStato() |
|
|
326
|
+
| inject() | ✅ | ✅ injectStore() |
|
|
327
|
+
| onInit / onDestroy | ✅ | ✅ |
|
|
328
|
+
| DevTools | ✅ extension Chrome | ✅ panel intégré |
|
|
329
|
+
| DevTools mobile | ❌ | ✅ |
|
|
330
|
+
| Protection prod | ⚠️ logOnly manuel | ✅ isDevMode() auto |
|
|
331
|
+
| RxJS requis | ✅ obligatoire | ❌ optionnel |
|
|
332
|
+
| Bundle size | ~50 KB gzip | ~3 KB gzip |
|
|
333
|
+
| withProps | ✅ | 🔜 v0.2 |
|
|
334
|
+
| withEntities | ✅ | 🔜 v1.0 |
|
|
335
|
+
| signalStoreFeature() | ✅ | 🔜 v0.4 |
|
|
336
|
+
| Schematics CLI | ✅ | 🔜 v1.0 |
|
|
337
|
+
| ESLint plugin | ✅ | 🔜 v1.0 |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Roadmap
|
|
342
|
+
|
|
343
|
+
### v0.1 ✅ TERMINÉ
|
|
344
|
+
- `createStore()` — state, actions, computed, hooks
|
|
345
|
+
- `StatoHttp` — GET POST PUT PATCH DELETE avec auth, timeout, params
|
|
346
|
+
- `abortable()`, `debounced()`, `throttled()`, `retryable()`, `fromStream()`, `optimistic()`
|
|
347
|
+
- `@ngstato/angular` — Signals natifs, `provideStato()`, `injectStore()`
|
|
348
|
+
- DevTools — panel déplaçable, redimensionnable, minimisable
|
|
349
|
+
- `connectDevTools()` — connexion automatique store → DevTools
|
|
350
|
+
- Protection prod automatique via `isDevMode()`
|
|
351
|
+
- **144 tests — 100% passing**
|
|
352
|
+
|
|
353
|
+
### v0.2 — Helpers avancés
|
|
354
|
+
- `exclusive()` — = exhaustMap NgRx
|
|
355
|
+
- `queued()` — = concatMap NgRx
|
|
356
|
+
- `store.on()` — réactions inter-stores
|
|
357
|
+
- Testing utilities
|
|
358
|
+
- DevTools time-travel
|
|
359
|
+
|
|
360
|
+
### v0.3 — Persistance
|
|
361
|
+
- `withPersist()` — localStorage / sessionStorage / IndexedDB
|
|
362
|
+
- `withHistory()` — undo/redo
|
|
363
|
+
- SSR ready
|
|
364
|
+
|
|
365
|
+
### v1.0 — Production ready
|
|
366
|
+
- `withEntities()`, Schematics CLI, ESLint plugin
|
|
367
|
+
- Documentation VitePress complète
|
|
368
|
+
- Benchmarks comparatifs
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Contribuer
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
git clone https://github.com/becher/ngstato
|
|
376
|
+
cd ngstato
|
|
377
|
+
pnpm install # Node >= 18, pnpm >= 8
|
|
378
|
+
pnpm build
|
|
379
|
+
pnpm test # 144 tests
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Convention commits : `feat` / `fix` / `docs` / `test` / `refactor` / `chore`
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## License
|
|
387
|
+
|
|
388
|
+
MIT — Copyright (c) 2025 ngStato
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Type, OnInit, OnDestroy } from '@angular/core';
|
|
3
|
+
import { StatoConfig, StatoStoreConfig, ActionLog } from '@ngstato/core';
|
|
4
|
+
|
|
5
|
+
declare function injectStore<T>(store: Type<T>): T;
|
|
6
|
+
|
|
7
|
+
interface StatoAngularConfig {
|
|
8
|
+
http?: StatoConfig;
|
|
9
|
+
devtools?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function provideStato(config?: StatoAngularConfig): _angular_core.EnvironmentProviders;
|
|
12
|
+
|
|
13
|
+
declare function createAngularStore<S extends object>(config: S & StatoStoreConfig<S>): any;
|
|
14
|
+
|
|
15
|
+
declare class StatoDevToolsComponent implements OnInit, OnDestroy {
|
|
16
|
+
private config;
|
|
17
|
+
private unsub?;
|
|
18
|
+
isOpen: _angular_core.WritableSignal<boolean>;
|
|
19
|
+
isMinimized: _angular_core.WritableSignal<boolean>;
|
|
20
|
+
activeTab: _angular_core.WritableSignal<"actions" | "state">;
|
|
21
|
+
logs: _angular_core.WritableSignal<ActionLog[]>;
|
|
22
|
+
selectedLog: _angular_core.WritableSignal<ActionLog | null>;
|
|
23
|
+
posX: _angular_core.WritableSignal<number>;
|
|
24
|
+
posY: _angular_core.WritableSignal<number>;
|
|
25
|
+
panelWidth: _angular_core.WritableSignal<number>;
|
|
26
|
+
panelHeight: _angular_core.WritableSignal<number>;
|
|
27
|
+
private isDragging;
|
|
28
|
+
private isResizing;
|
|
29
|
+
private dragOffsetX;
|
|
30
|
+
private dragOffsetY;
|
|
31
|
+
private startW;
|
|
32
|
+
private startH;
|
|
33
|
+
private startX;
|
|
34
|
+
private startY;
|
|
35
|
+
private boundMouseMove;
|
|
36
|
+
private boundMouseUp;
|
|
37
|
+
ngOnInit(): void;
|
|
38
|
+
ngOnDestroy(): void;
|
|
39
|
+
toggle(): void;
|
|
40
|
+
toggleMinimize(): void;
|
|
41
|
+
clear(): void;
|
|
42
|
+
selectLog(log: ActionLog): void;
|
|
43
|
+
formatTime(iso: string): string;
|
|
44
|
+
onDragStart(e: MouseEvent): void;
|
|
45
|
+
onResizeStart(e: MouseEvent): void;
|
|
46
|
+
onMouseMove(e: MouseEvent): void;
|
|
47
|
+
onMouseUp(): void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { type StatoAngularConfig, StatoDevToolsComponent, createAngularStore, injectStore, provideStato };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Type, OnInit, OnDestroy } from '@angular/core';
|
|
3
|
+
import { StatoConfig, StatoStoreConfig, ActionLog } from '@ngstato/core';
|
|
4
|
+
|
|
5
|
+
declare function injectStore<T>(store: Type<T>): T;
|
|
6
|
+
|
|
7
|
+
interface StatoAngularConfig {
|
|
8
|
+
http?: StatoConfig;
|
|
9
|
+
devtools?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function provideStato(config?: StatoAngularConfig): _angular_core.EnvironmentProviders;
|
|
12
|
+
|
|
13
|
+
declare function createAngularStore<S extends object>(config: S & StatoStoreConfig<S>): any;
|
|
14
|
+
|
|
15
|
+
declare class StatoDevToolsComponent implements OnInit, OnDestroy {
|
|
16
|
+
private config;
|
|
17
|
+
private unsub?;
|
|
18
|
+
isOpen: _angular_core.WritableSignal<boolean>;
|
|
19
|
+
isMinimized: _angular_core.WritableSignal<boolean>;
|
|
20
|
+
activeTab: _angular_core.WritableSignal<"actions" | "state">;
|
|
21
|
+
logs: _angular_core.WritableSignal<ActionLog[]>;
|
|
22
|
+
selectedLog: _angular_core.WritableSignal<ActionLog | null>;
|
|
23
|
+
posX: _angular_core.WritableSignal<number>;
|
|
24
|
+
posY: _angular_core.WritableSignal<number>;
|
|
25
|
+
panelWidth: _angular_core.WritableSignal<number>;
|
|
26
|
+
panelHeight: _angular_core.WritableSignal<number>;
|
|
27
|
+
private isDragging;
|
|
28
|
+
private isResizing;
|
|
29
|
+
private dragOffsetX;
|
|
30
|
+
private dragOffsetY;
|
|
31
|
+
private startW;
|
|
32
|
+
private startH;
|
|
33
|
+
private startX;
|
|
34
|
+
private startY;
|
|
35
|
+
private boundMouseMove;
|
|
36
|
+
private boundMouseUp;
|
|
37
|
+
ngOnInit(): void;
|
|
38
|
+
ngOnDestroy(): void;
|
|
39
|
+
toggle(): void;
|
|
40
|
+
toggleMinimize(): void;
|
|
41
|
+
clear(): void;
|
|
42
|
+
selectLog(log: ActionLog): void;
|
|
43
|
+
formatTime(iso: string): string;
|
|
44
|
+
onDragStart(e: MouseEvent): void;
|
|
45
|
+
onResizeStart(e: MouseEvent): void;
|
|
46
|
+
onMouseMove(e: MouseEvent): void;
|
|
47
|
+
onMouseUp(): void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { type StatoAngularConfig, StatoDevToolsComponent, createAngularStore, injectStore, provideStato };
|