@blac/react 2.0.0-rc.0 → 2.0.0-rc.3

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