@blac/core 2.0.0-rc-11 → 2.0.0-rc-14

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 (55) hide show
  1. package/dist/index.cjs.js +2 -2
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +739 -260
  4. package/dist/index.es.js +1924 -1237
  5. package/dist/index.es.js.map +1 -1
  6. package/package.json +6 -7
  7. package/src/Blac.ts +82 -69
  8. package/src/Bloc.ts +45 -3
  9. package/src/BlocBase.ts +263 -454
  10. package/src/Cubit.ts +1 -16
  11. package/src/__tests__/Blac.config.test.ts +10 -17
  12. package/src/__tests__/Bloc.event.test.ts +27 -52
  13. package/src/__tests__/BlocBase.subscription.test.ts +349 -0
  14. package/src/__tests__/Cubit.test.ts +39 -50
  15. package/src/__tests__/memory-leaks.test.ts +383 -0
  16. package/src/__tests__/plugins.test.ts +464 -0
  17. package/src/adapter/BlacAdapter.ts +347 -207
  18. package/src/adapter/ProxyFactory.ts +196 -255
  19. package/src/adapter/__tests__/BlacAdapter.test.ts +71 -77
  20. package/src/adapter/__tests__/ProxyFactory.test.ts +1 -1
  21. package/src/adapter/index.ts +0 -1
  22. package/src/errors/BlacError.ts +69 -0
  23. package/src/errors/ErrorManager.ts +101 -0
  24. package/src/errors/handleError.ts +114 -0
  25. package/src/errors/index.ts +13 -0
  26. package/src/events.ts +7 -1
  27. package/src/index.ts +10 -1
  28. package/src/lifecycle/BlocLifecycle.ts +156 -0
  29. package/src/lifecycle/index.ts +1 -0
  30. package/src/plugins/BlocPluginRegistry.ts +240 -0
  31. package/src/plugins/SystemPluginRegistry.ts +242 -0
  32. package/src/plugins/__tests__/BlocPluginRegistry.test.ts +450 -0
  33. package/src/plugins/__tests__/SystemPluginRegistry.test.ts +404 -0
  34. package/src/plugins/index.ts +8 -0
  35. package/src/plugins/types.ts +129 -0
  36. package/src/subscription/README.md +132 -0
  37. package/src/subscription/SubscriptionManager.ts +395 -0
  38. package/src/subscription/__tests__/SubscriptionManager.test.ts +355 -0
  39. package/src/subscription/index.ts +2 -0
  40. package/src/subscription/types.ts +90 -0
  41. package/src/testing.ts +31 -37
  42. package/src/types.ts +4 -21
  43. package/src/utils/BatchingManager.ts +59 -0
  44. package/src/utils/RerenderLogger.ts +265 -0
  45. package/src/utils/__tests__/generateInstanceId.test.ts +104 -0
  46. package/src/utils/__tests__/shallowEqual.test.ts +171 -0
  47. package/src/utils/__tests__/uuid.test.ts +144 -0
  48. package/src/utils/generateInstanceId.ts +54 -0
  49. package/src/utils/shallowEqual.ts +1 -1
  50. package/README.md +0 -329
  51. package/src/BlacObserver.ts +0 -186
  52. package/src/__tests__/BlocBase.lifecycle.test.ts +0 -441
  53. package/src/__tests__/props.test.ts +0 -256
  54. package/src/adapter/ConsumerTracker.ts +0 -241
  55. package/src/adapter/__tests__/ConsumerTracker.test.ts +0 -562
package/dist/index.d.ts CHANGED
@@ -1,7 +1,21 @@
1
+ /**
2
+ * Adapter metadata provided to plugins
3
+ */
4
+ export declare interface AdapterMetadata {
5
+ componentName?: string;
6
+ blocInstance: BlocBase<any>;
7
+ renderCount: number;
8
+ trackedPaths?: string[];
9
+ isUsingDependencies?: boolean;
10
+ lastState?: any;
11
+ lastDependencyValues?: any[];
12
+ currentDependencyValues?: any[];
13
+ }
14
+
1
15
  export declare interface AdapterOptions<B extends BlocBase<any>> {
2
- id?: string;
16
+ instanceId?: string;
3
17
  dependencies?: (bloc: B) => unknown[];
4
- props?: any;
18
+ staticProps?: any;
5
19
  onMount?: (bloc: B) => void;
6
20
  onUnmount?: (bloc: B) => void;
7
21
  }
