@blac/react 2.0.0-rc.1 → 2.0.0-rc.4

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.
@@ -0,0 +1,368 @@
1
+ import { RefObject } from "react";
2
+
3
+ //#region ../blac/src/core/StateContainerRegistry.d.ts
4
+
5
+ /**
6
+ * Registry for managing StateContainer instances
7
+ */
8
+ declare class StateContainerRegistry {
9
+ private readonly instances;
10
+ private readonly types;
11
+ /**
12
+ * Register a type with isolation mode
13
+ */
14
+ register<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, isolated?: boolean): void;
15
+ /**
16
+ * Get or create a StateContainer instance
17
+ * For isolated: always creates new
18
+ * For shared: singleton per key
19
+ */
20
+ getOrCreate<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, key?: string, ...args: any[]): T;
21
+ /**
22
+ * Release a reference to an instance
23
+ * Disposes when ref count reaches zero (unless static keepAlive is true)
24
+ */
25
+ release<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, key?: string, forceDispose?: boolean): void;
26
+ /**
27
+ * Get all instances of a type (shared only, isolated aren't tracked)
28
+ */
29
+ getAll<T extends StateContainer<any>>(constructor: new (...args: any[]) => T): T[];
30
+ /**
31
+ * Clear all instances of a type
32
+ */
33
+ clear<T extends StateContainer<any>>(constructor: new (...args: any[]) => T): void;
34
+ /**
35
+ * Clear all instances from all types (for testing)
36
+ */
37
+ clearAll(): void;
38
+ /**
39
+ * Get registry statistics (for debugging)
40
+ */
41
+ getStats(): {
42
+ registeredTypes: number;
43
+ totalInstances: number;
44
+ typeBreakdown: Record<string, number>;
45
+ };
46
+ /**
47
+ * Get reference count for an instance
48
+ */
49
+ getRefCount<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, key?: string): number;
50
+ /**
51
+ * Check if an instance exists
52
+ */
53
+ hasInstance<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, key?: string): boolean;
54
+ }
55
+ //#endregion
56
+ //#region ../blac/src/core/StateContainer.d.ts
57
+ /**
58
+ * Configuration options for StateContainer
59
+ */
60
+ interface StateContainerConfig {
61
+ /** Container name for debugging */
62
+ name?: string;
63
+ /** Enable debug logging */
64
+ debug?: boolean;
65
+ /** Custom instance identifier */
66
+ instanceId?: string;
67
+ }
68
+ /**
69
+ * Listener function for state changes
70
+ */
71
+ type StateListener<S$1> = (state: S$1) => void;
72
+ /**
73
+ * Base abstract class for all state containers
74
+ */
75
+ declare abstract class StateContainer<S$1> {
76
+ private static _registry;
77
+ /**
78
+ * Set a custom registry (mainly for testing)
79
+ */
80
+ static setRegistry(registry: StateContainerRegistry): void;
81
+ /**
82
+ * Register a type as isolated or shared
83
+ */
84
+ static register<T extends StateContainer<any>>(this: new (...args: any[]) => T, isolated?: boolean): void;
85
+ /**
86
+ * Get or create an instance
87
+ * @param key - Optional instance key for shared instances
88
+ * @param args - Constructor arguments
89
+ */
90
+ static getOrCreate<T extends StateContainer<any>>(this: new (...args: any[]) => T, key?: string, ...args: any[]): T;
91
+ /**
92
+ * Release a reference to an instance
93
+ * @param key - Optional instance key
94
+ * @param forceDispose - Force dispose regardless of ref count or keepAlive
95
+ */
96
+ static release<T extends StateContainer<any>>(this: new (...args: any[]) => T, key?: string, forceDispose?: boolean): void;
97
+ /**
98
+ * Get all instances of this type
99
+ */
100
+ static getAll<T extends StateContainer<any>>(this: new (...args: any[]) => T): T[];
101
+ /**
102
+ * Clear all instances of this type
103
+ */
104
+ static clear<T extends StateContainer<any>>(this: new (...args: any[]) => T): void;
105
+ /**
106
+ * Clear all instances from all types (for testing)
107
+ */
108
+ static clearAllInstances(): void;
109
+ /**
110
+ * Get registry statistics (for debugging)
111
+ */
112
+ static getStats(): {
113
+ registeredTypes: number;
114
+ totalInstances: number;
115
+ typeBreakdown: Record<string, number>;
116
+ };
117
+ /**
118
+ * Get reference count for an instance
119
+ * @param key - Optional instance key
120
+ */
121
+ static getRefCount<T extends StateContainer<any>>(this: new (...args: any[]) => T, key?: string): number;
122
+ /**
123
+ * Check if an instance exists
124
+ * @param key - Optional instance key
125
+ */
126
+ static hasInstance<T extends StateContainer<any>>(this: new (...args: any[]) => T, key?: string): boolean;
127
+ private _state;
128
+ private readonly listeners;
129
+ private _disposed;
130
+ private readonly config;
131
+ readonly name: string;
132
+ readonly debug: boolean;
133
+ readonly instanceId: string;
134
+ /**
135
+ * Create a new StateContainer
136
+ */
137
+ constructor(initialState: S$1, config?: StateContainerConfig);
138
+ /**
139
+ * Get the current state
140
+ */
141
+ get state(): S$1;
142
+ /**
143
+ * Check if disposed
144
+ */
145
+ get isDisposed(): boolean;
146
+ /**
147
+ * Subscribe to state changes
148
+ * @returns Unsubscribe function
149
+ */
150
+ subscribe(listener: StateListener<S$1>): () => void;
151
+ /**
152
+ * Dispose the container
153
+ */
154
+ dispose(): void;
155
+ /**
156
+ * Emit a new state (with change detection)
157
+ */
158
+ protected emit(newState: S$1): void;
159
+ /**
160
+ * Update state using a function
161
+ */
162
+ protected update(updater: (current: S$1) => S$1): void;
163
+ /**
164
+ * Optional disposal hook for subclasses
165
+ */
166
+ protected onDispose?(): void;
167
+ /**
168
+ * Optional state change hook for subclasses
169
+ */
170
+ protected onStateChange?(newState: S$1, previousState: S$1): void;
171
+ }
172
+ //#endregion
173
+ //#region ../blac/src/types/branded.d.ts
174
+ /**
175
+ * Branded types for type-safe IDs
176
+ * These types ensure that IDs can't be accidentally mixed up
177
+ */
178
+ /**
179
+ * Helper type for cases where any object type is acceptable
180
+ * Used sparingly only where type cannot be more specific
181
+ * eslint-disable-next-line @typescript-eslint/no-explicit-any
182
+ */
183
+ type AnyObject = any;
184
+ //#endregion
185
+ //#region ../blac/src/types/utilities.d.ts
186
+ /**
187
+ * Extract state type from StateContainer
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * class CounterBloc extends Cubit<number> { ... }
192
+ * type State = ExtractState<CounterBloc>; // number
193
+ * ```
194
+ */
195
+ type ExtractState<T$1> = T$1 extends StateContainer<infer S> ? S : never;
196
+ /**
197
+ * Bloc constructor type - represents a class constructor for StateContainer subclasses
198
+ * Includes static methods from StateContainer for instance management
199
+ *
200
+ * Note: Uses `any` for state type to support variance - the actual Bloc instance
201
+ * will have the correct specific types inferred at usage sites.
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * function createBloc<TBloc extends StateContainer<any>>(
206
+ * BlocClass: BlocConstructor<TBloc>
207
+ * ): TBloc {
208
+ * return BlocClass.getOrCreate();
209
+ * }
210
+ * ```
211
+ */
212
+ type BlocConstructor<TBloc extends StateContainer<any>> = (new (...args: any[]) => TBloc) & {
213
+ getOrCreate?(instanceKey?: string, ...args: any[]): TBloc;
214
+ release?(instanceKey?: string): void;
215
+ isolated?: boolean;
216
+ keepAlive?: boolean;
217
+ };
218
+ //#endregion
219
+ //#region src/types.d.ts
220
+ /**
221
+ * Configuration options for the useBloc hook
222
+ *
223
+ * @template TBloc - The StateContainer type
224
+ *
225
+ * @example
226
+ * ```tsx
227
+ * const [state, bloc] = useBloc(CounterBloc, {
228
+ * staticProps: { initialCount: 0 },
229
+ * dependencies: (state) => [state.count],
230
+ * onMount: (bloc) => console.log('Mounted'),
231
+ * });
232
+ * ```
233
+ */
234
+ interface UseBlocOptions<TBloc extends StateContainer<AnyObject>> {
235
+ /**
236
+ * Static props to pass to the Bloc constructor
237
+ * Type should match the constructor's first parameter
238
+ */
239
+ staticProps?: AnyObject;
240
+ /**
241
+ * Custom instance ID for shared blocs
242
+ * - For isolated blocs, each useBloc call gets its own instance
243
+ * - For shared blocs, the same instanceId will share the same bloc instance
244
+ */
245
+ instanceId?: string;
246
+ /**
247
+ * Manual dependency tracking function
248
+ * - When provided, automatic proxy tracking is disabled
249
+ * - Component only re-renders when the returned values change (shallow equality)
250
+ *
251
+ * @param state - Current state of the bloc
252
+ * @param bloc - The bloc instance
253
+ * @returns Array of values to track
254
+ */
255
+ dependencies?: (state: ExtractState<TBloc>, bloc: TBloc) => unknown[];
256
+ /**
257
+ * Control automatic dependency tracking (default: true)
258
+ * - true: Automatically track accessed properties via Proxy
259
+ * - false: Disable tracking, all state changes trigger re-render
260
+ * - Ignored when `dependencies` option is provided
261
+ *
262
+ * @default true
263
+ */
264
+ autoTrack?: boolean;
265
+ /**
266
+ * Callback invoked when the component mounts
267
+ *
268
+ * @param bloc - The bloc instance
269
+ */
270
+ onMount?: (bloc: TBloc) => void;
271
+ /**
272
+ * Callback invoked when the component unmounts
273
+ *
274
+ * @param bloc - The bloc instance
275
+ */
276
+ onUnmount?: (bloc: TBloc) => void;
277
+ }
278
+ /**
279
+ * Return type of the useBloc hook
280
+ *
281
+ * @template TBloc - The StateContainer type
282
+ *
283
+ * @returns A tuple containing:
284
+ * - [0]: The current state (may be a Proxy for tracking)
285
+ * - [1]: The bloc instance with methods
286
+ * - [2]: Component ref (internal use only)
287
+ */
288
+ type UseBlocReturn<TBloc extends StateContainer<AnyObject>> = [ExtractState<TBloc>, TBloc, RefObject<ComponentRef>];
289
+ /**
290
+ * @internal
291
+ * Component reference object for internal tracking
292
+ * Used to persist instance IDs across React Strict Mode remounts
293
+ */
294
+ type ComponentRef = {
295
+ __blocInstanceId?: string;
296
+ __bridge?: any;
297
+ };
298
+ //#endregion
299
+ //#region src/useBloc.d.ts
300
+ /**
301
+ * Lifecycle: INITIAL MOUNT
302
+ * 1. useMemo runs once - creates bloc, subscribeFn, getSnapshotFn
303
+ * 2. useSyncExternalStore calls getSnapshotFn (1st time) - lazy creates tracker, starts tracking, returns proxy
304
+ * 3. Component renders - proxy tracks property accesses
305
+ * 4. useSyncExternalStore calls getSnapshotFn (2nd time) - captures tracked paths, starts new tracking, returns proxy
306
+ * 5. useSyncExternalStore calls subscribeFn - sets up state change listener
307
+ *
308
+ * Lifecycle: STATE CHANGE
309
+ * 1. Bloc state changes
310
+ * 2. subscribeFn callback checks hasChanges() - only re-renders if tracked paths changed
311
+ * 3. If re-render: getSnapshotFn captures previous paths, starts tracking, returns proxy
312
+ *
313
+ * Lifecycle: RE-RENDER (parent re-render)
314
+ * 1. useMemo returns cached values (same bloc, subscribeFn, getSnapshotFn)
315
+ * 2. useSyncExternalStore calls getSnapshotFn - captures paths, starts tracking, returns proxy
316
+ */
317
+ declare function useBloc<TBloc extends StateContainer<AnyObject>>(BlocClass: BlocConstructor<TBloc>, options?: UseBlocOptions<TBloc>): UseBlocReturn<TBloc>;
318
+ //#endregion
319
+ //#region src/useBlocActions.d.ts
320
+ /**
321
+ * Configuration options for the useBlocActions hook
322
+ *
323
+ * @template TBloc - The StateContainer type
324
+ */
325
+ interface UseBlocActionsOptions<TBloc extends StateContainer<AnyObject>> {
326
+ /**
327
+ * Static props to pass to the Bloc constructor
328
+ * Type should match the constructor's first parameter
329
+ */
330
+ staticProps?: AnyObject;
331
+ /**
332
+ * Custom instance ID for shared blocs
333
+ * - For isolated blocs, each useBlocActions call gets its own instance
334
+ * - For shared blocs, the same instanceId will share the same bloc instance
335
+ */
336
+ instanceId?: string;
337
+ /**
338
+ * Callback invoked when the component mounts
339
+ *
340
+ * @param bloc - The bloc instance
341
+ */
342
+ onMount?: (bloc: TBloc) => void;
343
+ /**
344
+ * Callback invoked when the component unmounts
345
+ *
346
+ * @param bloc - The bloc instance
347
+ */
348
+ onUnmount?: (bloc: TBloc) => void;
349
+ }
350
+ /**
351
+ * React hook for accessing bloc instance without state subscription.
352
+ * Use this when you only need to call bloc methods/actions without reading state.
353
+ *
354
+ * Benefits over useBloc:
355
+ * - No state subscription overhead
356
+ * - No proxy tracking
357
+ * - Component never re-renders due to bloc state changes
358
+ * - Lighter weight for action-only components
359
+ *
360
+ * @template TBloc - The StateContainer type
361
+ * @param BlocClass - The bloc class constructor
362
+ * @param options - Optional configuration
363
+ * @returns The bloc instance
364
+ */
365
+ declare function useBlocActions<TBloc extends StateContainer<AnyObject>>(BlocClass: BlocConstructor<TBloc>, options?: UseBlocActionsOptions<TBloc>): TBloc;
366
+ //#endregion
367
+ export { type UseBlocActionsOptions, type UseBlocOptions, type UseBlocReturn, useBloc, useBlocActions };
368
+ //# sourceMappingURL=index.d.cts.map