@ngstato/core 0.1.2 → 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 CHANGED
@@ -23,14 +23,49 @@ const store = createStore({
23
23
  }
24
24
  },
25
25
 
26
- computed: {
26
+ selectors: {
27
27
  total: (state) => state.users.length
28
- }
28
+ },
29
+
30
+ effects: [
31
+ [
32
+ (state) => state.users.length,
33
+ (count) => console.log('Total users:', count)
34
+ ]
35
+ ]
29
36
  })
30
37
 
31
38
  await store.loadUsers()
32
39
  console.log(store.users) // User[]
33
- console.log(store.total) // number
40
+ console.log(store.total) // number (selector memoïzé)
41
+ ```
42
+
43
+ ## Réactions inter-stores (`on`)
44
+
45
+ Écouter la fin d’exécution d’une action précise (success **ou** error) et réagir ailleurs (toast, analytics, déclencher une autre action, etc.).
46
+
47
+ ```ts
48
+ import { createStore, on } from '@ngstato/core'
49
+
50
+ const userStore = createStore({
51
+ users: [] as { id: string; name: string }[],
52
+ actions: {
53
+ async loadUsers(state) {
54
+ state.users = await fetch('/api/users').then(r => r.json())
55
+ }
56
+ }
57
+ })
58
+
59
+ const unsubscribe = on(userStore.loadUsers, (_store, event) => {
60
+ if (event?.status === 'success') {
61
+ console.log(`[users] loaded in ${event.duration}ms`)
62
+ } else {
63
+ console.error('[users] load failed:', event?.error)
64
+ }
65
+ })
66
+
67
+ // Plus tard…
68
+ unsubscribe()
34
69
  ```
35
70
 
36
71
  ## Helpers
@@ -40,9 +75,26 @@ console.log(store.total) // number
40
75
  | `abortable()` | Annule la requête précédente si l'action est rappelée |
41
76
  | `debounced()` | Debounce sans RxJS |
42
77
  | `throttled()` | Throttle sans RxJS |
78
+ | `exclusive()` | Ignore les nouveaux appels pendant qu'une exécution est en cours |
43
79
  | `retryable()` | Retry avec backoff fixe ou exponentiel |
80
+ | `queued()` | Met en file et exécute les appels dans l'ordre d'arrivée |
81
+ | `distinctUntilChanged()` | Ignore les appels si l’entrée ne change pas |
82
+ | `forkJoin()` | Lance des tâches en parallèle, attend tout |
83
+ | `race()` | Retourne la première tâche terminée |
84
+ | `createEntityAdapter()` | Collections normalisées (ids/entities) + CRUD/selectors |
85
+ | `withEntities()` | Injecte une slice entities + actions/selectors générés |
86
+ | `combineLatest()` | Compose plusieurs deps pour `effects` |
87
+ | `combineLatestStream()` | Combine plusieurs flux externes (compatible RxJS) |
88
+ | `pipeStream()` + operators | Composable streams (`map`, `filter`, `distinctUntilChanged`, `debounce`, `throttle`, `switchMap`, `concatMap`, `exhaustMap`, `mergeMap`, `catchError`, `retry`) |
44
89
  | `fromStream()` | Realtime — WebSocket, Firebase, Supabase |
45
90
  | `optimistic()` | Optimistic update + rollback automatique |
91
+ | `withPersist()` | Persistance localStorage/sessionStorage + migration |
92
+
93
+ ## Nouvautés v0.2
94
+
95
+ - `selectors` memoïzés (recalcul seulement quand les dépendances changent)
96
+ - `effects` réactifs explicites avec cleanup automatique
97
+ - `withPersist()` pour hydrater/persister le state
46
98
 
47
99
  ## Documentation
48
100
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,16 @@
1
- type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'hooks'>;
1
+ type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'selectors' | 'hooks'>;
2
2
  type Action<S> = (state: S, ...args: any[]) => void | Promise<void> | (() => void);
3
3
  type ActionsMap<S> = Record<string, Action<S>>;
4
4
  type ComputedFn<S> = (state: S) => unknown;
5
+ type SelectorFn<S> = (state: S) => unknown;
6
+ type EffectDepsFn<S> = (state: S) => unknown | unknown[];
7
+ type EffectCleanup = void | (() => void);
8
+ type EffectRunner<S> = (depsValue: unknown | unknown[], ctx: {
9
+ state: Readonly<S>;
10
+ store: any;
11
+ prevDepsValue?: unknown | unknown[];
12
+ }) => EffectCleanup | Promise<EffectCleanup>;
13
+ type EffectEntry<S> = [EffectDepsFn<S>, EffectRunner<S>];
5
14
  interface StatoHooks<S> {
6
15
  onInit?: (store: S) => void | Promise<void>;
7
16
  onDestroy?: (store: S) => void | Promise<void>;
@@ -13,6 +22,8 @@ interface StatoHooks<S> {
13
22
  interface StatoStoreConfig<S extends object> {
14
23
  actions?: ActionsMap<StateSlice<S>>;
15
24
  computed?: Record<string, ComputedFn<StateSlice<S>> | unknown[]>;
25
+ selectors?: Record<string, SelectorFn<StateSlice<S>> | unknown[]>;
26
+ effects?: EffectEntry<StateSlice<S>>[];
16
27
  hooks?: StatoHooks<any>;
17
28
  [key: string]: unknown;
18
29
  }
@@ -34,6 +45,13 @@ declare class StatoHttpError extends Error {
34
45
  }
35
46
 
36
47
  declare function createStore<S extends object>(config: S & StatoStoreConfig<S>): any;
48
+ declare function on<S extends object>(sourceAction: Function, handler: (store: S, event?: {
49
+ name: string;
50
+ args: unknown[];
51
+ status: 'success' | 'error';
52
+ duration: number;
53
+ error?: Error;
54
+ }) => void | Promise<void>): () => void;
37
55
 
38
56
  interface RequestOptions {
39
57
  params?: Record<string, string | number | boolean>;
@@ -95,6 +113,164 @@ declare function fromStream<S, T>(setupFn: (state: S) => StatoObservable<T>, upd
95
113
 
96
114
  declare function optimistic<S, A extends unknown[]>(immediate: (state: S, ...args: A) => void, confirm: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
97
115
 
116
+ declare function exclusive<S, A extends unknown[]>(fn: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
117
+
118
+ declare function queued<S, A extends unknown[]>(fn: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
119
+
120
+ type Comparator<T> = (prev: T, next: T) => boolean;
121
+ declare function distinctUntilChanged<S, A extends unknown[], K>(fn: (state: S, ...args: A) => void | Promise<void>, keySelector: (...args: A) => K, comparator?: Comparator<K>): (state: S, ...args: A) => Promise<void>;
122
+
123
+ type TaskContext$1 = {
124
+ signal: AbortSignal;
125
+ };
126
+ type Task$1<T> = (ctx: TaskContext$1) => Promise<T> | T;
127
+ type ForkJoinOptions = {
128
+ signal?: AbortSignal;
129
+ };
130
+ declare function forkJoin<T extends Record<string, Task$1<any>>>(tasks: T, options?: ForkJoinOptions): Promise<{
131
+ [K in keyof T]: Awaited<ReturnType<T[K]>>;
132
+ }>;
133
+
134
+ type TaskContext = {
135
+ signal: AbortSignal;
136
+ };
137
+ type Task<T> = (ctx: TaskContext) => Promise<T> | T;
138
+ type RaceOptions = {
139
+ signal?: AbortSignal;
140
+ };
141
+ declare function race<T>(tasks: Array<Task<T>>, options?: RaceOptions): Promise<T>;
142
+
143
+ type DepFn<S, T> = (state: S) => T;
144
+ declare function combineLatest<S>(): <T extends unknown[]>(...deps: { [K in keyof T]: DepFn<S, T[K]>; }) => (state: S) => T;
145
+
146
+ declare function combineLatestStream<T extends unknown[]>(...sources: {
147
+ [K in keyof T]: StatoObservable<T[K]>;
148
+ }): StatoObservable<T>;
149
+
150
+ type EntityId = string | number;
151
+ interface EntityState<T> {
152
+ ids: EntityId[];
153
+ entities: Record<string, T>;
154
+ }
155
+ type Update<T> = {
156
+ id: EntityId;
157
+ changes: Partial<T>;
158
+ };
159
+ type SelectId<T> = (entity: T) => EntityId;
160
+ interface EntityAdapterOptions<T> {
161
+ selectId?: SelectId<T>;
162
+ sortComparer?: (a: T, b: T) => number;
163
+ }
164
+ declare function createEntityAdapter<T extends Record<string, any>>(options?: EntityAdapterOptions<T>): {
165
+ selectId: SelectId<T>;
166
+ sortComparer: ((a: T, b: T) => number) | undefined;
167
+ getInitialState: <E extends object = {}>(extra?: E) => EntityState<T> & E;
168
+ addOne: (entity: T, state: EntityState<T>) => void;
169
+ addMany: (entities: T[], state: EntityState<T>) => void;
170
+ setAll: (entities: T[], state: EntityState<T>) => void;
171
+ upsertOne: (entity: T, state: EntityState<T>) => void;
172
+ upsertMany: (entities: T[], state: EntityState<T>) => void;
173
+ updateOne: (update: Update<T>, state: EntityState<T>) => void;
174
+ removeOne: (id: EntityId, state: EntityState<T>) => void;
175
+ removeMany: (ids: EntityId[], state: EntityState<T>) => void;
176
+ removeAll: (state: EntityState<T>) => void;
177
+ getSelectors: <S = EntityState<T>>(selectState?: (state: S) => EntityState<T>) => {
178
+ selectIds: (state: S | EntityState<T>) => EntityId[];
179
+ selectEntities: (state: S | EntityState<T>) => Record<string, T>;
180
+ selectAll: (state: S | EntityState<T>) => T[];
181
+ selectTotal: (state: S | EntityState<T>) => number;
182
+ selectById: (state: S | EntityState<T>, id: EntityId) => T;
183
+ };
184
+ };
185
+
186
+ type EntityAdapter<T> = {
187
+ getInitialState: <E extends object = {}>(extra?: E) => EntityState<T> & E;
188
+ addOne: (entity: T, state: EntityState<T>) => void;
189
+ addMany: (entities: T[], state: EntityState<T>) => void;
190
+ setAll: (entities: T[], state: EntityState<T>) => void;
191
+ upsertOne: (entity: T, state: EntityState<T>) => void;
192
+ upsertMany: (entities: T[], state: EntityState<T>) => void;
193
+ updateOne: (update: Update<T>, state: EntityState<T>) => void;
194
+ removeOne: (id: EntityId, state: EntityState<T>) => void;
195
+ removeMany: (ids: EntityId[], state: EntityState<T>) => void;
196
+ removeAll: (state: EntityState<T>) => void;
197
+ getSelectors: <S = EntityState<T>>(selectState?: (state: S) => EntityState<T>) => {
198
+ selectIds: (state: S | EntityState<T>) => EntityId[];
199
+ selectEntities: (state: S | EntityState<T>) => Record<string, T>;
200
+ selectAll: (state: S | EntityState<T>) => T[];
201
+ selectTotal: (state: S | EntityState<T>) => number;
202
+ selectById: (state: S | EntityState<T>, id: EntityId) => T | undefined;
203
+ };
204
+ };
205
+ type WithEntitiesSelectorsNames = Partial<{
206
+ ids: string;
207
+ entities: string;
208
+ all: string;
209
+ total: string;
210
+ byId: string;
211
+ }>;
212
+ type WithEntitiesActionsNames = Partial<{
213
+ addOne: string;
214
+ addMany: string;
215
+ setAll: string;
216
+ upsertOne: string;
217
+ upsertMany: string;
218
+ updateOne: string;
219
+ removeOne: string;
220
+ removeMany: string;
221
+ removeAll: string;
222
+ }>;
223
+ type WithEntitiesOptions<T> = {
224
+ key: string;
225
+ adapter: EntityAdapter<T>;
226
+ initial?: T[];
227
+ selectors?: WithEntitiesSelectorsNames;
228
+ actions?: WithEntitiesActionsNames;
229
+ };
230
+ declare function withEntities<S extends object, T>(config: S & StatoStoreConfig<S>, options: WithEntitiesOptions<T>): S & StatoStoreConfig<S>;
231
+
232
+ type MaybeObservable<T> = StatoObservable<T> | Promise<T> | T;
233
+ type StreamOperator<I, O> = (source: StatoObservable<I>) => StatoObservable<O>;
234
+ declare function pipeStream<T>(source: StatoObservable<T>): StatoObservable<T>;
235
+ declare function pipeStream<T, A>(source: StatoObservable<T>, op1: StreamOperator<T, A>): StatoObservable<A>;
236
+ declare function pipeStream<T, A, B>(source: StatoObservable<T>, op1: StreamOperator<T, A>, op2: StreamOperator<A, B>): StatoObservable<B>;
237
+ declare function pipeStream<T, A, B, C>(source: StatoObservable<T>, op1: StreamOperator<T, A>, op2: StreamOperator<A, B>, op3: StreamOperator<B, C>): StatoObservable<C>;
238
+ declare function mapStream<I, O>(mapFn: (value: I) => O): StreamOperator<I, O>;
239
+ declare function filterStream<T>(predicate: (value: T) => boolean): StreamOperator<T, T>;
240
+ type Mapper<I, O> = (value: I, ctx: {
241
+ signal: AbortSignal;
242
+ }) => MaybeObservable<O>;
243
+ declare function switchMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
244
+ declare function concatMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
245
+ declare function exhaustMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
246
+ declare function mergeMapStream<I, O>(mapper: Mapper<I, O>, options?: {
247
+ concurrency?: number;
248
+ }): StreamOperator<I, O>;
249
+ declare function distinctUntilChangedStream<T, K = T>(keySelector?: (value: T) => K, comparator?: (prev: K, next: K) => boolean): StreamOperator<T, T>;
250
+ declare function debounceStream<T>(ms: number): StreamOperator<T, T>;
251
+ declare function throttleStream<T>(ms: number): StreamOperator<T, T>;
252
+ declare function catchErrorStream<T>(handler: (error: unknown) => MaybeObservable<T>): StreamOperator<T, T>;
253
+ declare function retryStream<T>(options?: {
254
+ attempts?: number;
255
+ delay?: number;
256
+ backoff?: 'fixed' | 'exponential';
257
+ }): StreamOperator<T, T>;
258
+
259
+ interface PersistStorage {
260
+ getItem(key: string): string | null;
261
+ setItem(key: string, value: string): void;
262
+ removeItem(key: string): void;
263
+ }
264
+ interface PersistOptions<S extends object> {
265
+ key: string;
266
+ version?: number;
267
+ storage?: PersistStorage;
268
+ pick?: (keyof S)[];
269
+ migrate?: (data: unknown, fromVersion: number) => Partial<S>;
270
+ onError?: (error: Error) => void;
271
+ }
272
+ declare function withPersist<S extends object>(config: S & StatoStoreConfig<S>, options: PersistOptions<StateSlice<S>>): S & StatoStoreConfig<S>;
273
+
98
274
  interface ActionLog {
99
275
  id: number;
100
276
  name: string;
@@ -124,4 +300,4 @@ declare function createDevTools(maxLogs?: number): DevToolsInstance;
124
300
  declare const devTools: DevToolsInstance;
125
301
  declare function connectDevTools(store: any, storeName: string): void;
126
302
 
127
- export { type ActionLog, type DevToolsInstance, type DevToolsState, type RequestOptions, type StatoConfig, type StatoHooks, StatoHttp, StatoHttpError, type StatoStoreConfig, type StatoStoreInstance, abortable, configureHttp, connectDevTools, createDevTools, createHttp, createStore, debounced, devTools, fromStream, http, optimistic, retryable, throttled };
303
+ export { type ActionLog, type DevToolsInstance, type DevToolsState, type EffectDepsFn, type EffectEntry, type EffectRunner, type EntityAdapterOptions, type EntityId, type EntityState, type PersistOptions, type PersistStorage, type RequestOptions, type StatoConfig, type StatoHooks, StatoHttp, StatoHttpError, type StatoStoreConfig, type StatoStoreInstance, type Update, type WithEntitiesOptions, abortable, catchErrorStream, combineLatest, combineLatestStream, concatMapStream, configureHttp, connectDevTools, createDevTools, createEntityAdapter, createHttp, createStore, debounceStream, debounced, devTools, distinctUntilChanged, distinctUntilChangedStream, exclusive, exhaustMapStream, filterStream, forkJoin, fromStream, http, mapStream, mergeMapStream, on, optimistic, pipeStream, queued, race, retryStream, retryable, switchMapStream, throttleStream, throttled, withEntities, withPersist };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,16 @@
1
- type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'hooks'>;
1
+ type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'selectors' | 'hooks'>;
2
2
  type Action<S> = (state: S, ...args: any[]) => void | Promise<void> | (() => void);
3
3
  type ActionsMap<S> = Record<string, Action<S>>;
4
4
  type ComputedFn<S> = (state: S) => unknown;
5
+ type SelectorFn<S> = (state: S) => unknown;
6
+ type EffectDepsFn<S> = (state: S) => unknown | unknown[];
7
+ type EffectCleanup = void | (() => void);
8
+ type EffectRunner<S> = (depsValue: unknown | unknown[], ctx: {
9
+ state: Readonly<S>;
10
+ store: any;
11
+ prevDepsValue?: unknown | unknown[];
12
+ }) => EffectCleanup | Promise<EffectCleanup>;
13
+ type EffectEntry<S> = [EffectDepsFn<S>, EffectRunner<S>];
5
14
  interface StatoHooks<S> {
6
15
  onInit?: (store: S) => void | Promise<void>;
7
16
  onDestroy?: (store: S) => void | Promise<void>;
@@ -13,6 +22,8 @@ interface StatoHooks<S> {
13
22
  interface StatoStoreConfig<S extends object> {
14
23
  actions?: ActionsMap<StateSlice<S>>;
15
24
  computed?: Record<string, ComputedFn<StateSlice<S>> | unknown[]>;
25
+ selectors?: Record<string, SelectorFn<StateSlice<S>> | unknown[]>;
26
+ effects?: EffectEntry<StateSlice<S>>[];
16
27
  hooks?: StatoHooks<any>;
17
28
  [key: string]: unknown;
18
29
  }
@@ -34,6 +45,13 @@ declare class StatoHttpError extends Error {
34
45
  }
35
46
 
36
47
  declare function createStore<S extends object>(config: S & StatoStoreConfig<S>): any;
48
+ declare function on<S extends object>(sourceAction: Function, handler: (store: S, event?: {
49
+ name: string;
50
+ args: unknown[];
51
+ status: 'success' | 'error';
52
+ duration: number;
53
+ error?: Error;
54
+ }) => void | Promise<void>): () => void;
37
55
 
38
56
  interface RequestOptions {
39
57
  params?: Record<string, string | number | boolean>;
@@ -95,6 +113,164 @@ declare function fromStream<S, T>(setupFn: (state: S) => StatoObservable<T>, upd
95
113
 
96
114
  declare function optimistic<S, A extends unknown[]>(immediate: (state: S, ...args: A) => void, confirm: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
97
115
 
116
+ declare function exclusive<S, A extends unknown[]>(fn: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
117
+
118
+ declare function queued<S, A extends unknown[]>(fn: (state: S, ...args: A) => Promise<void>): (state: S, ...args: A) => Promise<void>;
119
+
120
+ type Comparator<T> = (prev: T, next: T) => boolean;
121
+ declare function distinctUntilChanged<S, A extends unknown[], K>(fn: (state: S, ...args: A) => void | Promise<void>, keySelector: (...args: A) => K, comparator?: Comparator<K>): (state: S, ...args: A) => Promise<void>;
122
+
123
+ type TaskContext$1 = {
124
+ signal: AbortSignal;
125
+ };
126
+ type Task$1<T> = (ctx: TaskContext$1) => Promise<T> | T;
127
+ type ForkJoinOptions = {
128
+ signal?: AbortSignal;
129
+ };
130
+ declare function forkJoin<T extends Record<string, Task$1<any>>>(tasks: T, options?: ForkJoinOptions): Promise<{
131
+ [K in keyof T]: Awaited<ReturnType<T[K]>>;
132
+ }>;
133
+
134
+ type TaskContext = {
135
+ signal: AbortSignal;
136
+ };
137
+ type Task<T> = (ctx: TaskContext) => Promise<T> | T;
138
+ type RaceOptions = {
139
+ signal?: AbortSignal;
140
+ };
141
+ declare function race<T>(tasks: Array<Task<T>>, options?: RaceOptions): Promise<T>;
142
+
143
+ type DepFn<S, T> = (state: S) => T;
144
+ declare function combineLatest<S>(): <T extends unknown[]>(...deps: { [K in keyof T]: DepFn<S, T[K]>; }) => (state: S) => T;
145
+
146
+ declare function combineLatestStream<T extends unknown[]>(...sources: {
147
+ [K in keyof T]: StatoObservable<T[K]>;
148
+ }): StatoObservable<T>;
149
+
150
+ type EntityId = string | number;
151
+ interface EntityState<T> {
152
+ ids: EntityId[];
153
+ entities: Record<string, T>;
154
+ }
155
+ type Update<T> = {
156
+ id: EntityId;
157
+ changes: Partial<T>;
158
+ };
159
+ type SelectId<T> = (entity: T) => EntityId;
160
+ interface EntityAdapterOptions<T> {
161
+ selectId?: SelectId<T>;
162
+ sortComparer?: (a: T, b: T) => number;
163
+ }
164
+ declare function createEntityAdapter<T extends Record<string, any>>(options?: EntityAdapterOptions<T>): {
165
+ selectId: SelectId<T>;
166
+ sortComparer: ((a: T, b: T) => number) | undefined;
167
+ getInitialState: <E extends object = {}>(extra?: E) => EntityState<T> & E;
168
+ addOne: (entity: T, state: EntityState<T>) => void;
169
+ addMany: (entities: T[], state: EntityState<T>) => void;
170
+ setAll: (entities: T[], state: EntityState<T>) => void;
171
+ upsertOne: (entity: T, state: EntityState<T>) => void;
172
+ upsertMany: (entities: T[], state: EntityState<T>) => void;
173
+ updateOne: (update: Update<T>, state: EntityState<T>) => void;
174
+ removeOne: (id: EntityId, state: EntityState<T>) => void;
175
+ removeMany: (ids: EntityId[], state: EntityState<T>) => void;
176
+ removeAll: (state: EntityState<T>) => void;
177
+ getSelectors: <S = EntityState<T>>(selectState?: (state: S) => EntityState<T>) => {
178
+ selectIds: (state: S | EntityState<T>) => EntityId[];
179
+ selectEntities: (state: S | EntityState<T>) => Record<string, T>;
180
+ selectAll: (state: S | EntityState<T>) => T[];
181
+ selectTotal: (state: S | EntityState<T>) => number;
182
+ selectById: (state: S | EntityState<T>, id: EntityId) => T;
183
+ };
184
+ };
185
+
186
+ type EntityAdapter<T> = {
187
+ getInitialState: <E extends object = {}>(extra?: E) => EntityState<T> & E;
188
+ addOne: (entity: T, state: EntityState<T>) => void;
189
+ addMany: (entities: T[], state: EntityState<T>) => void;
190
+ setAll: (entities: T[], state: EntityState<T>) => void;
191
+ upsertOne: (entity: T, state: EntityState<T>) => void;
192
+ upsertMany: (entities: T[], state: EntityState<T>) => void;
193
+ updateOne: (update: Update<T>, state: EntityState<T>) => void;
194
+ removeOne: (id: EntityId, state: EntityState<T>) => void;
195
+ removeMany: (ids: EntityId[], state: EntityState<T>) => void;
196
+ removeAll: (state: EntityState<T>) => void;
197
+ getSelectors: <S = EntityState<T>>(selectState?: (state: S) => EntityState<T>) => {
198
+ selectIds: (state: S | EntityState<T>) => EntityId[];
199
+ selectEntities: (state: S | EntityState<T>) => Record<string, T>;
200
+ selectAll: (state: S | EntityState<T>) => T[];
201
+ selectTotal: (state: S | EntityState<T>) => number;
202
+ selectById: (state: S | EntityState<T>, id: EntityId) => T | undefined;
203
+ };
204
+ };
205
+ type WithEntitiesSelectorsNames = Partial<{
206
+ ids: string;
207
+ entities: string;
208
+ all: string;
209
+ total: string;
210
+ byId: string;
211
+ }>;
212
+ type WithEntitiesActionsNames = Partial<{
213
+ addOne: string;
214
+ addMany: string;
215
+ setAll: string;
216
+ upsertOne: string;
217
+ upsertMany: string;
218
+ updateOne: string;
219
+ removeOne: string;
220
+ removeMany: string;
221
+ removeAll: string;
222
+ }>;
223
+ type WithEntitiesOptions<T> = {
224
+ key: string;
225
+ adapter: EntityAdapter<T>;
226
+ initial?: T[];
227
+ selectors?: WithEntitiesSelectorsNames;
228
+ actions?: WithEntitiesActionsNames;
229
+ };
230
+ declare function withEntities<S extends object, T>(config: S & StatoStoreConfig<S>, options: WithEntitiesOptions<T>): S & StatoStoreConfig<S>;
231
+
232
+ type MaybeObservable<T> = StatoObservable<T> | Promise<T> | T;
233
+ type StreamOperator<I, O> = (source: StatoObservable<I>) => StatoObservable<O>;
234
+ declare function pipeStream<T>(source: StatoObservable<T>): StatoObservable<T>;
235
+ declare function pipeStream<T, A>(source: StatoObservable<T>, op1: StreamOperator<T, A>): StatoObservable<A>;
236
+ declare function pipeStream<T, A, B>(source: StatoObservable<T>, op1: StreamOperator<T, A>, op2: StreamOperator<A, B>): StatoObservable<B>;
237
+ declare function pipeStream<T, A, B, C>(source: StatoObservable<T>, op1: StreamOperator<T, A>, op2: StreamOperator<A, B>, op3: StreamOperator<B, C>): StatoObservable<C>;
238
+ declare function mapStream<I, O>(mapFn: (value: I) => O): StreamOperator<I, O>;
239
+ declare function filterStream<T>(predicate: (value: T) => boolean): StreamOperator<T, T>;
240
+ type Mapper<I, O> = (value: I, ctx: {
241
+ signal: AbortSignal;
242
+ }) => MaybeObservable<O>;
243
+ declare function switchMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
244
+ declare function concatMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
245
+ declare function exhaustMapStream<I, O>(mapper: Mapper<I, O>): StreamOperator<I, O>;
246
+ declare function mergeMapStream<I, O>(mapper: Mapper<I, O>, options?: {
247
+ concurrency?: number;
248
+ }): StreamOperator<I, O>;
249
+ declare function distinctUntilChangedStream<T, K = T>(keySelector?: (value: T) => K, comparator?: (prev: K, next: K) => boolean): StreamOperator<T, T>;
250
+ declare function debounceStream<T>(ms: number): StreamOperator<T, T>;
251
+ declare function throttleStream<T>(ms: number): StreamOperator<T, T>;
252
+ declare function catchErrorStream<T>(handler: (error: unknown) => MaybeObservable<T>): StreamOperator<T, T>;
253
+ declare function retryStream<T>(options?: {
254
+ attempts?: number;
255
+ delay?: number;
256
+ backoff?: 'fixed' | 'exponential';
257
+ }): StreamOperator<T, T>;
258
+
259
+ interface PersistStorage {
260
+ getItem(key: string): string | null;
261
+ setItem(key: string, value: string): void;
262
+ removeItem(key: string): void;
263
+ }
264
+ interface PersistOptions<S extends object> {
265
+ key: string;
266
+ version?: number;
267
+ storage?: PersistStorage;
268
+ pick?: (keyof S)[];
269
+ migrate?: (data: unknown, fromVersion: number) => Partial<S>;
270
+ onError?: (error: Error) => void;
271
+ }
272
+ declare function withPersist<S extends object>(config: S & StatoStoreConfig<S>, options: PersistOptions<StateSlice<S>>): S & StatoStoreConfig<S>;
273
+
98
274
  interface ActionLog {
99
275
  id: number;
100
276
  name: string;
@@ -124,4 +300,4 @@ declare function createDevTools(maxLogs?: number): DevToolsInstance;
124
300
  declare const devTools: DevToolsInstance;
125
301
  declare function connectDevTools(store: any, storeName: string): void;
126
302
 
127
- export { type ActionLog, type DevToolsInstance, type DevToolsState, type RequestOptions, type StatoConfig, type StatoHooks, StatoHttp, StatoHttpError, type StatoStoreConfig, type StatoStoreInstance, abortable, configureHttp, connectDevTools, createDevTools, createHttp, createStore, debounced, devTools, fromStream, http, optimistic, retryable, throttled };
303
+ export { type ActionLog, type DevToolsInstance, type DevToolsState, type EffectDepsFn, type EffectEntry, type EffectRunner, type EntityAdapterOptions, type EntityId, type EntityState, type PersistOptions, type PersistStorage, type RequestOptions, type StatoConfig, type StatoHooks, StatoHttp, StatoHttpError, type StatoStoreConfig, type StatoStoreInstance, type Update, type WithEntitiesOptions, abortable, catchErrorStream, combineLatest, combineLatestStream, concatMapStream, configureHttp, connectDevTools, createDevTools, createEntityAdapter, createHttp, createStore, debounceStream, debounced, devTools, distinctUntilChanged, distinctUntilChangedStream, exclusive, exhaustMapStream, filterStream, forkJoin, fromStream, http, mapStream, mergeMapStream, on, optimistic, pipeStream, queued, race, retryStream, retryable, switchMapStream, throttleStream, throttled, withEntities, withPersist };