@@ -20,6 +34,7 @@ export declare class Blac {
20
34
  static get instance(): Blac;
21
35
  /** Timestamp when the instance was created */
22
36
  createdAt: number;
37
+ private errorManager;
23
38
  static get getAllBlocs(): <B extends BlocConstructor<any>>(blocClass: B, options?: {
24
39
  searchIsolated?: boolean;
25
40
  }) => InstanceType<B>[];
@@ -45,6 +60,8 @@ export declare class Blac {
45
60
  keepAliveBlocs: Set<BlocBase<unknown>>;
46
61
  /** Flag to control whether changes should be posted to document */
47
62
  postChangesToDocument: boolean;
63
+ /** System plugin registry */
64
+ readonly plugins: SystemPluginRegistry;
48
65
  /**
49
66
  * Creates a new Blac instance.
50
67
  * @param options - Configuration options including singleton control
@@ -159,24 +176,6 @@ export declare class Blac {
159
176
  */
160
177
  getBloc: <B extends BlocConstructor<BlocBase<any>>>(blocClass: B, options?: GetBlocOptions<InstanceType<B>>) => InstanceType<B>;
161
178
  static get getBloc(): <B extends BlocConstructor<BlocBase<any>>>(blocClass: B, options?: GetBlocOptions<InstanceType<B>>) => InstanceType<B>;
162
- /**
163
- * Gets a bloc instance or throws an error if it doesn't exist
164
- * @param blocClass - The bloc class to get
165
- * @param options - Options including:
166
- * - id: The instance ID (defaults to class name if not provided)
167
- * - props: Properties to pass to the bloc constructor
168
- * - instanceRef: Optional reference string for the instance
169
- */
170
- getBlocOrThrow: <B extends BlocConstructor<any>>(blocClass: B, options?: {
171
- id?: BlocInstanceId;
172
- props?: InferPropsFromGeneric<B>;
173
- instanceRef?: string;
174
- }) => InstanceType<B>;
175
- static get getBlocOrThrow(): <B extends BlocConstructor<any>>(blocClass: B, options?: {
176
- id?: BlocInstanceId;
177
- props?: InferPropsFromGeneric<B> | undefined;
178
- instanceRef?: string;
179
- }) => InstanceType<B>;
180
179
  /**
181
180
  * Gets all instances of a specific bloc class
182
181
  * @param blocClass - The bloc class to search for
@@ -217,10 +216,18 @@ export declare class Blac {
217
216
  isolatedBlocTypes: number;
218
217
  };
219
218
  /**
220
- * Validates consumer references and cleans up orphaned consumers
219
+ * Validates subscription references and cleans up orphaned blocs
221
220
  */
222
221
  validateConsumers: () => void;
223
222
  static get validateConsumers(): () => void;
223
+ /**
224
+ * Bootstrap the Blac instance and all plugins
225
+ */
226
+ bootstrap(): void;
227
+ /**
228
+ * Shutdown the Blac instance and all plugins
229
+ */
230
+ shutdown(): void;
224
231
  }
225
232
 
226
233
  /**
@@ -234,15 +241,24 @@ export declare class BlacAdapter<B extends BlocConstructor<BlocBase<any>>> {
234
241
  current: object;
235
242
  };
236
243
  blocInstance: InstanceType<B>;
237
- private consumerTracker;
238
- private static propsOwners;
239
- private lastProps?;
240
244
  unmountTime: number;
241
245
  mountTime: number;
246
+ private subscriptionId?;
247
+ private unsubscribe?;
242
248
  private dependencyValues?;
243
249
  private isUsingDependencies;
250
+ private trackedPaths;
251
+ private pendingTrackedPaths;
252
+ private cachedStateProxy?;
253
+ private cachedBlocProxy?;
254
+ private lastProxiedState?;
244
255
  private hasMounted;
245
256
  private mountCount;
257
+ private lastState?;
258
+ private lastDependencyValues?;
259
+ private componentName?;
260
+ private renderCount;
261
+ private lastDependenciesFn?;
246
262
  options?: AdapterOptions<InstanceType<B>>;
247
263
  constructor(instanceProps: {
248
264
  componentRef: {
@@ -251,35 +267,35 @@ export declare class BlacAdapter<B extends BlocConstructor<BlocBase<any>>> {
251
267
  blocConstructor: B;
252
268
  }, options?: typeof BlacAdapter.options);
253
269
  trackAccess(consumerRef: object, type: 'state' | 'class', path: string, value?: any): void;
254
- getConsumerDependencies(consumerRef: object): DependencyArray | null;
255
- shouldNotifyConsumer(consumerRef: object, changedPaths: Set<string>): boolean;
256
- updateLastNotified(consumerRef: object): void;
257
- resetConsumerTracking(): void;
270
+ updateBlocInstance(): InstanceType<B>;
271
+ createSubscription: (options: {
272
+ onChange: () => void;
273
+ }) => () => void;
274
+ hasDependencyValuesChanged: (oldValues: unknown[] | undefined, newValues: unknown[]) => boolean;
275
+ getStateProxy: () => BlocState<InstanceType<B>>;
276
+ getBlocProxy: () => InstanceType<B>;
258
277
  createStateProxy: <T extends object>(props: {
259
278
  target: T;
260
279
  }) => T;
261
280
  createClassProxy: <T extends object>(props: {
262
281
  target: T;
263
282
  }) => T;
264
- updateBlocInstance(): InstanceType<B>;
265
- createSubscription: (options: {
266
- onChange: () => void;
267
- }) => () => void;
268
283
  mount: () => void;
269
284
  unmount: () => void;
270
- getProxyState: (state: BlocState<InstanceType<B>>) => BlocState<InstanceType<B>>;
271
- getProxyBlocInstance: () => InstanceType<B>;
272
- get calledOnMount(): boolean;
273
- updateProps(props: any): void;
274
- private hasDependencyValuesChanged;
285
+ resetTracking(): void;
286
+ setComponentName(name: string): void;
287
+ notifyRender(): void;
288
+ private getAdapterMetadata;
289
+ private getValueAtPath;
290
+ private getStateChangedPaths;
291
+ private getDeepChangedPaths;
292
+ getLastRerenderReason(): any;
275
293
  }
276
294
 
277
295
  /**
278
296
  * Configuration options for the Blac instance
279
297
  */
280
298
  export declare interface BlacConfig {
281
- /** Whether to expose the Blac instance globally */
282
- exposeBlacInstance?: boolean;
283
299
  /**
284
300
  * Whether to enable proxy dependency tracking for automatic re-render optimization.
285
301
  * When false, state changes always cause re-renders unless dependencies are manually specified.
@@ -288,6 +304,24 @@ export declare interface BlacConfig {
288
304
  proxyDependencyTracking?: boolean;
289
305
  }
290
306
 
307
+ export declare class BlacError extends Error {
308
+ readonly category: ErrorCategory;
309
+ readonly severity: ErrorSeverity;
310
+ readonly context?: BlacErrorContext | undefined;
311
+ readonly cause?: unknown | undefined;
312
+ constructor(message: string, category: ErrorCategory, severity: ErrorSeverity, context?: BlacErrorContext | undefined, cause?: unknown | undefined);
313
+ toString(): string;
314
+ }
315
+
316
+ export declare type BlacErrorContext = {
317
+ blocName?: string;
318
+ blocId?: string;
319
+ consumerId?: string;
320
+ pluginName?: string;
321
+ operation?: string;
322
+ metadata?: Record<string, unknown>;
323
+ };
324
+
291
325
  /**
292
326
  * Interface for Blac instance management
293
327
  */
@@ -298,72 +332,27 @@ export declare interface BlacInstanceManager {
298
332
  }
299
333
 
300
334
  /**
301
- * A class that manages observers for a Bloc's state changes
302
- * @template S - The type of state being observed
335
+ * System-wide plugin that observes all blocs
303
336
  */
304
- export declare class BlacObservable<S = unknown> {
305
- /** The Bloc instance this observable is associated with */
306
- bloc: BlocBase<S>;
307
- /**
308
- * Creates a new BlacObservable instance
309
- * @param bloc - The Bloc instance to observe
310
- */
311
- constructor(bloc: BlocBase<S>);
312
- private _observers;
313
- /**
314
- * Gets the number of active observers
315
- * @returns The number of observers currently subscribed
316
- */
317
- get size(): number;
318
- /**
319
- * Gets the set of all observers
320
- * @returns The Set of all BlacObserver instances
321
- */
322
- get observers(): Set<BlacObserver<S>>;
323
- /**
324
- * Subscribes an observer to state changes
325
- * @param observer - The observer to subscribe
326
- * @returns A function that can be called to unsubscribe the observer
327
- */
328
- subscribe(observer: BlacObserver<S>): () => void;
329
- /**
330
- * Unsubscribes an observer from state changes
331
- * @param observer - The observer to unsubscribe
332
- */
333
- unsubscribe(observer: BlacObserver<S>): void;
334
- /**
335
- * Notifies all observers of a state change
336
- * @param newState - The new state value
337
- * @param oldState - The previous state value
338
- * @param action - Optional action that triggered the state change
339
- */
340
- notify(newState: S, oldState: S, action?: unknown): void;
341
- /**
342
- * Clears the observer set
343
- */
344
- clear(): void;
337
+ export declare interface BlacPlugin extends Plugin_2 {
338
+ beforeBootstrap?(): void;
339
+ afterBootstrap?(): void;
340
+ beforeShutdown?(): void;
341
+ afterShutdown?(): void;
342
+ onBlocCreated?(bloc: BlocBase<any>): void;
343
+ onBlocDisposed?(bloc: BlocBase<any>): void;
344
+ onStateChanged?(bloc: BlocBase<any>, previousState: any, currentState: any): void;
345
+ onEventAdded?(bloc: Bloc<any, any>, event: any): void;
346
+ onError?(error: Error, bloc: BlocBase<unknown>, context: ErrorContext): void;
347
+ onAdapterCreated?(adapter: any, metadata: AdapterMetadata): void;
348
+ onAdapterMount?(adapter: any, metadata: AdapterMetadata): void;
349
+ onAdapterUnmount?(adapter: any, metadata: AdapterMetadata): void;
350
+ onAdapterRender?(adapter: any, metadata: AdapterMetadata): void;
351
+ onAdapterDisposed?(adapter: any, metadata: AdapterMetadata): void;
345
352
  }
346
353
 
347
- /**
348
- * Represents an observer that can subscribe to state changes in a Bloc
349
- * @template S - The type of state being observed
350
- */
351
- export declare type BlacObserver<S> = {
352
- /** Function to be called when state changes */
353
- fn: (newState: S, oldState: S, action?: unknown) => void | Promise<void>;
354
- /** Optional function to determine if the observer should be notified of state changes */
355
- dependencyArray?: BlocHookDependencyArrayFn<S>;
356
- /** Dispose function for the observer */
357
- dispose?: () => void;
358
- /** Cached state values used for dependency comparison */
359
- lastState?: unknown[];
360
- /** Unique identifier for the observer */
361
- id: string;
362
- };
363
-
364
354
  export declare abstract class Bloc<S, // State type
365
- A extends BlocEventConstraint = BlocEventConstraint, // Base Action/Event type with proper constraints
366
- P = unknown> extends BlocBase<S, P> {
355
+ A extends BlocEventConstraint = BlocEventConstraint> extends BlocBase<S> {
367
356
  readonly eventHandlers: Map<new (...args: any[]) => A, (event: A, emit: (newState: S) => void) => void | Promise<void>>;
368
357
  /* Excluded from this release type: _eventQueue */
369
358
  /* Excluded from this release type: _isProcessingEvent */
@@ -386,104 +375,113 @@ P = unknown> extends BlocBase<S, P> {
386
375
  }
387
376
 
388
377
  /**
389
- * Base class for both Blocs and Cubits that provides core state management functionality.
390
- * Handles state transitions, observer notifications, lifecycle management, and addon integration.
391
- *
392
- * @abstract This class should be extended, not instantiated directly
393
- * @template S The type of state managed by this Bloc
394
- * @template P The type of props that can be passed during instance creation (optional)
378
+ * Base class for both Blocs and Cubits using unified subscription model.
395
379
  */
396
- export declare abstract class BlocBase<S, P = unknown> {
380
+ export declare abstract class BlocBase<S> {
397
381
  uid: string;
398
- /**
399
- * When true, every consumer will receive its own unique instance of this Bloc.
400
- * Use this when state should not be shared between components.
401
- * @default false
402
- */
382
+ blacInstance?: Blac;
403
383
  static isolated: boolean;
404
384
  get isIsolated(): boolean;
405
- /**
406
- * When true, the Bloc instance persists even when there are no active consumers.
407
- * Useful for maintaining state between component unmount/remount cycles.
408
- * @default false
409
- */
410
385
  static keepAlive: boolean;
411
386
  get isKeepAlive(): boolean;
387
+ _isolated: boolean;
388
+ _id: BlocInstanceId;
389
+ _instanceRef?: string;
390
+ _name: string;
412
391
  /**
413
- * Defines how dependencies are selected from the state for efficient updates.
414
- * When provided, observers will only be notified when selected dependencies change.
392
+ * Unified subscription manager for all state notifications
415
393
  */
416
- defaultDependencySelector: DependencySelector<S> | undefined;
417
- /* Excluded from this release type: _isolated */
418
- /* Excluded from this release type: _observer */
394
+ _subscriptionManager: SubscriptionManager<S>;
395
+ _state: S;
396
+ private _lifecycleManager;
397
+ private _batchingManager;
398
+ _keepAlive: boolean;
399
+ lastUpdate?: number;
400
+ _plugins: BlocPluginRegistry<S, any>;
401
+ onDispose?: () => void;
419
402
  /**
420
- * The unique identifier for this Bloc instance.
421
- * Defaults to the class name, but can be customized.
403
+ * Creates a new BlocBase instance with unified subscription management
422
404
  */
423
- _id: BlocInstanceId;
424
- /* Excluded from this release type: _instanceRef */
425
- /* Excluded from this release type: _keepAlive */
405
+ constructor(initialState: S);
426
406
  /**
427
- * @readonly
428
- * Timestamp when this Bloc instance was created, useful for debugging and performance tracking.
407
+ * Returns the current state
429
408
  */
430
- readonly _createdAt: number;
431
- /* Excluded from this release type: _disposalState */
432
- /* Excluded from this release type: _disposalRequestTime */
433
- /* Excluded from this release type: _state */
434
- /* Excluded from this release type: _oldState */
409
+ get state(): S;
435
410
  /**
436
- * Props passed during Bloc instance creation.
437
- * Can be used to configure or parameterize the Bloc's behavior.
411
+ * Subscribe to all state changes
438
412
  */
439
- props: P | null;
440
- /* Excluded from this release type: _batchingLock */
441
- /* Excluded from this release type: _pendingUpdates */
442
- /* Excluded from this release type: _consumerRefs */
443
- /* Excluded from this release type: _validateConsumers */
413
+ subscribe(callback: (state: S) => void): () => void;
444
414
  /**
445
- * Creates a new BlocBase instance with the given initial state.
446
- * Sets up the observer, registers with the Blac manager, and initializes addons.
447
- *
448
- * @param initialState The initial state value for this Bloc
415
+ * Subscribe with a selector for optimized updates
449
416
  */
450
- constructor(initialState: S);
417
+ subscribeWithSelector<T>(selector: (state: S) => T, callback: (value: T) => void, equalityFn?: (a: T, b: T) => boolean): () => void;
451
418
  /**
452
- * Returns the current state of the Bloc.
453
- * Use this getter to access the state in a read-only manner.
454
- * Returns the state even during transitional lifecycle states for React compatibility.
419
+ * Subscribe with React component reference for automatic cleanup
455
420
  */
456
- get state(): S;
421
+ subscribeComponent(componentRef: WeakRef<object>, callback: () => void): () => void;
422
+ /**
423
+ * Get current subscription count
424
+ */
425
+ get subscriptionCount(): number;
426
+ /**
427
+ * Track property access for a subscription
428
+ */
429
+ trackAccess(subscriptionId: string, path: string, value?: unknown): void;
430
+ /**
431
+ * Emit a new state
432
+ */
433
+ protected emit(newState: S, action?: unknown): void;
434
+ /**
435
+ * Internal state push method used by Bloc
436
+ */
437
+ _pushState(newState: S, oldState: S, action?: unknown): void;
438
+ _batchUpdates(callback: () => void): void;
457
439
  /**
458
- * Returns whether this Bloc instance has been disposed.
459
- * @returns true if the bloc is in DISPOSED state
440
+ * Add a plugin
441
+ */
442
+ addPlugin(plugin: BlocPlugin<S, any>): void;
443
+ /**
444
+ * Remove a plugin
445
+ */
446
+ removePlugin(plugin: BlocPlugin<S, any>): void;
447
+ /**
448
+ * Get all plugins
449
+ */
450
+ get plugins(): ReadonlyArray<BlocPlugin<S, any>>;
451
+ /**
452
+ * Disposal management
460
453
  */
461
454
  get isDisposed(): boolean;
462
- /* Excluded from this release type: _name */
463
- /* Excluded from this release type: _updateId */
464
- /* Excluded from this release type: _atomicStateTransition */
465
- /* Excluded from this release type: _dispose */
466
- /* Excluded from this release type: onDispose */
467
- /* Excluded from this release type: _consumers */
468
- /* Excluded from this release type: _addConsumer */
469
- /* Excluded from this release type: _removeConsumer */
470
- /* Excluded from this release type: _disposalHandler */
471
- /* Excluded from this release type: _setDisposalHandler */
472
- /* Excluded from this release type: _scheduleDisposal */
473
- lastUpdate: number;
474
- /* Excluded from this release type: _batchingEnabled */
475
- /* Excluded from this release type: _pushState */
476
455
  /**
477
- * Enables batching for multiple state updates
478
- * @param batchFn Function to execute with batching enabled
456
+ * Atomic state transition for disposal
457
+ */
458
+ _atomicStateTransition(expectedState: BlocLifecycleState, newState: BlocLifecycleState): StateTransitionResult;
459
+ /**
460
+ * Dispose the bloc and clean up resources
461
+ */
462
+ dispose(): Promise<void>;
463
+ /**
464
+ * Schedule disposal when no subscriptions remain
479
465
  */
480
- batch: <T>(batchFn: () => T) => T;
466
+ _scheduleDisposal(): void;
467
+ /**
468
+ * Set disposal handler
469
+ */
470
+ setDisposalHandler(handler: (bloc: BlocBase<unknown>) => void): void;
471
+ /**
472
+ * Check if disposal should be scheduled (called by subscription manager)
473
+ */
474
+ checkDisposal(): void;
475
+ /**
476
+ * Cancel disposal if bloc is in disposal_requested state
477
+ */
478
+ _cancelDisposalIfRequested(): void;
481
479
  }
482
480
 
483
481
  /**
484
482
  * Represents the abstract base types for Bloc and Cubit
485
483
  */
486
- export declare type BlocBaseAbstract = typeof Bloc<any, any, any> | typeof Cubit<any, any>;
484
+ export declare type BlocBaseAbstract = typeof Bloc<any, any> | typeof Cubit<any>;
487
485
 
488
486
  /**
489
487
  * Represents a constructor type for a Bloc that takes no parameters
@@ -500,11 +498,7 @@ export declare type BlocConstructor<B> = (new (...args: any) => B) & {
500
498
  keepAlive?: boolean;
501
499
  };
502
500
 
503
- /**
504
- * Extracts the constructor parameters type from a BlocBase
505
- * @template B - The BlocBase type to extract the constructor parameters from
506
- */
507
- export declare type BlocConstructorParameters<B extends BlocBase<any>> = BlocConstructor<B> extends new (...args: infer P) => B ? P : never;
501
+ export declare type BlocConstructorParams<B extends BlocConstructor<BlocBase<any>>> = ConstructorParameters<B>[0];
508
502
 
509
503
  /**
510
504
  * Error boundary interface for Bloc error handling
@@ -536,9 +530,45 @@ export declare type BlocHookDependencyArrayFn<S, I = any> = (currentState: S, pr
536
530
 
537
531
  export declare type BlocInstanceId = string | number | undefined;
538
532
 
533
+ /**
534
+ * Manages the lifecycle state transitions for Bloc instances.
535
+ * Ensures atomic state transitions to prevent race conditions during disposal.
536
+ */
537
+ export declare class BlocLifecycleManager {
538
+ private disposalState;
539
+ private disposalLock;
540
+ private disposalTimer?;
541
+ private disposalHandler?;
542
+ get currentState(): BlocLifecycleState;
543
+ get isDisposed(): boolean;
544
+ /**
545
+ * Atomic state transition for disposal
546
+ */
547
+ atomicStateTransition(expectedState: BlocLifecycleState, newState: BlocLifecycleState): StateTransitionResult;
548
+ /**
549
+ * Schedule disposal after a delay
550
+ */
551
+ scheduleDisposal(delay: number, canDispose: () => boolean, onDispose: () => void): void;
552
+ /**
553
+ * Cancel disposal if in disposal requested state
554
+ */
555
+ cancelDisposal(): boolean;
556
+ /**
557
+ * Set disposal handler
558
+ */
559
+ setDisposalHandler(handler: (bloc: unknown) => void): void;
560
+ /**
561
+ * Get disposal handler
562
+ */
563
+ getDisposalHandler(): ((bloc: unknown) => void) | undefined;
564
+ /**
565
+ * Clear disposal timer
566
+ */
567
+ clearDisposalTimer(): void;
568
+ }
569
+
539
570
  /**
540
571
  * Enum representing the lifecycle states of a Bloc instance
541
- * Used for atomic state transitions to prevent race conditions
542
572
  */
543
573
  export declare enum BlocLifecycleState {
544
574
  ACTIVE = "active",
@@ -547,6 +577,76 @@ export declare enum BlocLifecycleState {
547
577
  DISPOSED = "disposed"
548
578
  }
549
579
 
580
+ /**
581
+ * Bloc-specific plugin that can transform behavior
582
+ */
583
+ export declare interface BlocPlugin<TState = any, TEvent = never> extends Plugin_2 {
584
+ transformState?(previousState: TState, nextState: TState): TState;
585
+ transformEvent?(event: TEvent): TEvent | null;
586
+ onAttach?(bloc: BlocBase<TState>): void;
587
+ onDetach?(): void;
588
+ onStateChange?(previousState: TState, currentState: TState): void;
589
+ onEvent?(event: TEvent): void;
590
+ onError?(error: Error, context: ErrorContext): void;
591
+ }
592
+
593
+ /**
594
+ * Registry for bloc-specific plugins
595
+ */
596
+ export declare class BlocPluginRegistry<TState, TEvent = never> implements PluginRegistry<BlocPlugin<TState, TEvent>> {
597
+ private plugins;
598
+ private executionOrder;
599
+ private attached;
600
+ /**
601
+ * Add a bloc plugin
602
+ */
603
+ add(plugin: BlocPlugin<TState, TEvent>): void;
604
+ /**
605
+ * Remove a bloc plugin
606
+ */
607
+ remove(pluginName: string): boolean;
608
+ /**
609
+ * Get a plugin by name
610
+ */
611
+ get(pluginName: string): BlocPlugin<TState, TEvent> | undefined;
612
+ /**
613
+ * Get all plugins in execution order
614
+ */
615
+ getAll(): ReadonlyArray<BlocPlugin<TState, TEvent>>;
616
+ /**
617
+ * Clear all plugins
618
+ */
619
+ clear(): void;
620
+ /**
621
+ * Attach all plugins to a bloc
622
+ */
623
+ attach(bloc: any): void;
624
+ /**
625
+ * Transform state through all plugins
626
+ */
627
+ transformState(previousState: TState, nextState: TState): TState;
628
+ /**
629
+ * Transform event through all plugins
630
+ */
631
+ transformEvent(event: TEvent): TEvent | null;
632
+ /**
633
+ * Notify plugins of state change
634
+ */
635
+ notifyStateChange(previousState: TState, currentState: TState): void;
636
+ /**
637
+ * Notify plugins of event
638
+ */
639
+ notifyEvent(event: TEvent): void;
640
+ /**
641
+ * Notify plugins of error
642
+ */
643
+ notifyError(error: Error, context: ErrorContext): void;
644
+ private validateCapabilities;
645
+ private canReadState;
646
+ private canTransformState;
647
+ private canInterceptEvents;
648
+ }
649
+
550
650
  /**
551
651
  * Extracts the state type from either a Bloc or Cubit
552
652
  * @template T - The Bloc or Cubit type to extract the state from
@@ -580,61 +680,26 @@ export declare class BlocTest {
580
680
  static expectStates<T extends BlocBase<S>, S>(bloc: T, expectedStates: S[], timeout?: number): Promise<void>;
581
681
  }
582
682
 
583
- export declare interface ConsumerInfo {
584
- id: string;
585
- lastNotified: number;
586
- hasRendered: boolean;
587
- stateAccesses: Set<string>;
588
- classAccesses: Set<string>;
589
- stateValues: Map<string, TrackedValue>;
590
- classValues: Map<string, TrackedValue>;
591
- accessCount: number;
592
- lastAccessTime: number;
593
- firstAccessTime: number;
594
- }
595
-
596
- /**
597
- * ConsumerTracker manages both consumer registration and dependency tracking.
598
- * It uses a WeakMap for automatic garbage collection when consumers are no longer referenced.
599
- */
600
- export declare class ConsumerTracker {
601
- private consumers;
602
- private registrationCount;
603
- private activeConsumers;
604
- register(consumerRef: object, consumerId: string): void;
605
- unregister(consumerRef: object): void;
606
- trackAccess(consumerRef: object, type: 'state' | 'class', path: string, value?: any): void;
607
- resetTracking(consumerRef: object): void;
608
- getDependencies(consumerRef: object): DependencyArray | null;
609
- hasValuesChanged(consumerRef: object, newState: any, newBlocInstance: any): boolean;
610
- shouldNotifyConsumer(consumerRef: object, changedPaths: Set<string>): boolean;
611
- updateLastNotified(consumerRef: object): void;
612
- getConsumerInfo(consumerRef: object): ConsumerInfo | undefined;
613
- setHasRendered(consumerRef: object, hasRendered: boolean): void;
614
- hasConsumer(consumerRef: object): boolean;
615
- getStats(): {
616
- totalRegistrations: number;
617
- activeConsumers: number;
618
- };
619
- private getValueAtPath;
620
- }
621
-
622
- declare interface ConsumerTracker_2 {
683
+ declare interface ConsumerTracker {
623
684
  trackAccess: (consumerRef: object, type: 'state' | 'class', path: string, value?: any) => void;
624
685
  }
625
686
 
687
+ /**
688
+ * Creates a proxy for bloc instances that tracks getter access
689
+ */
690
+ export declare const createBlocProxy: <T extends object>(target: T, consumerRef: object, consumerTracker: ConsumerTracker) => T;
691
+
692
+ /**
693
+ * Creates a proxy for state objects that tracks property access
694
+ */
695
+ export declare const createStateProxy: <T extends object>(target: T, consumerRef: object, consumerTracker: ConsumerTracker, path?: string) => T;
696
+
626
697
  /**
627
698
  * A Cubit is a simpler version of a Bloc that doesn't handle events.
628
699
  * It manages state and provides methods to update it.
629
700
  * @template S - The type of state this Cubit manages
630
- * @template P - The type of parameters (optional, defaults to null)
631
701
  */
632
- export declare abstract class Cubit<S, P = null> extends BlocBase<S, P> {
633
- /* Excluded from this release type: _updateProps */
634
- /**
635
- * Optional override for props handling
636
- */
637
- protected onPropsChanged?(oldProps: P | undefined, newProps: P): void;
702
+ export declare abstract class Cubit<S> extends BlocBase<S> {
638
703
  /**
639
704
  * Updates the current state and notifies all observers of the change.
640
705
  * If the new state is identical to the current state (using Object.is),
@@ -653,12 +718,89 @@ export declare abstract class Cubit<S, P = null> extends BlocBase<S, P> {
653
718
  patch(statePatch: S extends object ? Partial<S> : S, ignoreChangeCheck?: boolean): void;
654
719
  }
655
720
 
656
- export declare interface DependencyArray {
657
- statePaths: string[];
658
- classPaths: string[];
721
+ export declare const DefaultErrorStrategy: ErrorHandlingStrategy;
722
+
723
+ export declare enum ErrorCategory {
724
+ LIFECYCLE = "LIFECYCLE",
725
+ STATE = "STATE",
726
+ PLUGIN = "PLUGIN",
727
+ VALIDATION = "VALIDATION",
728
+ DISPOSAL = "DISPOSAL",
729
+ CONSUMER = "CONSUMER"
730
+ }
731
+
732
+ /**
733
+ * Error context provided to error handlers
734
+ */
735
+ export declare interface ErrorContext {
736
+ readonly phase: 'initialization' | 'state-change' | 'event-processing' | 'disposal';
737
+ readonly operation: string;
738
+ readonly metadata?: Record<string, unknown>;
659
739
  }
660
740
 
661
- declare type DependencySelector<S> = (currentState: S, previousState: S | undefined, instance: any) => unknown[];
741
+ export declare type ErrorHandler = (error: BlacError) => void;
742
+
743
+ export declare type ErrorHandlingStrategy = {
744
+ shouldPropagate: (error: BlacError) => boolean;
745
+ shouldLog: (error: BlacError) => boolean;
746
+ handle: (error: BlacError) => void;
747
+ };
748
+
749
+ /**
750
+ * Centralized error management system for BlaC framework.
751
+ * Handles error processing, logging, and propagation strategies.
752
+ */
753
+ export declare class ErrorManager {
754
+ private static instance;
755
+ private handlers;
756
+ private strategy;
757
+ /**
758
+ * Get the singleton instance of ErrorManager
759
+ */
760
+ static getInstance(): ErrorManager;
761
+ /**
762
+ * Set a custom error handling strategy
763
+ */
764
+ setStrategy(strategy: ErrorHandlingStrategy): void;
765
+ /**
766
+ * Add a custom error handler that will be called for all errors
767
+ */
768
+ addHandler(handler: ErrorHandler): void;
769
+ /**
770
+ * Remove a previously added error handler
771
+ */
772
+ removeHandler(handler: ErrorHandler): void;
773
+ /**
774
+ * Process an error through all handlers and apply the configured strategy
775
+ */
776
+ handle(error: BlacError): void;
777
+ /**
778
+ * Convenience method for wrapping operations with error handling
779
+ */
780
+ wrap<T>(operation: () => T, errorFactory: (error: unknown) => BlacError): T;
781
+ /**
782
+ * Async version of wrap
783
+ */
784
+ wrapAsync<T>(operation: () => Promise<T>, errorFactory: (error: unknown) => BlacError): Promise<T>;
785
+ }
786
+
787
+ export declare enum ErrorSeverity {
788
+ FATAL = "FATAL",// System cannot continue
789
+ ERROR = "ERROR",// Operation failed but system continues
790
+ WARNING = "WARNING",// Potential issue but operation succeeded
791
+ INFO = "INFO"
792
+ }
793
+
794
+ /**
795
+ * Generates a deterministic instance ID from static props by extracting primitive values
796
+ *
797
+ * Rules:
798
+ * 1. Only considers primitive types: string, number, boolean, null, undefined
799
+ * 2. Ignores complex types: objects, arrays, functions, symbols
800
+ * 3. Sorts keys alphabetically for deterministic output
801
+ * 4. Returns undefined if no primitives found (caller should use default ID)
802
+ */
803
+ export declare function generateInstanceIdFromProps(props: unknown): string | undefined;
662
804
 
663
805
  /**
664
806
  * Cross-platform UUID v4 generator that works in all environments including React Native/Hermes
@@ -673,7 +815,7 @@ export declare function generateUUID(): string;
673
815
  export declare interface GetBlocOptions<B extends BlocBase<unknown>> {
674
816
  id?: string;
675
817
  selector?: BlocHookDependencyArrayFn<BlocState<B>>;
676
- props?: InferPropsFromGeneric<B>;
818
+ constructorParams?: ConstructorParameters<BlocConstructor<B>>[];
677
819
  onMount?: (bloc: B) => void;
678
820
  instanceRef?: string;
679
821
  throwIfNotFound?: boolean;
@@ -682,10 +824,27 @@ export declare interface GetBlocOptions<B extends BlocBase<unknown>> {
682
824
  }
683
825
 
684
826
  /**
685
- * Extracts the props type from either a Bloc or Cubit
686
- * @template T - The Bloc or Cubit type to extract the props from
827
+ * Standard error handling helper for BlaC
828
+ *
829
+ * Usage:
830
+ * - For fatal errors that should propagate: handleError.fatal(...)
831
+ * - For recoverable errors: handleError.error(...)
832
+ * - For warnings: handleError.warn(...)
687
833
  */
688
- export declare type InferPropsFromGeneric<T> = T extends Bloc<any, any, infer P> ? P : T extends Cubit<any, infer P> ? P : never;
834
+ export declare const handleError: {
835
+ fatal: (message: string, category: ErrorCategory, context?: BlacErrorContext, cause?: unknown) => never;
836
+ error: (message: string, category: ErrorCategory, context?: BlacErrorContext, cause?: unknown) => void;
837
+ warn: (message: string, category: ErrorCategory, context?: BlacErrorContext, cause?: unknown) => void;
838
+ info: (message: string, category: ErrorCategory, context?: BlacErrorContext) => void;
839
+ /**
840
+ * Wraps a function to catch and handle errors
841
+ */
842
+ wrap: <T>(fn: () => T, category: ErrorCategory, context?: BlacErrorContext, severity?: ErrorSeverity) => T | undefined;
843
+ /**
844
+ * Wraps an async function to catch and handle errors
845
+ */
846
+ wrapAsync: <T>(fn: () => Promise<T>, category: ErrorCategory, context?: BlacErrorContext, severity?: ErrorSeverity) => Promise<T | undefined>;
847
+ };
689
848
 
690
849
  /**
691
850
  * Memory leak detector for tests
@@ -743,35 +902,96 @@ export declare class MockCubit<S> extends Cubit<S> {
743
902
  clearStateHistory(): void;
744
903
  }
745
904
 
905
+ /**
906
+ * Base interface for all plugins
907
+ */
908
+ declare interface Plugin_2 {
909
+ readonly name: string;
910
+ readonly version: string;
911
+ readonly capabilities?: PluginCapabilities;
912
+ }
913
+ export { Plugin_2 as Plugin }
914
+
915
+ /**
916
+ * Plugin capabilities for security model
917
+ */
918
+ export declare interface PluginCapabilities {
919
+ readonly readState: boolean;
920
+ readonly transformState: boolean;
921
+ readonly interceptEvents: boolean;
922
+ readonly persistData: boolean;
923
+ readonly accessMetadata: boolean;
924
+ }
925
+
926
+ /**
927
+ * Plugin execution context for performance monitoring
928
+ */
929
+ export declare interface PluginExecutionContext {
930
+ readonly pluginName: string;
931
+ readonly hookName: string;
932
+ readonly startTime: number;
933
+ readonly blocName?: string;
934
+ readonly blocId?: string;
935
+ }
936
+
937
+ /**
938
+ * Plugin metrics for monitoring
939
+ */
940
+ export declare interface PluginMetrics {
941
+ readonly executionTime: number;
942
+ readonly executionCount: number;
943
+ readonly errorCount: number;
944
+ readonly lastError?: Error;
945
+ readonly lastExecutionTime?: number;
946
+ }
947
+
948
+ /**
949
+ * Plugin registry interface
950
+ */
951
+ export declare interface PluginRegistry<T extends Plugin_2> {
952
+ add(plugin: T): void;
953
+ remove(pluginName: string): boolean;
954
+ get(pluginName: string): T | undefined;
955
+ getAll(): ReadonlyArray<T>;
956
+ clear(): void;
957
+ }
958
+
959
+ /**
960
+ * Event fired when props are updated on a Bloc or Cubit instance.
961
+ * This is primarily used internally by the framework to notify
962
+ * about prop changes in React components.
963
+ * @template P - The type of props being updated
964
+ */
746
965
  export declare class PropsUpdated<P = any> {
747
966
  readonly props: P;
748
967
  constructor(props: P);
749
968
  }
750
969
 
751
- export declare class ProxyFactory {
752
- static createStateProxy<T extends object>(options: {
753
- target: T;
970
+ export declare const ProxyFactory: {
971
+ createStateProxy: (options: {
972
+ target: any;
754
973
  consumerRef: object;
755
- consumerTracker: ConsumerTracker_2;
974
+ consumerTracker: ConsumerTracker;
756
975
  path?: string;
757
- }): T;
758
- static createClassProxy<T extends object>(options: {
759
- target: T;
976
+ }) => any;
977
+ createClassProxy: (options: {
978
+ target: any;
760
979
  consumerRef: object;
761
- consumerTracker: ConsumerTracker_2;
762
- }): T;
763
- static getProxyState<B extends BlocBase<any>>(options: {
764
- state: BlocState<B>;
980
+ consumerTracker: ConsumerTracker;
981
+ }) => any;
982
+ getProxyState: <B extends BlocBase<any>>(options: {
983
+ state: any;
765
984
  consumerRef: object;
766
- consumerTracker: ConsumerTracker_2;
767
- }): BlocState<B>;
768
- static getProxyBlocInstance<B extends BlocBase<any>>(options: {
985
+ consumerTracker: ConsumerTracker;
986
+ }) => any;
987
+ getProxyBlocInstance: <B extends BlocBase<any>>(options: {
769
988
  blocInstance: B;
770
989
  consumerRef: object;
771
- consumerTracker: ConsumerTracker_2;
772
- }): B;
773
- static getStats(): {
774
- totalProxies: number;
990
+ consumerTracker: ConsumerTracker;
991
+ }) => B;
992
+ getStats: () => {
993
+ propertyAccesses: number;
994
+ nestedProxiesCreated: number;
775
995
  cacheEfficiency: string;
776
996
  lifetime: string;
777
997
  proxiesPerSecond: string;
@@ -779,12 +999,71 @@ export declare class ProxyFactory {
779
999
  classProxiesCreated: number;
780
1000
  cacheHits: number;
781
1001
  cacheMisses: number;
782
- propertyAccesses: number;
783
- nestedProxiesCreated: number;
784
1002
  totalProxiesCreated: number;
785
- createdAt: number;
786
1003
  };
787
- static resetStats(): void;
1004
+ resetStats: () => void;
1005
+ };
1006
+
1007
+ export declare interface RerenderInfo {
1008
+ componentName: string;
1009
+ blocName: string;
1010
+ blocId: string;
1011
+ renderCount: number;
1012
+ reason: RerenderReason;
1013
+ timestamp: number;
1014
+ duration?: number;
1015
+ stackTrace?: string;
1016
+ }
1017
+
1018
+ /**
1019
+ * Utility class for logging component rerenders with detailed debugging information
1020
+ */
1021
+ export declare class RerenderLogger {
1022
+ private static componentRenderCounts;
1023
+ private static lastRenderTimestamps;
1024
+ private static groupedLogs;
1025
+ private static groupTimeouts;
1026
+ /**
1027
+ * Log a component rerender with detailed information
1028
+ */
1029
+ static logRerender(info: RerenderInfo): void;
1030
+ /**
1031
+ * Parse the logging configuration
1032
+ */
1033
+ private static parseConfig;
1034
+ /**
1035
+ * Log immediately without grouping
1036
+ */
1037
+ private static logImmediate;
1038
+ /**
1039
+ * Log with grouping (batch multiple rerenders)
1040
+ */
1041
+ private static logGrouped;
1042
+ /**
1043
+ * Format the log message based on level
1044
+ */
1045
+ private static formatMessage;
1046
+ /**
1047
+ * Get emoji for reason type
1048
+ */
1049
+ private static getReasonEmoji;
1050
+ /**
1051
+ * Clear all tracking data
1052
+ */
1053
+ static clear(): void;
1054
+ /**
1055
+ * Get render count for a component
1056
+ */
1057
+ static getRenderCount(componentName: string, blocId: string): number;
1058
+ }
1059
+
1060
+ export declare interface RerenderReason {
1061
+ type: 'state-change' | 'dependency-change' | 'mount' | 'props-change' | 'unknown';
1062
+ changedPaths?: string[];
1063
+ oldValues?: Record<string, any>;
1064
+ newValues?: Record<string, any>;
1065
+ dependencies?: string[];
1066
+ description?: string;
788
1067
  }
789
1068
 
790
1069
  /**
@@ -801,18 +1080,218 @@ export declare function setBlacInstanceManager(manager: BlacInstanceManager): vo
801
1080
  */
802
1081
  export declare function shallowEqual(a: any, b: any): boolean;
803
1082
 
804
- /**
805
- * Result of an atomic state transition operation
806
- */
807
1083
  export declare interface StateTransitionResult {
808
1084
  success: boolean;
809
1085
  currentState: BlocLifecycleState;
810
1086
  previousState: BlocLifecycleState;
811
1087
  }
812
1088
 
813
- export declare interface TrackedValue {
814
- value: any;
815
- lastAccessTime: number;
1089
+ /**
1090
+ * Unified subscription interface that replaces the dual consumer/observer system
1091
+ */
1092
+ export declare interface Subscription<S = unknown> {
1093
+ /** Unique identifier for the subscription */
1094
+ id: string;
1095
+ /** Type of subscription for backward compatibility */
1096
+ type: 'consumer' | 'observer';
1097
+ /** Optional selector function to derive values from state */
1098
+ selector?: (state: S, bloc?: BlocBase<S>) => unknown;
1099
+ /** Custom equality function for selector results (defaults to Object.is) */
1100
+ equalityFn?: (prev: unknown, next: unknown) => boolean;
1101
+ /** Notification callback when state changes */
1102
+ notify: (value: unknown, oldValue?: unknown, action?: unknown) => void;
1103
+ /** Priority for notification order (higher = earlier) */
1104
+ priority?: number;
1105
+ /** WeakRef to the subscriber for automatic cleanup (React components) */
1106
+ weakRef?: WeakRef<object>;
1107
+ /** Last computed selector value for comparison */
1108
+ lastValue?: unknown;
1109
+ /** Tracked state path dependencies */
1110
+ dependencies?: Set<string>;
1111
+ /** Metadata for tracking and debugging */
1112
+ metadata?: SubscriptionMetadata;
1113
+ }
1114
+
1115
+ /**
1116
+ * Unified subscription manager that replaces the dual consumer/observer system.
1117
+ * Handles all state change subscriptions with a single, consistent interface.
1118
+ */
1119
+ export declare class SubscriptionManager<S = unknown> {
1120
+ private bloc;
1121
+ private subscriptions;
1122
+ private pathToSubscriptions;
1123
+ private weakRefCleanupScheduled;
1124
+ private totalNotifications;
1125
+ constructor(bloc: BlocBase<S>);
1126
+ /**
1127
+ * Subscribe to state changes
1128
+ */
1129
+ subscribe(options: SubscriptionOptions<S>): () => void;
1130
+ /**
1131
+ * Unsubscribe by ID
1132
+ */
1133
+ unsubscribe(id: string): void;
1134
+ /**
1135
+ * Notify all subscriptions of state change
1136
+ */
1137
+ notify(newState: S, oldState: S, action?: unknown): void;
1138
+ /**
1139
+ * Track a path access for a subscription
1140
+ */
1141
+ trackAccess(subscriptionId: string, path: string, value?: unknown): void;
1142
+ /**
1143
+ * Get the paths that changed between two states
1144
+ */
1145
+ private getChangedPaths;
1146
+ /**
1147
+ * Check if a subscription should be notified based on changed paths
1148
+ */
1149
+ shouldNotifyForPaths(subscriptionId: string, changedPaths: Set<string>): boolean;
1150
+ /**
1151
+ * Get statistics about subscriptions
1152
+ */
1153
+ getStats(): SubscriptionManagerStats;
1154
+ /**
1155
+ * Clear all subscriptions
1156
+ */
1157
+ clear(): void;
1158
+ /**
1159
+ * Get subscription by ID
1160
+ */
1161
+ getSubscription(id: string): Subscription<S> | undefined;
1162
+ /**
1163
+ * Check if there are any active subscriptions
1164
+ */
1165
+ get hasSubscriptions(): boolean;
1166
+ /**
1167
+ * Get count of active subscriptions
1168
+ */
1169
+ get size(): number;
1170
+ /**
1171
+ * Clean up subscriptions with dead weak references
1172
+ */
1173
+ private cleanupDeadReferences;
1174
+ /**
1175
+ * Schedule weak reference cleanup for next tick
1176
+ */
1177
+ private scheduleWeakRefCleanup;
1178
+ }
1179
+
1180
+ export declare interface SubscriptionManagerStats {
1181
+ /** Total number of active subscriptions */
1182
+ activeSubscriptions: number;
1183
+ /** Number of consumer subscriptions */
1184
+ consumerCount: number;
1185
+ /** Number of observer subscriptions */
1186
+ observerCount: number;
1187
+ /** Total notifications sent */
1188
+ totalNotifications: number;
1189
+ /** Number of tracked dependencies */
1190
+ trackedDependencies: number;
1191
+ }
1192
+
1193
+ export declare interface SubscriptionMetadata {
1194
+ /** Timestamp of last notification */
1195
+ lastNotified?: number;
1196
+ /** Whether the subscriber has rendered (React-specific) */
1197
+ hasRendered?: boolean;
1198
+ /** Number of times this subscription accessed state */
1199
+ accessCount?: number;
1200
+ /** First access timestamp */
1201
+ firstAccessTime?: number;
1202
+ /** Last access timestamp */
1203
+ lastAccessTime?: number;
1204
+ }
1205
+
1206
+ export declare interface SubscriptionOptions<S> {
1207
+ /** Type of subscription */
1208
+ type: 'consumer' | 'observer';
1209
+ /** Optional selector function */
1210
+ selector?: (state: S, bloc?: BlocBase<S>) => unknown;
1211
+ /** Custom equality function */
1212
+ equalityFn?: (prev: unknown, next: unknown) => boolean;
1213
+ /** Notification callback */
1214
+ notify: (value: unknown, oldValue?: unknown, action?: unknown) => void;
1215
+ /** Priority for notifications */
1216
+ priority?: number;
1217
+ /** WeakRef to subscriber */
1218
+ weakRef?: WeakRef<object>;
1219
+ }
1220
+
1221
+ /**
1222
+ * Registry for system-wide plugins
1223
+ */
1224
+ export declare class SystemPluginRegistry implements PluginRegistry<BlacPlugin> {
1225
+ private plugins;
1226
+ private metrics;
1227
+ private executionOrder;
1228
+ /**
1229
+ * Add a system plugin
1230
+ */
1231
+ add(plugin: BlacPlugin): void;
1232
+ /**
1233
+ * Remove a system plugin
1234
+ */
1235
+ remove(pluginName: string): boolean;
1236
+ /**
1237
+ * Get a plugin by name
1238
+ */
1239
+ get(pluginName: string): BlacPlugin | undefined;
1240
+ /**
1241
+ * Get all plugins in execution order
1242
+ */
1243
+ getAll(): ReadonlyArray<BlacPlugin>;
1244
+ /**
1245
+ * Clear all plugins
1246
+ */
1247
+ clear(): void;
1248
+ /**
1249
+ * Execute a hook on all plugins
1250
+ */
1251
+ executeHook(hookName: keyof BlacPlugin, args: unknown[], errorHandler?: (error: Error, plugin: BlacPlugin) => void): void;
1252
+ /**
1253
+ * Bootstrap all plugins
1254
+ */
1255
+ bootstrap(): void;
1256
+ /**
1257
+ * Shutdown all plugins
1258
+ */
1259
+ shutdown(): void;
1260
+ /**
1261
+ * Notify plugins of bloc creation
1262
+ */
1263
+ notifyBlocCreated(bloc: BlocBase<any>): void;
1264
+ /**
1265
+ * Notify plugins of bloc disposal
1266
+ */
1267
+ notifyBlocDisposed(bloc: BlocBase<any>): void;
1268
+ /**
1269
+ * Notify plugins of state change
1270
+ */
1271
+ notifyStateChanged(bloc: BlocBase<any>, previousState: any, currentState: any): void;
1272
+ /**
1273
+ * Notify plugins of event addition
1274
+ */
1275
+ notifyEventAdded(bloc: Bloc<any, any>, event: any): void;
1276
+ /**
1277
+ * Notify plugins of errors
1278
+ */
1279
+ notifyError(error: Error, bloc: BlocBase<unknown>, context: ErrorContext): void;
1280
+ /**
1281
+ * Notify plugins of adapter lifecycle events
1282
+ */
1283
+ notifyAdapterCreated(adapter: any, metadata: AdapterMetadata): void;
1284
+ notifyAdapterMount(adapter: any, metadata: AdapterMetadata): void;
1285
+ notifyAdapterUnmount(adapter: any, metadata: AdapterMetadata): void;
1286
+ notifyAdapterRender(adapter: any, metadata: AdapterMetadata): void;
1287
+ notifyAdapterDisposed(adapter: any, metadata: AdapterMetadata): void;
1288
+ /**
1289
+ * Get metrics for a plugin
1290
+ */
1291
+ getMetrics(pluginName: string): Map<string, PluginMetrics> | undefined;
1292
+ private initializeMetrics;
1293
+ private recordSuccess;
1294
+ private recordError;
816
1295
  }
817
1296
 
818
1297
  /**