@coherent.js/state 1.0.0-beta.5 → 1.0.0-beta.6

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/types/index.d.ts +364 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coherent.js/state",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.6",
4
4
  "description": "Reactive state management for Coherent.js applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,7 +29,7 @@
29
29
  "access": "public"
30
30
  },
31
31
  "peerDependencies": {
32
- "@coherent.js/core": "1.0.0-beta.5"
32
+ "@coherent.js/core": "1.0.0-beta.6"
33
33
  },
34
34
  "types": "./types/index.d.ts",
35
35
  "files": [
package/types/index.d.ts CHANGED
@@ -3,138 +3,463 @@
3
3
  * @module @coherent.js/state
4
4
  */
5
5
 
6
- // ===== Reactive State Types =====
6
+ import type { CoherentNode, ComponentState } from '@coherent.js/core';
7
7
 
8
- export interface Observer<T = any> {
8
+ // ============================================================================
9
+ // Core Store Types
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Typed state store with subscribe and update capabilities
14
+ * @template T - The shape of the state object
15
+ */
16
+ export interface Store<T extends Record<string, unknown> = Record<string, unknown>> {
17
+ /**
18
+ * Get the current state
19
+ */
20
+ getState(): T;
21
+
22
+ /**
23
+ * Update state with partial object or updater function
24
+ */
25
+ setState(partial: Partial<T> | ((state: T) => Partial<T>)): void;
26
+
27
+ /**
28
+ * Subscribe to state changes
29
+ * @returns Unsubscribe function
30
+ */
31
+ subscribe(listener: (state: T, prevState: T) => void): () => void;
32
+
33
+ /**
34
+ * Destroy the store and clean up subscriptions
35
+ */
36
+ destroy(): void;
37
+ }
38
+
39
+ /**
40
+ * Store creation options
41
+ * @template T - The shape of the state object
42
+ */
43
+ export interface StoreOptions<T extends Record<string, unknown> = Record<string, unknown>> {
44
+ /** Initial state */
45
+ initialState: T;
46
+ /** Persistence configuration */
47
+ persist?: {
48
+ /** Storage key */
49
+ key: string;
50
+ /** Storage adapter (localStorage, sessionStorage, or custom) */
51
+ storage?: Storage;
52
+ /** Custom serialization */
53
+ serialize?: (state: T) => string;
54
+ /** Custom deserialization */
55
+ deserialize?: (value: string) => T;
56
+ /** Debounce persistence writes (ms) */
57
+ debounce?: number;
58
+ };
59
+ /** Enable devtools integration */
60
+ devtools?: boolean;
61
+ /** Store name for debugging */
62
+ name?: string;
63
+ /** Middleware functions */
64
+ middleware?: Array<StoreMiddleware<T>>;
65
+ }
66
+
67
+ /**
68
+ * Store middleware function
69
+ */
70
+ export type StoreMiddleware<T> = (
71
+ state: T,
72
+ action: string,
73
+ payload?: unknown
74
+ ) => T | void;
75
+
76
+ /**
77
+ * Create a typed state store
78
+ */
79
+ export function createStore<T extends Record<string, unknown>>(
80
+ options: StoreOptions<T>
81
+ ): Store<T>;
82
+
83
+ // ============================================================================
84
+ // Selector Types
85
+ // ============================================================================
86
+
87
+ /**
88
+ * Create a derived selector from store state
89
+ * @template T - Store state type
90
+ * @template R - Return type of selector
91
+ */
92
+ export function createSelector<T extends Record<string, unknown>, R>(
93
+ store: Store<T>,
94
+ selector: (state: T) => R
95
+ ): () => R;
96
+
97
+ /**
98
+ * Create a memoized selector with dependencies
99
+ */
100
+ export function createMemoizedSelector<T extends Record<string, unknown>, D extends unknown[], R>(
101
+ store: Store<T>,
102
+ dependencies: (...args: D) => unknown[],
103
+ selector: (state: T, ...deps: D) => R
104
+ ): (...args: D) => R;
105
+
106
+ // ============================================================================
107
+ // Action Types
108
+ // ============================================================================
109
+
110
+ /**
111
+ * Action type helper for type-safe actions
112
+ * @template T - Store state type
113
+ * @template P - Payload type (void for no payload)
114
+ */
115
+ export type Action<T, P = void> = P extends void
116
+ ? () => Partial<T>
117
+ : (payload: P) => Partial<T>;
118
+
119
+ /**
120
+ * Create typed action creators
121
+ */
122
+ export function createActions<
123
+ T extends Record<string, unknown>,
124
+ A extends Record<string, Action<T, unknown>>
125
+ >(
126
+ store: Store<T>,
127
+ actions: A
128
+ ): {
129
+ [K in keyof A]: A[K] extends Action<T, infer P>
130
+ ? P extends void
131
+ ? () => void
132
+ : (payload: P) => void
133
+ : never;
134
+ };
135
+
136
+ // ============================================================================
137
+ // Reactive State Types
138
+ // ============================================================================
139
+
140
+ /**
141
+ * Observer callback type
142
+ */
143
+ export interface Observer<T = unknown> {
9
144
  (value: T, oldValue: T): void;
10
145
  }
11
146
 
12
- export class Observable<T = any> {
147
+ /**
148
+ * Observable value wrapper
149
+ */
150
+ export class Observable<T = unknown> {
13
151
  constructor(initialValue: T);
152
+
153
+ /** Get current value */
14
154
  get(): T;
155
+
156
+ /** Set new value */
15
157
  set(value: T): void;
158
+
159
+ /** Subscribe to changes */
16
160
  subscribe(observer: Observer<T>): () => void;
161
+
162
+ /** Unsubscribe observer */
17
163
  unsubscribe(observer: Observer<T>): void;
164
+
165
+ /** Notify all observers */
18
166
  notify(): void;
19
167
  }
20
168
 
21
- export interface ReactiveStateOptions<T = any> {
169
+ /**
170
+ * Reactive state options
171
+ */
172
+ export interface ReactiveStateOptions<T = unknown> {
173
+ /** Initial state value */
22
174
  initialValue: T;
23
- computed?: Record<string, (state: T) => any>;
24
- watchers?: Record<string, Observer<any>>;
25
- middleware?: Array<(state: T, action: string, payload?: any) => T | void>;
175
+ /** Computed properties */
176
+ computed?: Record<string, (state: T) => unknown>;
177
+ /** Property watchers */
178
+ watchers?: Record<string, Observer<unknown>>;
179
+ /** Middleware functions */
180
+ middleware?: Array<(state: T, action: string, payload?: unknown) => T | void>;
26
181
  }
27
182
 
28
- export class ReactiveState<T = any> {
183
+ /**
184
+ * Reactive state class with computed properties and watchers
185
+ */
186
+ export class ReactiveState<T extends Record<string, unknown> = Record<string, unknown>> {
29
187
  constructor(options: ReactiveStateOptions<T>);
188
+
189
+ /** Get a property value */
30
190
  get<K extends keyof T>(key: K): T[K];
191
+
192
+ /** Set a property value */
31
193
  set<K extends keyof T>(key: K, value: T[K]): void;
194
+
195
+ /** Update multiple properties */
32
196
  update(partial: Partial<T>): void;
197
+
198
+ /** Subscribe to all changes */
33
199
  subscribe(observer: Observer<T>): () => void;
200
+
201
+ /** Watch a specific property */
34
202
  watch<K extends keyof T>(key: K, observer: Observer<T[K]>): () => void;
203
+
204
+ /** Get full state */
35
205
  getState(): T;
206
+
207
+ /** Reset to initial state */
36
208
  reset(): void;
37
209
  }
38
210
 
39
- export function createReactiveState<T = any>(options: ReactiveStateOptions<T>): ReactiveState<T>;
40
- export function observable<T = any>(initialValue: T): Observable<T>;
41
- export function computed<T = any>(fn: () => T, dependencies: Observable<any>[]): Observable<T>;
211
+ /**
212
+ * Create a reactive state instance
213
+ */
214
+ export function createReactiveState<T extends Record<string, unknown> = Record<string, unknown>>(
215
+ options: ReactiveStateOptions<T>
216
+ ): ReactiveState<T>;
217
+
218
+ /**
219
+ * Create a simple observable value
220
+ */
221
+ export function observable<T = unknown>(initialValue: T): Observable<T>;
222
+
223
+ /**
224
+ * Create a computed observable
225
+ */
226
+ export function computed<T = unknown>(
227
+ fn: () => T,
228
+ dependencies: Observable<unknown>[]
229
+ ): Observable<T>;
42
230
 
231
+ /**
232
+ * State utility functions
233
+ */
43
234
  export const stateUtils: {
235
+ /** Batch multiple state updates */
44
236
  batch<T>(fn: () => T): T;
237
+ /** Run updates in a transaction */
45
238
  transaction<T>(fn: () => T): T;
239
+ /** Freeze state (make immutable) */
46
240
  freeze<T>(state: T): Readonly<T>;
241
+ /** Deep clone state */
47
242
  clone<T>(state: T): T;
48
243
  };
49
244
 
50
- // ===== SSR-Compatible State Manager Types =====
245
+ // ============================================================================
246
+ // SSR-Compatible State Manager
247
+ // ============================================================================
51
248
 
52
- export interface StateManagerOptions<T = any> {
249
+ /**
250
+ * State manager options
251
+ */
252
+ export interface StateManagerOptions<T = unknown> {
253
+ /** Initial state */
53
254
  initialState?: T;
255
+ /** Enable persistence */
54
256
  persist?: boolean;
257
+ /** Persistence key */
55
258
  key?: string;
259
+ /** Middleware functions */
56
260
  middleware?: Array<(state: T, action: string) => T | void>;
57
261
  }
58
262
 
59
- export interface State<T = any> {
263
+ /**
264
+ * Simple state interface
265
+ */
266
+ export interface State<T = unknown> {
267
+ /** Get current state */
60
268
  get(): T;
269
+ /** Set new state */
61
270
  set(value: T): void;
271
+ /** Update with partial */
62
272
  update(partial: Partial<T>): void;
273
+ /** Subscribe to changes */
63
274
  subscribe(listener: (state: T) => void): () => void;
275
+ /** Reset to initial state */
64
276
  reset(): void;
65
277
  }
66
278
 
67
- export function createState<T = any>(initialState: T, options?: StateManagerOptions<T>): State<T>;
279
+ /**
280
+ * Create a simple state container
281
+ */
282
+ export function createState<T = unknown>(
283
+ initialState: T,
284
+ options?: StateManagerOptions<T>
285
+ ): State<T>;
68
286
 
287
+ /**
288
+ * Global state manager for SSR
289
+ */
69
290
  export const globalStateManager: {
70
- getState<T = any>(key: string): T | undefined;
71
- setState<T = any>(key: string, value: T): void;
72
- subscribe<T = any>(key: string, listener: (state: T) => void): () => void;
291
+ /** Get state by key */
292
+ getState<T = unknown>(key: string): T | undefined;
293
+ /** Set state by key */
294
+ setState<T = unknown>(key: string, value: T): void;
295
+ /** Subscribe to state key */
296
+ subscribe<T = unknown>(key: string, listener: (state: T) => void): () => void;
297
+ /** Clear state (optionally by key) */
73
298
  clear(key?: string): void;
74
299
  };
75
300
 
76
- // ===== Context API Types =====
301
+ // ============================================================================
302
+ // Context API
303
+ // ============================================================================
77
304
 
78
- export interface ContextValue<T = any> {
305
+ /**
306
+ * Context value wrapper
307
+ */
308
+ export interface ContextValue<T = unknown> {
79
309
  value: T;
80
310
  subscribers: Set<(value: T) => void>;
81
311
  }
82
312
 
83
- export function provideContext<T = any>(key: string, value: T): void;
84
- export function createContextProvider<T = any>(key: string, value: T): { key: string; value: T };
85
- export function useContext<T = any>(key: string, defaultValue?: T): T;
86
- export function restoreContext(contexts: Record<string, any>): void;
313
+ /**
314
+ * Provide a context value
315
+ */
316
+ export function provideContext<T = unknown>(key: string, value: T): void;
317
+
318
+ /**
319
+ * Create a context provider
320
+ */
321
+ export function createContextProvider<T = unknown>(
322
+ key: string,
323
+ value: T
324
+ ): { key: string; value: T };
325
+
326
+ /**
327
+ * Use/consume a context value
328
+ */
329
+ export function useContext<T = unknown>(key: string, defaultValue?: T): T;
330
+
331
+ /**
332
+ * Restore context from saved state
333
+ */
334
+ export function restoreContext(contexts: Record<string, unknown>): void;
335
+
336
+ /**
337
+ * Clear all context stacks
338
+ */
87
339
  export function clearAllContexts(): void;
88
340
 
89
- // ===== Persistent State Types =====
341
+ // ============================================================================
342
+ // Persistent State
343
+ // ============================================================================
90
344
 
345
+ /**
346
+ * Persistence adapter interface
347
+ */
91
348
  export interface PersistenceAdapter {
349
+ /** Get item from storage */
92
350
  getItem(key: string): Promise<string | null> | string | null;
351
+ /** Set item in storage */
93
352
  setItem(key: string, value: string): Promise<void> | void;
353
+ /** Remove item from storage */
94
354
  removeItem(key: string): Promise<void> | void;
95
355
  }
96
356
 
97
- export interface PersistentStateOptions<T = any> extends StateManagerOptions<T> {
357
+ /**
358
+ * Persistent state options
359
+ */
360
+ export interface PersistentStateOptions<T = unknown> extends StateManagerOptions<T> {
361
+ /** Required: storage key */
98
362
  key: string;
363
+ /** Storage adapter */
99
364
  storage?: PersistenceAdapter;
365
+ /** Custom serialization */
100
366
  serialize?: (state: T) => string;
367
+ /** Custom deserialization */
101
368
  deserialize?: (data: string) => T;
369
+ /** Debounce writes (ms) */
102
370
  debounce?: number;
103
371
  }
104
372
 
105
- export function createPersistentState<T = any>(options: PersistentStateOptions<T>): State<T>;
106
- export function withLocalStorage<T = any>(state: State<T>, key: string): State<T>;
107
- export function withSessionStorage<T = any>(state: State<T>, key: string): State<T>;
108
- export function withIndexedDB<T = any>(state: State<T>, key: string, dbName?: string): Promise<State<T>>;
373
+ /**
374
+ * Create a persistent state
375
+ */
376
+ export function createPersistentState<T = unknown>(
377
+ options: PersistentStateOptions<T>
378
+ ): State<T>;
379
+
380
+ /**
381
+ * Wrap state with localStorage persistence
382
+ */
383
+ export function withLocalStorage<T = unknown>(state: State<T>, key: string): State<T>;
384
+
385
+ /**
386
+ * Wrap state with sessionStorage persistence
387
+ */
388
+ export function withSessionStorage<T = unknown>(state: State<T>, key: string): State<T>;
389
+
390
+ /**
391
+ * Wrap state with IndexedDB persistence
392
+ */
393
+ export function withIndexedDB<T = unknown>(
394
+ state: State<T>,
395
+ key: string,
396
+ dbName?: string
397
+ ): Promise<State<T>>;
109
398
 
110
- // ===== Validated State Types =====
399
+ // ============================================================================
400
+ // Validated State
401
+ // ============================================================================
111
402
 
112
- export interface ValidationRule<T = any> {
403
+ /**
404
+ * Validation rule function
405
+ */
406
+ export interface ValidationRule<T = unknown> {
113
407
  (value: T): boolean | string;
114
408
  }
115
409
 
116
- export interface ValidatedStateOptions<T = any> extends StateManagerOptions<T> {
117
- validators: Record<keyof T, ValidationRule<T[keyof T]>[]>;
410
+ /**
411
+ * Validated state options
412
+ */
413
+ export interface ValidatedStateOptions<T extends Record<string, unknown> = Record<string, unknown>>
414
+ extends StateManagerOptions<T> {
415
+ /** Validation rules by property */
416
+ validators: { [K in keyof T]?: ValidationRule<T[K]>[] };
417
+ /** Validate on every change */
118
418
  validateOnChange?: boolean;
419
+ /** Throw on validation failure */
119
420
  strict?: boolean;
120
421
  }
121
422
 
122
- export interface ValidatedState<T = any> extends State<T> {
123
- validate(): { valid: boolean; errors: Record<keyof T, string[]> };
423
+ /**
424
+ * Validated state interface
425
+ */
426
+ export interface ValidatedState<T extends Record<string, unknown> = Record<string, unknown>>
427
+ extends State<T> {
428
+ /** Validate current state */
429
+ validate(): { valid: boolean; errors: { [K in keyof T]?: string[] } };
430
+ /** Check if state is valid */
124
431
  isValid(): boolean;
125
- getErrors(): Record<keyof T, string[]>;
432
+ /** Get validation errors */
433
+ getErrors(): { [K in keyof T]?: string[] };
126
434
  }
127
435
 
128
- export function createValidatedState<T = any>(options: ValidatedStateOptions<T>): ValidatedState<T>;
436
+ /**
437
+ * Create a validated state
438
+ */
439
+ export function createValidatedState<T extends Record<string, unknown> = Record<string, unknown>>(
440
+ options: ValidatedStateOptions<T>
441
+ ): ValidatedState<T>;
129
442
 
443
+ /**
444
+ * Built-in validators
445
+ */
130
446
  export const validators: {
447
+ /** Required value */
131
448
  required(message?: string): ValidationRule;
449
+ /** Minimum length */
132
450
  minLength(length: number, message?: string): ValidationRule;
451
+ /** Maximum length */
133
452
  maxLength(length: number, message?: string): ValidationRule;
453
+ /** Minimum value */
134
454
  min(value: number, message?: string): ValidationRule;
455
+ /** Maximum value */
135
456
  max(value: number, message?: string): ValidationRule;
457
+ /** Pattern matching */
136
458
  pattern(regex: RegExp, message?: string): ValidationRule;
459
+ /** Email format */
137
460
  email(message?: string): ValidationRule;
461
+ /** URL format */
138
462
  url(message?: string): ValidationRule;
139
- custom(fn: (value: any) => boolean | string): ValidationRule;
463
+ /** Custom validator */
464
+ custom(fn: (value: unknown) => boolean | string): ValidationRule;
140
465
  };