@blac/core
Advanced tools
| export type BlacOptions = { | ||
| isolated: true; | ||
| } | { | ||
| keepAlive: true; | ||
| } | { | ||
| excludeFromDevTools: true; | ||
| }; | ||
| /** | ||
| * Decorator to configure StateContainer classes. | ||
| * | ||
| * @example Decorator syntax (requires experimentalDecorators or TC39 decorators) | ||
| * ```typescript | ||
| * @blac({ isolated: true }) | ||
| * class FormBloc extends Cubit<FormState> {} | ||
| * | ||
| * @blac({ keepAlive: true }) | ||
| * class AuthBloc extends Cubit<AuthState> {} | ||
| * | ||
| * @blac({ excludeFromDevTools: true }) | ||
| * class InternalBloc extends Cubit<InternalState> {} | ||
| * ``` | ||
| * | ||
| * @example Function syntax (no decorator support needed) | ||
| * ```typescript | ||
| * const FormBloc = blac({ isolated: true })( | ||
| * class extends Cubit<FormState> {} | ||
| * ); | ||
| * ``` | ||
| */ | ||
| export declare function blac(options: BlacOptions): <T extends new (...args: any[]) => any>(target: T, _context?: ClassDecoratorContext) => T; | ||
| //# sourceMappingURL=blac.d.ts.map |
| export { blac, type BlacOptions } from './blac'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,114 +0,33 @@ | ||
| /** | ||
| * Framework Adapter - Reusable logic for integrating BlaC with any reactive framework | ||
| * | ||
| * This module provides framework-agnostic utilities for: | ||
| * - Subscription management (auto-tracking, manual deps, no-tracking modes) | ||
| * - Snapshot generation (state proxies with tracking) | ||
| * - External dependency management (cross-bloc subscriptions) | ||
| * - Change detection (state and getter tracking) | ||
| * | ||
| * Can be used to integrate BlaC with React, Vue, Solid, Svelte, Angular, etc. | ||
| */ | ||
| import type { StateContainer } from '../core/StateContainer'; | ||
| import type { TrackerState, GetterTrackerState } from '../tracking'; | ||
| import type { ExtractState } from '../types/utilities'; | ||
| /** | ||
| * Framework-agnostic adapter state | ||
| * Frameworks should store this in their component state mechanism | ||
| */ | ||
| export interface AdapterState<TBloc extends StateContainer<any>> { | ||
| /** State property tracker */ | ||
| export interface AdapterState<TBloc extends StateContainer<any, any>> { | ||
| tracker: TrackerState<ExtractState<TBloc>> | null; | ||
| /** Manual dependencies cache */ | ||
| manualDepsCache: unknown[] | null; | ||
| /** Getter tracking state */ | ||
| getterTracker: GetterTrackerState | null; | ||
| /** Cached proxied bloc instance */ | ||
| proxiedBloc: TBloc | null; | ||
| } | ||
| /** | ||
| * Configuration for manual dependencies mode | ||
| */ | ||
| export interface ManualDepsConfig<TBloc extends StateContainer<any>> { | ||
| export interface ManualDepsConfig<TBloc extends StateContainer<any, any>> { | ||
| dependencies: (state: any, bloc: TBloc) => unknown[]; | ||
| } | ||
| /** | ||
| * Subscription callback type | ||
| * Called when the framework should re-render | ||
| */ | ||
| export type SubscriptionCallback = () => void; | ||
| /** | ||
| * Subscription function type | ||
| * Returns an unsubscribe function | ||
| */ | ||
| export type SubscribeFunction = (callback: SubscriptionCallback) => () => void; | ||
| /** | ||
| * Snapshot function type | ||
| * Returns the current state (possibly proxied) | ||
| */ | ||
| export type SnapshotFunction<TState> = () => TState; | ||
| /** | ||
| * External dependency manager | ||
| * Handles subscriptions to external blocs accessed in getters | ||
| */ | ||
| export declare class ExternalDependencyManager { | ||
| private subscriptions; | ||
| private previousDeps; | ||
| /** | ||
| * Check if dependencies have changed | ||
| */ | ||
| private areDependenciesEqual; | ||
| /** | ||
| * Update external subscriptions | ||
| * @param getterTracker - The getter tracker state | ||
| * @param rawInstance - The raw bloc instance (exclude from subscriptions) | ||
| * @param onGetterChange - Callback when external getter changes | ||
| * @returns Whether subscriptions were updated | ||
| */ | ||
| updateSubscriptions(getterTracker: GetterTrackerState | null, rawInstance: StateContainer<any>, onGetterChange: () => void): boolean; | ||
| /** | ||
| * Cleanup all subscriptions | ||
| */ | ||
| updateSubscriptions(getterTracker: GetterTrackerState | null, rawInstance: StateContainer<any, any>, onGetterChange: () => void): boolean; | ||
| cleanup(): void; | ||
| } | ||
| /** | ||
| * Create a subscription function for auto-tracking mode | ||
| */ | ||
| export declare function createAutoTrackSubscribe<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SubscribeFunction; | ||
| /** | ||
| * Create a subscription function for manual dependencies mode | ||
| */ | ||
| export declare function createManualDepsSubscribe<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SubscribeFunction; | ||
| /** | ||
| * Create a subscription function for no-tracking mode | ||
| */ | ||
| export declare function createNoTrackSubscribe<TBloc extends StateContainer<any>>(instance: TBloc): SubscribeFunction; | ||
| /** | ||
| * Create a snapshot function for auto-tracking mode | ||
| */ | ||
| export declare function createAutoTrackSnapshot<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SnapshotFunction<ExtractState<TBloc>>; | ||
| /** | ||
| * Create a snapshot function for manual dependencies mode | ||
| */ | ||
| export declare function createManualDepsSnapshot<TBloc extends StateContainer<any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SnapshotFunction<ExtractState<TBloc>>; | ||
| /** | ||
| * Create a snapshot function for no-tracking mode | ||
| */ | ||
| export declare function createNoTrackSnapshot<TBloc extends StateContainer<any>>(instance: TBloc): SnapshotFunction<ExtractState<TBloc>>; | ||
| /** | ||
| * Initialize adapter state for auto-tracking mode | ||
| */ | ||
| export declare function initAutoTrackState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>; | ||
| /** | ||
| * Initialize adapter state for manual dependencies mode | ||
| */ | ||
| export declare function initManualDepsState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>; | ||
| /** | ||
| * Initialize adapter state for no-tracking mode | ||
| */ | ||
| export declare function initNoTrackState<TBloc extends StateContainer<any>>(instance: TBloc): AdapterState<TBloc>; | ||
| /** | ||
| * Disable getter tracking (call after render completes) | ||
| */ | ||
| export declare function disableGetterTracking<TBloc extends StateContainer<any>>(adapterState: AdapterState<TBloc>, rawInstance: TBloc): void; | ||
| export declare function createAutoTrackSubscribe<TBloc extends StateContainer<any, any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SubscribeFunction; | ||
| export declare function createManualDepsSubscribe<TBloc extends StateContainer<any, any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SubscribeFunction; | ||
| export declare function createNoTrackSubscribe<TBloc extends StateContainer<any, any>>(instance: TBloc): SubscribeFunction; | ||
| export declare function createAutoTrackSnapshot<TBloc extends StateContainer<any, any>>(instance: TBloc, adapterState: AdapterState<TBloc>): SnapshotFunction<ExtractState<TBloc>>; | ||
| export declare function createManualDepsSnapshot<TBloc extends StateContainer<any, any>>(instance: TBloc, adapterState: AdapterState<TBloc>, config: ManualDepsConfig<TBloc>): SnapshotFunction<ExtractState<TBloc>>; | ||
| export declare function createNoTrackSnapshot<TBloc extends StateContainer<any, any>>(instance: TBloc): SnapshotFunction<ExtractState<TBloc>>; | ||
| export declare function initAutoTrackState<TBloc extends StateContainer<any, any>>(instance: TBloc): AdapterState<TBloc>; | ||
| export declare function initManualDepsState<TBloc extends StateContainer<any, any>>(instance: TBloc): AdapterState<TBloc>; | ||
| export declare function initNoTrackState<TBloc extends StateContainer<any, any>>(instance: TBloc): AdapterState<TBloc>; | ||
| export declare function disableGetterTracking<TBloc extends StateContainer<any, any>>(adapterState: AdapterState<TBloc>, rawInstance: TBloc): void; | ||
| //# sourceMappingURL=framework-adapter.d.ts.map |
+1
-43
@@ -1,47 +0,8 @@ | ||
| /** | ||
| * Cubit - Simple state container with direct state emission | ||
| * | ||
| * This validates that our StateContainer design can support | ||
| * the simple Cubit pattern from the original BlaC. | ||
| */ | ||
| import { StateContainer } from './StateContainer'; | ||
| /** | ||
| * Cubit is a simple state container that allows direct state emission | ||
| * | ||
| * Unlike StateContainer (where emit is protected), Cubit exposes emit and update | ||
| * as public methods to allow direct state management. | ||
| */ | ||
| export declare abstract class Cubit<S> extends StateContainer<S> { | ||
| /** | ||
| * Create a new Cubit | ||
| * @param initialState Initial state value | ||
| */ | ||
| export declare abstract class Cubit<S, P = undefined> extends StateContainer<S, P> { | ||
| constructor(initialState: S); | ||
| /** | ||
| * Emit a new state (public override of protected parent method) | ||
| */ | ||
| emit(newState: S): void; | ||
| /** | ||
| * Update state using a function (public override of protected parent method) | ||
| */ | ||
| update(updater: (current: S) => S): void; | ||
| /** | ||
| * Patch state with partial updates (shallow merge) | ||
| * Only available when state is an object type | ||
| * Arrow function to maintain correct 'this' binding in React | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Update single field | ||
| * this.patch({ count: 5 }); | ||
| * | ||
| * // Update multiple fields | ||
| * this.patch({ count: 5, name: 'Updated' }); | ||
| * ``` | ||
| */ | ||
| patch: S extends object ? (partial: Partial<S>) => void : never; | ||
| } | ||
| /** | ||
| * Example: Counter Cubit | ||
| */ | ||
| export declare class CounterCubit extends Cubit<number> { | ||
@@ -54,5 +15,2 @@ constructor(); | ||
| } | ||
| /** | ||
| * Example: Complex State Cubit | ||
| */ | ||
| export interface TodoState { | ||
@@ -59,0 +17,0 @@ todos: Array<{ |
@@ -1,71 +0,29 @@ | ||
| /** | ||
| * StateContainer - Clean, minimal state management container | ||
| * | ||
| * Responsibilities: | ||
| * - State storage and updates | ||
| * - Change notifications to subscribers | ||
| * - Lifecycle management | ||
| */ | ||
| import { StateContainerRegistry } from './StateContainerRegistry'; | ||
| /** | ||
| * Configuration options for StateContainer | ||
| */ | ||
| export interface StateContainerConfig { | ||
| /** Container name for debugging */ | ||
| name?: string; | ||
| /** Enable debug logging */ | ||
| debug?: boolean; | ||
| /** Custom instance identifier */ | ||
| instanceId?: string; | ||
| } | ||
| /** | ||
| * Listener function for state changes | ||
| */ | ||
| type StateListener<S> = (state: S) => void; | ||
| /** | ||
| * Base abstract class for all state containers | ||
| */ | ||
| export declare abstract class StateContainer<S> { | ||
| /** | ||
| * Exclude this class from DevTools reporting | ||
| * Set to true for internal/DevTools-related Blocs to prevent infinite loops | ||
| */ | ||
| export type SystemEvent = 'propsUpdated' | 'stateChanged' | 'dispose'; | ||
| export interface SystemEventPayloads<S, P> { | ||
| propsUpdated: { | ||
| props: P; | ||
| previousProps: P | undefined; | ||
| }; | ||
| stateChanged: { | ||
| state: S; | ||
| previousState: S; | ||
| }; | ||
| dispose: void; | ||
| } | ||
| type SystemEventHandler<S, P, E extends SystemEvent> = (payload: SystemEventPayloads<S, P>[E]) => void; | ||
| export declare abstract class StateContainer<S, P = undefined> { | ||
| static __excludeFromDevTools: boolean; | ||
| /** | ||
| * Global registry for lifecycle events and instance management | ||
| */ | ||
| protected static _registry: StateContainerRegistry; | ||
| /** | ||
| * Get the global registry (mainly for testing) | ||
| */ | ||
| static getRegistry(): StateContainerRegistry; | ||
| /** | ||
| * Set a custom registry (mainly for testing) | ||
| * | ||
| * Clears all instances before switching to ensure clean test isolation. | ||
| */ | ||
| static setRegistry(registry: StateContainerRegistry): void; | ||
| /** | ||
| * Register a type as isolated or shared | ||
| */ | ||
| static register<T extends StateContainer<any>>(this: new (...args: any[]) => T, isolated?: boolean): void; | ||
| /** | ||
| * Resolve an instance with ref counting (ownership semantics) | ||
| * | ||
| * Delegates to the global registry for instance management. | ||
| * | ||
| * @param instanceKey - Optional instance key for shared instances | ||
| * @param constructorArgs - Constructor arguments | ||
| * @returns Instance with incremented ref count | ||
| */ | ||
| static resolve<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T; | ||
| /** | ||
| * Get an existing instance without ref counting (borrowing semantics) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static get<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): T; | ||
| /** | ||
| * Safely get an existing instance (borrowing semantics with error handling) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getSafe<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): { | ||
@@ -78,46 +36,8 @@ error: Error; | ||
| }; | ||
| /** | ||
| * Connect to an instance with borrowing semantics (for B2B communication) | ||
| * Gets existing instance OR creates it if it doesn't exist, without incrementing ref count. | ||
| * Tracks cross-bloc dependency for reactive updates. | ||
| * | ||
| * Use this in bloc-to-bloc communication when you need to ensure an instance exists | ||
| * but don't want to claim ownership (no ref count increment). | ||
| * | ||
| * Delegates to the global registry. | ||
| * | ||
| * @param instanceKey - Optional instance key (defaults to 'default') | ||
| * @param constructorArgs - Constructor arguments (only used if creating new instance) | ||
| * @returns The bloc instance | ||
| */ | ||
| static connect<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, constructorArgs?: any): T; | ||
| /** | ||
| * Release a reference to an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static release<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string, forceDispose?: boolean): void; | ||
| /** | ||
| * Get all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getAll<T extends StateContainer<any>>(this: new (...args: any[]) => T): T[]; | ||
| /** | ||
| * Safely iterate over all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static forEach<T extends StateContainer<any>>(this: new (...args: any[]) => T, callback: (instance: T) => void): void; | ||
| /** | ||
| * Clear all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clear<T extends StateContainer<any>>(this: new (...args: any[]) => T): void; | ||
| /** | ||
| * Clear all instances from all types (for testing) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clearAllInstances(): void; | ||
| /** | ||
| * Get registry statistics (for debugging) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getStats(): { | ||
@@ -128,11 +48,3 @@ registeredTypes: number; | ||
| }; | ||
| /** | ||
| * Get reference count for an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getRefCount<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): number; | ||
| /** | ||
| * Check if an instance exists | ||
| * Delegates to the global registry. | ||
| */ | ||
| static hasInstance<T extends StateContainer<any>>(this: new (...args: any[]) => T, instanceKey?: string): boolean; | ||
@@ -143,2 +55,4 @@ private _state; | ||
| private config; | ||
| private _props; | ||
| private readonly systemEventHandlers; | ||
| name: string; | ||
@@ -148,62 +62,21 @@ debug: boolean; | ||
| createdAt: number; | ||
| /** | ||
| * Create a new StateContainer | ||
| */ | ||
| get props(): P | undefined; | ||
| constructor(initialState: S); | ||
| initConfig(config: StateContainerConfig): void; | ||
| /** | ||
| * Get the current state | ||
| */ | ||
| get state(): S; | ||
| /** | ||
| * Check if disposed | ||
| */ | ||
| get isDisposed(): boolean; | ||
| /** | ||
| * Subscribe to state changes | ||
| * @returns Unsubscribe function | ||
| */ | ||
| subscribe(listener: StateListener<S>): () => void; | ||
| /** | ||
| * Dispose the container | ||
| */ | ||
| dispose(): void; | ||
| /** | ||
| * Emit a new state (with change detection) | ||
| */ | ||
| protected emit(newState: S): void; | ||
| /** | ||
| * Enable stack trace capture in development | ||
| * Defaults to true, but can be disabled to improve performance | ||
| */ | ||
| static enableStackTrace: boolean; | ||
| /** | ||
| * Capture stack trace for debugging | ||
| * Can be overridden to disable in production | ||
| */ | ||
| private captureStackTrace; | ||
| /** | ||
| * Format a single stack trace line for better readability | ||
| * Removes URL prefixes, query params, and cleans up the output | ||
| */ | ||
| private formatStackLine; | ||
| /** | ||
| * Clean up file path by removing URL prefixes and query params | ||
| */ | ||
| private cleanFilePath; | ||
| lastUpdateTimestamp: number; | ||
| /** | ||
| * Update state using a function | ||
| */ | ||
| protected update(updater: (current: S) => S): void; | ||
| /** | ||
| * Optional disposal hook for subclasses | ||
| */ | ||
| protected onDispose?(): void; | ||
| /** | ||
| * Optional state change hook for subclasses | ||
| */ | ||
| protected onStateChange?(newState: S, previousState: S): void; | ||
| protected onSystemEvent: <E extends SystemEvent>(event: E, handler: SystemEventHandler<S, P, E>) => (() => void); | ||
| private emitSystemEvent; | ||
| updateProps(newProps: P): void; | ||
| } | ||
| export {}; | ||
| //# sourceMappingURL=StateContainer.d.ts.map |
@@ -1,16 +0,3 @@ | ||
| /** | ||
| * StateContainerRegistry - Centralized instance and lifecycle management | ||
| * | ||
| * Responsibilities: | ||
| * - Instance storage and management (WeakMap per constructor) | ||
| * - Type registration and tracking | ||
| * - Lifecycle event notifications (plugin system) | ||
| * - Global operations (clearAllInstances) | ||
| */ | ||
| import type { StateContainer } from './StateContainer'; | ||
| import type { Vertex } from './Vertex'; | ||
| /** | ||
| * Internal entry for instance storage | ||
| * Each entry tracks an instance and its reference count | ||
| */ | ||
| export interface InstanceEntry<T = any> { | ||
@@ -20,55 +7,11 @@ instance: T; | ||
| } | ||
| /** | ||
| * Lifecycle events that can be observed | ||
| */ | ||
| export type LifecycleEvent = 'created' | 'stateChanged' | 'eventAdded' | 'disposed'; | ||
| /** | ||
| * Listener function types for each lifecycle event | ||
| */ | ||
| export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ? (container: StateContainer<any>) => void : E extends 'stateChanged' ? (container: StateContainer<any>, previousState: any, currentState: any, callstack?: string) => void : E extends 'eventAdded' ? (container: Vertex<any, any>, event: any) => void : E extends 'disposed' ? (container: StateContainer<any>) => void : never; | ||
| /** | ||
| * Registry for coordinating StateContainer lifecycle and managing instances | ||
| * | ||
| * Centralizes all instance management using WeakMap to ensure proper isolation. | ||
| */ | ||
| export declare class StateContainerRegistry { | ||
| /** | ||
| * Global storage for all instance Maps, keyed by constructor | ||
| * | ||
| * IMPORTANT: JavaScript/TypeScript static properties are inherited by reference, | ||
| * meaning all subclasses would share the same Map. To ensure each subclass has | ||
| * its own instance storage, we use a WeakMap keyed by the constructor function. | ||
| * | ||
| * This approach guarantees: | ||
| * - CounterBloc instances are separate from UserBloc instances | ||
| * - Each class owns and manages its own instances | ||
| * - Automatic garbage collection when classes are no longer referenced | ||
| */ | ||
| private readonly instancesByConstructor; | ||
| /** | ||
| * Strong Set for tracking all registered types | ||
| * Used for clearAllInstances() and getStats() | ||
| */ | ||
| private readonly types; | ||
| /** | ||
| * Type configurations (isolated flag) | ||
| */ | ||
| private readonly typeConfigs; | ||
| /** | ||
| * Lifecycle event listeners | ||
| */ | ||
| private readonly listeners; | ||
| /** | ||
| * Register a type for tracking | ||
| * Called automatically on first instance creation | ||
| */ | ||
| registerType<T extends StateContainer<any>>(constructor: new (...args: any[]) => T): void; | ||
| /** | ||
| * Register a type with isolation mode (explicit registration) | ||
| */ | ||
| register<T extends StateContainer<any>>(constructor: new (...args: any[]) => T, isolated?: boolean): void; | ||
| /** | ||
| * Get the instances Map for a specific class | ||
| * Creates a new Map on first access. | ||
| */ | ||
| private ensureInstancesMap; | ||
@@ -75,0 +18,0 @@ /** |
@@ -1,53 +0,14 @@ | ||
| /** | ||
| * Vertex - Event-driven state container (Bloc pattern) | ||
| * | ||
| * Simplified version that includes its own event handling, | ||
| * since events are only needed for the Vertex pattern. | ||
| */ | ||
| import { StateContainer } from './StateContainer'; | ||
| import { BaseEvent } from '../types/events'; | ||
| /** | ||
| * Event handler signature (synchronous only) | ||
| */ | ||
| export type EventHandler<E extends BaseEvent, S> = (event: E, emit: (state: S) => void) => void; | ||
| /** | ||
| * Type-safe event constructor | ||
| */ | ||
| export type EventConstructor<T extends BaseEvent = BaseEvent> = new (...args: never[]) => T; | ||
| /** | ||
| * Vertex is an event-driven state container (Bloc pattern) | ||
| * | ||
| * Includes its own simple event system since events are only needed | ||
| * for the Vertex pattern, not for the base StateContainer. | ||
| */ | ||
| export declare abstract class Vertex<S, E extends BaseEvent = BaseEvent> extends StateContainer<S> { | ||
| export declare abstract class Vertex<S, E extends BaseEvent = BaseEvent, P = undefined> extends StateContainer<S, P> { | ||
| private eventHandlers; | ||
| private isProcessing; | ||
| private eventQueue; | ||
| /** | ||
| * Create a new Vertex | ||
| * @param initialState Initial state value | ||
| */ | ||
| constructor(initialState: S); | ||
| /** | ||
| * Register an event handler | ||
| * Arrow function to maintain correct 'this' binding | ||
| */ | ||
| protected on: <T extends E>(EventClass: EventConstructor<T>, handler: EventHandler<T, S>) => void; | ||
| /** | ||
| * Add an event to be processed | ||
| * Arrow function to maintain correct 'this' binding in React | ||
| */ | ||
| add: (event: E) => void; | ||
| /** | ||
| * Process an event (synchronously) | ||
| */ | ||
| private processEvent; | ||
| /** | ||
| * Handle a single event (synchronously) | ||
| */ | ||
| private handleEvent; | ||
| /** | ||
| * Hook for handling event processing errors | ||
| */ | ||
| protected onEventError(_event: E, _error: Error): void; | ||
@@ -54,0 +15,0 @@ } |
+78
-257
@@ -100,5 +100,2 @@ | ||
| //#region src/plugin/PluginManager.ts | ||
| /** | ||
| * Plugin manager for registering and coordinating plugins | ||
| */ | ||
| var PluginManager = class { | ||
@@ -110,5 +107,2 @@ constructor(registry) { | ||
| } | ||
| /** | ||
| * Install a plugin | ||
| */ | ||
| install(plugin, config = {}) { | ||
@@ -140,5 +134,2 @@ const effectiveConfig = { | ||
| } | ||
| /** | ||
| * Uninstall a plugin | ||
| */ | ||
| uninstall(pluginName) { | ||
@@ -155,23 +146,11 @@ const installed = this.plugins.get(pluginName); | ||
| } | ||
| /** | ||
| * Get installed plugin | ||
| */ | ||
| getPlugin(pluginName) { | ||
| return this.plugins.get(pluginName)?.plugin; | ||
| } | ||
| /** | ||
| * Get all installed plugins | ||
| */ | ||
| getAllPlugins() { | ||
| return Array.from(this.plugins.values()).map((p) => p.plugin); | ||
| } | ||
| /** | ||
| * Check if plugin is installed | ||
| */ | ||
| hasPlugin(pluginName) { | ||
| return this.plugins.has(pluginName); | ||
| } | ||
| /** | ||
| * Clear all plugins (for testing) | ||
| */ | ||
| clear() { | ||
@@ -499,7 +478,2 @@ for (const name of this.plugins.keys()) this.uninstall(name); | ||
| //#region src/core/StateContainerRegistry.ts | ||
| /** | ||
| * Registry for coordinating StateContainer lifecycle and managing instances | ||
| * | ||
| * Centralizes all instance management using WeakMap to ensure proper isolation. | ||
| */ | ||
| var StateContainerRegistry = class { | ||
@@ -512,12 +486,5 @@ constructor() { | ||
| } | ||
| /** | ||
| * Register a type for tracking | ||
| * Called automatically on first instance creation | ||
| */ | ||
| registerType(constructor) { | ||
| this.types.add(constructor); | ||
| } | ||
| /** | ||
| * Register a type with isolation mode (explicit registration) | ||
| */ | ||
| register(constructor, isolated = false) { | ||
@@ -530,6 +497,2 @@ const className = constructor.name; | ||
| } | ||
| /** | ||
| * Get the instances Map for a specific class | ||
| * Creates a new Map on first access. | ||
| */ | ||
| ensureInstancesMap(Type) { | ||
@@ -780,13 +743,2 @@ let instances = this.instancesByConstructor.get(Type); | ||
| //#region src/core/StateContainer.ts | ||
| /** | ||
| * StateContainer - Clean, minimal state management container | ||
| * | ||
| * Responsibilities: | ||
| * - State storage and updates | ||
| * - Change notifications to subscribers | ||
| * - Lifecycle management | ||
| */ | ||
| /** | ||
| * Base abstract class for all state containers | ||
| */ | ||
| var StateContainer = class StateContainer { | ||
@@ -799,13 +751,5 @@ static { | ||
| } | ||
| /** | ||
| * Get the global registry (mainly for testing) | ||
| */ | ||
| static getRegistry() { | ||
| return StateContainer._registry; | ||
| } | ||
| /** | ||
| * Set a custom registry (mainly for testing) | ||
| * | ||
| * Clears all instances before switching to ensure clean test isolation. | ||
| */ | ||
| static setRegistry(registry) { | ||
@@ -815,110 +759,44 @@ StateContainer._registry.clearAll(); | ||
| } | ||
| /** | ||
| * Register a type as isolated or shared | ||
| */ | ||
| static register(isolated = false) { | ||
| StateContainer._registry.register(this, isolated); | ||
| } | ||
| /** | ||
| * Resolve an instance with ref counting (ownership semantics) | ||
| * | ||
| * Delegates to the global registry for instance management. | ||
| * | ||
| * @param instanceKey - Optional instance key for shared instances | ||
| * @param constructorArgs - Constructor arguments | ||
| * @returns Instance with incremented ref count | ||
| */ | ||
| static resolve(instanceKey, constructorArgs) { | ||
| return StateContainer._registry.resolve(this, instanceKey, constructorArgs); | ||
| } | ||
| /** | ||
| * Get an existing instance without ref counting (borrowing semantics) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static get(instanceKey) { | ||
| return StateContainer._registry.get(this, instanceKey); | ||
| } | ||
| /** | ||
| * Safely get an existing instance (borrowing semantics with error handling) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getSafe(instanceKey) { | ||
| return StateContainer._registry.getSafe(this, instanceKey); | ||
| } | ||
| /** | ||
| * Connect to an instance with borrowing semantics (for B2B communication) | ||
| * Gets existing instance OR creates it if it doesn't exist, without incrementing ref count. | ||
| * Tracks cross-bloc dependency for reactive updates. | ||
| * | ||
| * Use this in bloc-to-bloc communication when you need to ensure an instance exists | ||
| * but don't want to claim ownership (no ref count increment). | ||
| * | ||
| * Delegates to the global registry. | ||
| * | ||
| * @param instanceKey - Optional instance key (defaults to 'default') | ||
| * @param constructorArgs - Constructor arguments (only used if creating new instance) | ||
| * @returns The bloc instance | ||
| */ | ||
| static connect(instanceKey, constructorArgs) { | ||
| return StateContainer._registry.connect(this, instanceKey, constructorArgs); | ||
| } | ||
| /** | ||
| * Release a reference to an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static release(instanceKey, forceDispose = false) { | ||
| StateContainer._registry.release(this, instanceKey, forceDispose); | ||
| } | ||
| /** | ||
| * Get all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getAll() { | ||
| return StateContainer._registry.getAll(this); | ||
| } | ||
| /** | ||
| * Safely iterate over all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static forEach(callback) { | ||
| StateContainer._registry.forEach(this, callback); | ||
| } | ||
| /** | ||
| * Clear all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clear() { | ||
| StateContainer._registry.clear(this); | ||
| } | ||
| /** | ||
| * Clear all instances from all types (for testing) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clearAllInstances() { | ||
| StateContainer._registry.clearAll(); | ||
| } | ||
| /** | ||
| * Get registry statistics (for debugging) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getStats() { | ||
| return StateContainer._registry.getStats(); | ||
| } | ||
| /** | ||
| * Get reference count for an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getRefCount(instanceKey) { | ||
| return StateContainer._registry.getRefCount(this, instanceKey); | ||
| } | ||
| /** | ||
| * Check if an instance exists | ||
| * Delegates to the global registry. | ||
| */ | ||
| static hasInstance(instanceKey) { | ||
| return StateContainer._registry.hasInstance(this, instanceKey); | ||
| } | ||
| /** | ||
| * Create a new StateContainer | ||
| */ | ||
| get props() { | ||
| return this._props; | ||
| } | ||
| constructor(initialState) { | ||
@@ -928,2 +806,4 @@ this.listeners = /* @__PURE__ */ new Set(); | ||
| this.config = {}; | ||
| this._props = void 0; | ||
| this.systemEventHandlers = /* @__PURE__ */ new Map(); | ||
| this.name = this.constructor.name; | ||
@@ -934,2 +814,13 @@ this.debug = false; | ||
| this.lastUpdateTimestamp = Date.now(); | ||
| this.onSystemEvent = (event, handler) => { | ||
| let handlers = this.systemEventHandlers.get(event); | ||
| if (!handlers) { | ||
| handlers = /* @__PURE__ */ new Set(); | ||
| this.systemEventHandlers.set(event, handlers); | ||
| } | ||
| handlers.add(handler); | ||
| return () => { | ||
| handlers?.delete(handler); | ||
| }; | ||
| }; | ||
| this._state = initialState; | ||
@@ -944,18 +835,8 @@ } | ||
| } | ||
| /** | ||
| * Get the current state | ||
| */ | ||
| get state() { | ||
| return this._state; | ||
| } | ||
| /** | ||
| * Check if disposed | ||
| */ | ||
| get isDisposed() { | ||
| return this._disposed; | ||
| } | ||
| /** | ||
| * Subscribe to state changes | ||
| * @returns Unsubscribe function | ||
| */ | ||
| subscribe(listener) { | ||
@@ -966,5 +847,2 @@ if (this._disposed) throw new Error(`Cannot subscribe to disposed container ${this.name}`); | ||
| } | ||
| /** | ||
| * Dispose the container | ||
| */ | ||
| dispose() { | ||
@@ -974,10 +852,8 @@ if (this._disposed) return; | ||
| this._disposed = true; | ||
| this.onDispose?.(); | ||
| this.emitSystemEvent("dispose", void 0); | ||
| this.listeners.clear(); | ||
| this.systemEventHandlers.clear(); | ||
| StateContainer._registry.emit("disposed", this); | ||
| if (this.debug) console.log(`[${this.name}] Disposed successfully`); | ||
| } | ||
| /** | ||
| * Emit a new state (with change detection) | ||
| */ | ||
| emit(newState) { | ||
@@ -988,3 +864,6 @@ if (this._disposed) throw new Error(`Cannot emit state from disposed container ${this.name}`); | ||
| this._state = newState; | ||
| this.onStateChange?.(newState, previousState); | ||
| this.emitSystemEvent("stateChanged", { | ||
| state: newState, | ||
| previousState | ||
| }); | ||
| for (const listener of this.listeners) try { | ||
@@ -1002,6 +881,2 @@ listener(newState); | ||
| } | ||
| /** | ||
| * Capture stack trace for debugging | ||
| * Can be overridden to disable in production | ||
| */ | ||
| captureStackTrace() { | ||
@@ -1024,6 +899,2 @@ if (!StateContainer.enableStackTrace || typeof process !== "undefined" && process.env?.NODE_ENV === "production") return ""; | ||
| } | ||
| /** | ||
| * Format a single stack trace line for better readability | ||
| * Removes URL prefixes, query params, and cleans up the output | ||
| */ | ||
| formatStackLine(line) { | ||
@@ -1042,5 +913,2 @@ const match = line.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/); | ||
| } | ||
| /** | ||
| * Clean up file path by removing URL prefixes and query params | ||
| */ | ||
| cleanFilePath(url) { | ||
@@ -1054,5 +922,2 @@ let path = url.replace(/http:\/\/localhost:\d+\/@fs/, "").replace(/http:\/\/localhost:\d+\//, "").replace(/\?t=\d+/, "").replace(/\?v=[a-f0-9]+/, ""); | ||
| } | ||
| /** | ||
| * Update state using a function | ||
| */ | ||
| update(updater) { | ||
@@ -1062,2 +927,24 @@ if (this._disposed) throw new Error(`Cannot update state from disposed container ${this.name}`); | ||
| } | ||
| emitSystemEvent(event, payload) { | ||
| const handlers = this.systemEventHandlers.get(event); | ||
| if (!handlers) return; | ||
| for (const handler of handlers) try { | ||
| handler(payload); | ||
| } catch (error$1) { | ||
| console.error(`[${this.name}] Error in system event handler:`, error$1); | ||
| } | ||
| } | ||
| updateProps(newProps) { | ||
| if (this._disposed) throw new Error(`Cannot update props on disposed container ${this.name}`); | ||
| const previousProps = this._props; | ||
| this._props = newProps; | ||
| this.emitSystemEvent("propsUpdated", { | ||
| props: newProps, | ||
| previousProps | ||
| }); | ||
| if (this.debug) console.log(`[${this.name}] Props updated:`, { | ||
| newProps, | ||
| previousProps | ||
| }); | ||
| } | ||
| }; | ||
@@ -1067,19 +954,3 @@ | ||
| //#region src/core/Cubit.ts | ||
| /** | ||
| * Cubit - Simple state container with direct state emission | ||
| * | ||
| * This validates that our StateContainer design can support | ||
| * the simple Cubit pattern from the original BlaC. | ||
| */ | ||
| /** | ||
| * Cubit is a simple state container that allows direct state emission | ||
| * | ||
| * Unlike StateContainer (where emit is protected), Cubit exposes emit and update | ||
| * as public methods to allow direct state management. | ||
| */ | ||
| var Cubit = class extends StateContainer { | ||
| /** | ||
| * Create a new Cubit | ||
| * @param initialState Initial state value | ||
| */ | ||
| constructor(initialState) { | ||
@@ -1095,11 +966,5 @@ super(initialState); | ||
| } | ||
| /** | ||
| * Emit a new state (public override of protected parent method) | ||
| */ | ||
| emit(newState) { | ||
| super["emit"](newState); | ||
| } | ||
| /** | ||
| * Update state using a function (public override of protected parent method) | ||
| */ | ||
| update(updater) { | ||
@@ -1109,5 +974,2 @@ super["update"](updater); | ||
| }; | ||
| /** | ||
| * Example: Counter Cubit | ||
| */ | ||
| var CounterCubit = class extends Cubit { | ||
@@ -1189,19 +1051,3 @@ constructor() { | ||
| //#region src/core/Vertex.ts | ||
| /** | ||
| * Vertex - Event-driven state container (Bloc pattern) | ||
| * | ||
| * Simplified version that includes its own event handling, | ||
| * since events are only needed for the Vertex pattern. | ||
| */ | ||
| /** | ||
| * Vertex is an event-driven state container (Bloc pattern) | ||
| * | ||
| * Includes its own simple event system since events are only needed | ||
| * for the Vertex pattern, not for the base StateContainer. | ||
| */ | ||
| var Vertex = class extends StateContainer { | ||
| /** | ||
| * Create a new Vertex | ||
| * @param initialState Initial state value | ||
| */ | ||
| constructor(initialState) { | ||
@@ -1226,5 +1072,2 @@ super(initialState); | ||
| } | ||
| /** | ||
| * Process an event (synchronously) | ||
| */ | ||
| processEvent(event) { | ||
@@ -1246,5 +1089,2 @@ if (this.isProcessing) { | ||
| } | ||
| /** | ||
| * Handle a single event (synchronously) | ||
| */ | ||
| handleEvent(event) { | ||
@@ -1267,5 +1107,2 @@ const className = event.constructor.name; | ||
| } | ||
| /** | ||
| * Hook for handling event processing errors | ||
| */ | ||
| onEventError(_event, _error) {} | ||
@@ -1387,5 +1224,2 @@ }; | ||
| //#region src/plugin/BlacPlugin.ts | ||
| /** | ||
| * Type guard for plugins with init | ||
| */ | ||
| function hasInitHook(plugin) { | ||
@@ -1734,6 +1568,2 @@ return typeof plugin.onInstall === "function"; | ||
| //#region src/adapter/framework-adapter.ts | ||
| /** | ||
| * External dependency manager | ||
| * Handles subscriptions to external blocs accessed in getters | ||
| */ | ||
| var ExternalDependencyManager = class { | ||
@@ -1744,5 +1574,2 @@ constructor() { | ||
| } | ||
| /** | ||
| * Check if dependencies have changed | ||
| */ | ||
| areDependenciesEqual(oldDeps, newDeps) { | ||
@@ -1753,9 +1580,2 @@ if (oldDeps.size !== newDeps.size) return false; | ||
| } | ||
| /** | ||
| * Update external subscriptions | ||
| * @param getterTracker - The getter tracker state | ||
| * @param rawInstance - The raw bloc instance (exclude from subscriptions) | ||
| * @param onGetterChange - Callback when external getter changes | ||
| * @returns Whether subscriptions were updated | ||
| */ | ||
| updateSubscriptions(getterTracker, rawInstance, onGetterChange) { | ||
@@ -1781,5 +1601,2 @@ if (!getterTracker?.externalDependencies) return false; | ||
| } | ||
| /** | ||
| * Cleanup all subscriptions | ||
| */ | ||
| cleanup() { | ||
@@ -1790,5 +1607,2 @@ this.subscriptions.forEach((unsub) => unsub()); | ||
| }; | ||
| /** | ||
| * Create a subscription function for auto-tracking mode | ||
| */ | ||
| function createAutoTrackSubscribe(instance, adapterState) { | ||
@@ -1812,5 +1626,2 @@ return (callback) => { | ||
| } | ||
| /** | ||
| * Create a subscription function for manual dependencies mode | ||
| */ | ||
| function createManualDepsSubscribe(instance, adapterState, config) { | ||
@@ -1827,11 +1638,5 @@ return (callback) => { | ||
| } | ||
| /** | ||
| * Create a subscription function for no-tracking mode | ||
| */ | ||
| function createNoTrackSubscribe(instance) { | ||
| return (callback) => instance.subscribe(callback); | ||
| } | ||
| /** | ||
| * Create a snapshot function for auto-tracking mode | ||
| */ | ||
| function createAutoTrackSnapshot(instance, adapterState) { | ||
@@ -1851,5 +1656,2 @@ return () => { | ||
| } | ||
| /** | ||
| * Create a snapshot function for manual dependencies mode | ||
| */ | ||
| function createManualDepsSnapshot(instance, adapterState, config) { | ||
@@ -1861,11 +1663,5 @@ return () => { | ||
| } | ||
| /** | ||
| * Create a snapshot function for no-tracking mode | ||
| */ | ||
| function createNoTrackSnapshot(instance) { | ||
| return () => instance.state; | ||
| } | ||
| /** | ||
| * Initialize adapter state for auto-tracking mode | ||
| */ | ||
| function initAutoTrackState(instance) { | ||
@@ -1879,5 +1675,2 @@ return { | ||
| } | ||
| /** | ||
| * Initialize adapter state for manual dependencies mode | ||
| */ | ||
| function initManualDepsState(instance) { | ||
@@ -1891,5 +1684,2 @@ return { | ||
| } | ||
| /** | ||
| * Initialize adapter state for no-tracking mode | ||
| */ | ||
| function initNoTrackState(instance) { | ||
@@ -1903,5 +1693,2 @@ return { | ||
| } | ||
| /** | ||
| * Disable getter tracking (call after render completes) | ||
| */ | ||
| function disableGetterTracking(adapterState, rawInstance) { | ||
@@ -2011,2 +1798,35 @@ if (adapterState.getterTracker) { | ||
| //#endregion | ||
| //#region src/decorators/blac.ts | ||
| /** | ||
| * Decorator to configure StateContainer classes. | ||
| * | ||
| * @example Decorator syntax (requires experimentalDecorators or TC39 decorators) | ||
| * ```typescript | ||
| * @blac({ isolated: true }) | ||
| * class FormBloc extends Cubit<FormState> {} | ||
| * | ||
| * @blac({ keepAlive: true }) | ||
| * class AuthBloc extends Cubit<AuthState> {} | ||
| * | ||
| * @blac({ excludeFromDevTools: true }) | ||
| * class InternalBloc extends Cubit<InternalState> {} | ||
| * ``` | ||
| * | ||
| * @example Function syntax (no decorator support needed) | ||
| * ```typescript | ||
| * const FormBloc = blac({ isolated: true })( | ||
| * class extends Cubit<FormState> {} | ||
| * ); | ||
| * ``` | ||
| */ | ||
| function blac(options) { | ||
| return function(target, _context) { | ||
| if ("isolated" in options && options.isolated) target[BLAC_STATIC_PROPS.ISOLATED] = true; | ||
| if ("keepAlive" in options && options.keepAlive) target[BLAC_STATIC_PROPS.KEEP_ALIVE] = true; | ||
| if ("excludeFromDevTools" in options && options.excludeFromDevTools) target[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true; | ||
| return target; | ||
| }; | ||
| } | ||
| //#endregion | ||
| exports.AuthVertex = AuthVertex; | ||
@@ -2033,2 +1853,3 @@ exports.BLAC_DEFAULTS = BLAC_DEFAULTS; | ||
| exports.__resetIdCounters = __resetIdCounters; | ||
| exports.blac = blac; | ||
| exports.captureTrackedPaths = captureTrackedPaths; | ||
@@ -2035,0 +1856,0 @@ exports.clearActiveTracker = clearActiveTracker; |
+2
-0
| export * from './core/StateContainer'; | ||
| export type { SystemEvent, SystemEventPayloads } from './core/StateContainer'; | ||
| export * from './core/StateContainerRegistry'; | ||
@@ -19,2 +20,3 @@ export * from './core/Cubit'; | ||
| export { getStaticProp, isIsolatedClass, isKeepAliveClass, isExcludedFromDevTools, } from './utils/static-props'; | ||
| export { blac, type BlacOptions } from './decorators'; | ||
| //# sourceMappingURL=index.d.ts.map |
+2
-0
| export * from './core/StateContainer'; | ||
| export type { SystemEvent, SystemEventPayloads } from './core/StateContainer'; | ||
| export * from './core/StateContainerRegistry'; | ||
@@ -19,2 +20,3 @@ export * from './core/Cubit'; | ||
| export { getStaticProp, isIsolatedClass, isKeepAliveClass, isExcludedFromDevTools, } from './utils/static-props'; | ||
| export { blac, type BlacOptions } from './decorators'; | ||
| //# sourceMappingURL=index.d.ts.map |
+78
-258
@@ -99,5 +99,2 @@ //#region src/utils/idGenerator.ts | ||
| //#region src/plugin/PluginManager.ts | ||
| /** | ||
| * Plugin manager for registering and coordinating plugins | ||
| */ | ||
| var PluginManager = class { | ||
@@ -109,5 +106,2 @@ constructor(registry) { | ||
| } | ||
| /** | ||
| * Install a plugin | ||
| */ | ||
| install(plugin, config = {}) { | ||
@@ -139,5 +133,2 @@ const effectiveConfig = { | ||
| } | ||
| /** | ||
| * Uninstall a plugin | ||
| */ | ||
| uninstall(pluginName) { | ||
@@ -154,23 +145,11 @@ const installed = this.plugins.get(pluginName); | ||
| } | ||
| /** | ||
| * Get installed plugin | ||
| */ | ||
| getPlugin(pluginName) { | ||
| return this.plugins.get(pluginName)?.plugin; | ||
| } | ||
| /** | ||
| * Get all installed plugins | ||
| */ | ||
| getAllPlugins() { | ||
| return Array.from(this.plugins.values()).map((p) => p.plugin); | ||
| } | ||
| /** | ||
| * Check if plugin is installed | ||
| */ | ||
| hasPlugin(pluginName) { | ||
| return this.plugins.has(pluginName); | ||
| } | ||
| /** | ||
| * Clear all plugins (for testing) | ||
| */ | ||
| clear() { | ||
@@ -498,7 +477,2 @@ for (const name of this.plugins.keys()) this.uninstall(name); | ||
| //#region src/core/StateContainerRegistry.ts | ||
| /** | ||
| * Registry for coordinating StateContainer lifecycle and managing instances | ||
| * | ||
| * Centralizes all instance management using WeakMap to ensure proper isolation. | ||
| */ | ||
| var StateContainerRegistry = class { | ||
@@ -511,12 +485,5 @@ constructor() { | ||
| } | ||
| /** | ||
| * Register a type for tracking | ||
| * Called automatically on first instance creation | ||
| */ | ||
| registerType(constructor) { | ||
| this.types.add(constructor); | ||
| } | ||
| /** | ||
| * Register a type with isolation mode (explicit registration) | ||
| */ | ||
| register(constructor, isolated = false) { | ||
@@ -529,6 +496,2 @@ const className = constructor.name; | ||
| } | ||
| /** | ||
| * Get the instances Map for a specific class | ||
| * Creates a new Map on first access. | ||
| */ | ||
| ensureInstancesMap(Type) { | ||
@@ -779,13 +742,2 @@ let instances = this.instancesByConstructor.get(Type); | ||
| //#region src/core/StateContainer.ts | ||
| /** | ||
| * StateContainer - Clean, minimal state management container | ||
| * | ||
| * Responsibilities: | ||
| * - State storage and updates | ||
| * - Change notifications to subscribers | ||
| * - Lifecycle management | ||
| */ | ||
| /** | ||
| * Base abstract class for all state containers | ||
| */ | ||
| var StateContainer = class StateContainer { | ||
@@ -798,13 +750,5 @@ static { | ||
| } | ||
| /** | ||
| * Get the global registry (mainly for testing) | ||
| */ | ||
| static getRegistry() { | ||
| return StateContainer._registry; | ||
| } | ||
| /** | ||
| * Set a custom registry (mainly for testing) | ||
| * | ||
| * Clears all instances before switching to ensure clean test isolation. | ||
| */ | ||
| static setRegistry(registry) { | ||
@@ -814,110 +758,44 @@ StateContainer._registry.clearAll(); | ||
| } | ||
| /** | ||
| * Register a type as isolated or shared | ||
| */ | ||
| static register(isolated = false) { | ||
| StateContainer._registry.register(this, isolated); | ||
| } | ||
| /** | ||
| * Resolve an instance with ref counting (ownership semantics) | ||
| * | ||
| * Delegates to the global registry for instance management. | ||
| * | ||
| * @param instanceKey - Optional instance key for shared instances | ||
| * @param constructorArgs - Constructor arguments | ||
| * @returns Instance with incremented ref count | ||
| */ | ||
| static resolve(instanceKey, constructorArgs) { | ||
| return StateContainer._registry.resolve(this, instanceKey, constructorArgs); | ||
| } | ||
| /** | ||
| * Get an existing instance without ref counting (borrowing semantics) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static get(instanceKey) { | ||
| return StateContainer._registry.get(this, instanceKey); | ||
| } | ||
| /** | ||
| * Safely get an existing instance (borrowing semantics with error handling) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getSafe(instanceKey) { | ||
| return StateContainer._registry.getSafe(this, instanceKey); | ||
| } | ||
| /** | ||
| * Connect to an instance with borrowing semantics (for B2B communication) | ||
| * Gets existing instance OR creates it if it doesn't exist, without incrementing ref count. | ||
| * Tracks cross-bloc dependency for reactive updates. | ||
| * | ||
| * Use this in bloc-to-bloc communication when you need to ensure an instance exists | ||
| * but don't want to claim ownership (no ref count increment). | ||
| * | ||
| * Delegates to the global registry. | ||
| * | ||
| * @param instanceKey - Optional instance key (defaults to 'default') | ||
| * @param constructorArgs - Constructor arguments (only used if creating new instance) | ||
| * @returns The bloc instance | ||
| */ | ||
| static connect(instanceKey, constructorArgs) { | ||
| return StateContainer._registry.connect(this, instanceKey, constructorArgs); | ||
| } | ||
| /** | ||
| * Release a reference to an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static release(instanceKey, forceDispose = false) { | ||
| StateContainer._registry.release(this, instanceKey, forceDispose); | ||
| } | ||
| /** | ||
| * Get all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getAll() { | ||
| return StateContainer._registry.getAll(this); | ||
| } | ||
| /** | ||
| * Safely iterate over all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static forEach(callback) { | ||
| StateContainer._registry.forEach(this, callback); | ||
| } | ||
| /** | ||
| * Clear all instances of this type | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clear() { | ||
| StateContainer._registry.clear(this); | ||
| } | ||
| /** | ||
| * Clear all instances from all types (for testing) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static clearAllInstances() { | ||
| StateContainer._registry.clearAll(); | ||
| } | ||
| /** | ||
| * Get registry statistics (for debugging) | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getStats() { | ||
| return StateContainer._registry.getStats(); | ||
| } | ||
| /** | ||
| * Get reference count for an instance | ||
| * Delegates to the global registry. | ||
| */ | ||
| static getRefCount(instanceKey) { | ||
| return StateContainer._registry.getRefCount(this, instanceKey); | ||
| } | ||
| /** | ||
| * Check if an instance exists | ||
| * Delegates to the global registry. | ||
| */ | ||
| static hasInstance(instanceKey) { | ||
| return StateContainer._registry.hasInstance(this, instanceKey); | ||
| } | ||
| /** | ||
| * Create a new StateContainer | ||
| */ | ||
| get props() { | ||
| return this._props; | ||
| } | ||
| constructor(initialState) { | ||
@@ -927,2 +805,4 @@ this.listeners = /* @__PURE__ */ new Set(); | ||
| this.config = {}; | ||
| this._props = void 0; | ||
| this.systemEventHandlers = /* @__PURE__ */ new Map(); | ||
| this.name = this.constructor.name; | ||
@@ -933,2 +813,13 @@ this.debug = false; | ||
| this.lastUpdateTimestamp = Date.now(); | ||
| this.onSystemEvent = (event, handler) => { | ||
| let handlers = this.systemEventHandlers.get(event); | ||
| if (!handlers) { | ||
| handlers = /* @__PURE__ */ new Set(); | ||
| this.systemEventHandlers.set(event, handlers); | ||
| } | ||
| handlers.add(handler); | ||
| return () => { | ||
| handlers?.delete(handler); | ||
| }; | ||
| }; | ||
| this._state = initialState; | ||
@@ -943,18 +834,8 @@ } | ||
| } | ||
| /** | ||
| * Get the current state | ||
| */ | ||
| get state() { | ||
| return this._state; | ||
| } | ||
| /** | ||
| * Check if disposed | ||
| */ | ||
| get isDisposed() { | ||
| return this._disposed; | ||
| } | ||
| /** | ||
| * Subscribe to state changes | ||
| * @returns Unsubscribe function | ||
| */ | ||
| subscribe(listener) { | ||
@@ -965,5 +846,2 @@ if (this._disposed) throw new Error(`Cannot subscribe to disposed container ${this.name}`); | ||
| } | ||
| /** | ||
| * Dispose the container | ||
| */ | ||
| dispose() { | ||
@@ -973,10 +851,8 @@ if (this._disposed) return; | ||
| this._disposed = true; | ||
| this.onDispose?.(); | ||
| this.emitSystemEvent("dispose", void 0); | ||
| this.listeners.clear(); | ||
| this.systemEventHandlers.clear(); | ||
| StateContainer._registry.emit("disposed", this); | ||
| if (this.debug) console.log(`[${this.name}] Disposed successfully`); | ||
| } | ||
| /** | ||
| * Emit a new state (with change detection) | ||
| */ | ||
| emit(newState) { | ||
@@ -987,3 +863,6 @@ if (this._disposed) throw new Error(`Cannot emit state from disposed container ${this.name}`); | ||
| this._state = newState; | ||
| this.onStateChange?.(newState, previousState); | ||
| this.emitSystemEvent("stateChanged", { | ||
| state: newState, | ||
| previousState | ||
| }); | ||
| for (const listener of this.listeners) try { | ||
@@ -1001,6 +880,2 @@ listener(newState); | ||
| } | ||
| /** | ||
| * Capture stack trace for debugging | ||
| * Can be overridden to disable in production | ||
| */ | ||
| captureStackTrace() { | ||
@@ -1023,6 +898,2 @@ if (!StateContainer.enableStackTrace || typeof process !== "undefined" && process.env?.NODE_ENV === "production") return ""; | ||
| } | ||
| /** | ||
| * Format a single stack trace line for better readability | ||
| * Removes URL prefixes, query params, and cleans up the output | ||
| */ | ||
| formatStackLine(line) { | ||
@@ -1041,5 +912,2 @@ const match = line.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/); | ||
| } | ||
| /** | ||
| * Clean up file path by removing URL prefixes and query params | ||
| */ | ||
| cleanFilePath(url) { | ||
@@ -1053,5 +921,2 @@ let path = url.replace(/http:\/\/localhost:\d+\/@fs/, "").replace(/http:\/\/localhost:\d+\//, "").replace(/\?t=\d+/, "").replace(/\?v=[a-f0-9]+/, ""); | ||
| } | ||
| /** | ||
| * Update state using a function | ||
| */ | ||
| update(updater) { | ||
@@ -1061,2 +926,24 @@ if (this._disposed) throw new Error(`Cannot update state from disposed container ${this.name}`); | ||
| } | ||
| emitSystemEvent(event, payload) { | ||
| const handlers = this.systemEventHandlers.get(event); | ||
| if (!handlers) return; | ||
| for (const handler of handlers) try { | ||
| handler(payload); | ||
| } catch (error$1) { | ||
| console.error(`[${this.name}] Error in system event handler:`, error$1); | ||
| } | ||
| } | ||
| updateProps(newProps) { | ||
| if (this._disposed) throw new Error(`Cannot update props on disposed container ${this.name}`); | ||
| const previousProps = this._props; | ||
| this._props = newProps; | ||
| this.emitSystemEvent("propsUpdated", { | ||
| props: newProps, | ||
| previousProps | ||
| }); | ||
| if (this.debug) console.log(`[${this.name}] Props updated:`, { | ||
| newProps, | ||
| previousProps | ||
| }); | ||
| } | ||
| }; | ||
@@ -1066,19 +953,3 @@ | ||
| //#region src/core/Cubit.ts | ||
| /** | ||
| * Cubit - Simple state container with direct state emission | ||
| * | ||
| * This validates that our StateContainer design can support | ||
| * the simple Cubit pattern from the original BlaC. | ||
| */ | ||
| /** | ||
| * Cubit is a simple state container that allows direct state emission | ||
| * | ||
| * Unlike StateContainer (where emit is protected), Cubit exposes emit and update | ||
| * as public methods to allow direct state management. | ||
| */ | ||
| var Cubit = class extends StateContainer { | ||
| /** | ||
| * Create a new Cubit | ||
| * @param initialState Initial state value | ||
| */ | ||
| constructor(initialState) { | ||
@@ -1094,11 +965,5 @@ super(initialState); | ||
| } | ||
| /** | ||
| * Emit a new state (public override of protected parent method) | ||
| */ | ||
| emit(newState) { | ||
| super["emit"](newState); | ||
| } | ||
| /** | ||
| * Update state using a function (public override of protected parent method) | ||
| */ | ||
| update(updater) { | ||
@@ -1108,5 +973,2 @@ super["update"](updater); | ||
| }; | ||
| /** | ||
| * Example: Counter Cubit | ||
| */ | ||
| var CounterCubit = class extends Cubit { | ||
@@ -1188,19 +1050,3 @@ constructor() { | ||
| //#region src/core/Vertex.ts | ||
| /** | ||
| * Vertex - Event-driven state container (Bloc pattern) | ||
| * | ||
| * Simplified version that includes its own event handling, | ||
| * since events are only needed for the Vertex pattern. | ||
| */ | ||
| /** | ||
| * Vertex is an event-driven state container (Bloc pattern) | ||
| * | ||
| * Includes its own simple event system since events are only needed | ||
| * for the Vertex pattern, not for the base StateContainer. | ||
| */ | ||
| var Vertex = class extends StateContainer { | ||
| /** | ||
| * Create a new Vertex | ||
| * @param initialState Initial state value | ||
| */ | ||
| constructor(initialState) { | ||
@@ -1225,5 +1071,2 @@ super(initialState); | ||
| } | ||
| /** | ||
| * Process an event (synchronously) | ||
| */ | ||
| processEvent(event) { | ||
@@ -1245,5 +1088,2 @@ if (this.isProcessing) { | ||
| } | ||
| /** | ||
| * Handle a single event (synchronously) | ||
| */ | ||
| handleEvent(event) { | ||
@@ -1266,5 +1106,2 @@ const className = event.constructor.name; | ||
| } | ||
| /** | ||
| * Hook for handling event processing errors | ||
| */ | ||
| onEventError(_event, _error) {} | ||
@@ -1386,5 +1223,2 @@ }; | ||
| //#region src/plugin/BlacPlugin.ts | ||
| /** | ||
| * Type guard for plugins with init | ||
| */ | ||
| function hasInitHook(plugin) { | ||
@@ -1733,6 +1567,2 @@ return typeof plugin.onInstall === "function"; | ||
| //#region src/adapter/framework-adapter.ts | ||
| /** | ||
| * External dependency manager | ||
| * Handles subscriptions to external blocs accessed in getters | ||
| */ | ||
| var ExternalDependencyManager = class { | ||
@@ -1743,5 +1573,2 @@ constructor() { | ||
| } | ||
| /** | ||
| * Check if dependencies have changed | ||
| */ | ||
| areDependenciesEqual(oldDeps, newDeps) { | ||
@@ -1752,9 +1579,2 @@ if (oldDeps.size !== newDeps.size) return false; | ||
| } | ||
| /** | ||
| * Update external subscriptions | ||
| * @param getterTracker - The getter tracker state | ||
| * @param rawInstance - The raw bloc instance (exclude from subscriptions) | ||
| * @param onGetterChange - Callback when external getter changes | ||
| * @returns Whether subscriptions were updated | ||
| */ | ||
| updateSubscriptions(getterTracker, rawInstance, onGetterChange) { | ||
@@ -1780,5 +1600,2 @@ if (!getterTracker?.externalDependencies) return false; | ||
| } | ||
| /** | ||
| * Cleanup all subscriptions | ||
| */ | ||
| cleanup() { | ||
@@ -1789,5 +1606,2 @@ this.subscriptions.forEach((unsub) => unsub()); | ||
| }; | ||
| /** | ||
| * Create a subscription function for auto-tracking mode | ||
| */ | ||
| function createAutoTrackSubscribe(instance, adapterState) { | ||
@@ -1811,5 +1625,2 @@ return (callback) => { | ||
| } | ||
| /** | ||
| * Create a subscription function for manual dependencies mode | ||
| */ | ||
| function createManualDepsSubscribe(instance, adapterState, config) { | ||
@@ -1826,11 +1637,5 @@ return (callback) => { | ||
| } | ||
| /** | ||
| * Create a subscription function for no-tracking mode | ||
| */ | ||
| function createNoTrackSubscribe(instance) { | ||
| return (callback) => instance.subscribe(callback); | ||
| } | ||
| /** | ||
| * Create a snapshot function for auto-tracking mode | ||
| */ | ||
| function createAutoTrackSnapshot(instance, adapterState) { | ||
@@ -1850,5 +1655,2 @@ return () => { | ||
| } | ||
| /** | ||
| * Create a snapshot function for manual dependencies mode | ||
| */ | ||
| function createManualDepsSnapshot(instance, adapterState, config) { | ||
@@ -1860,11 +1662,5 @@ return () => { | ||
| } | ||
| /** | ||
| * Create a snapshot function for no-tracking mode | ||
| */ | ||
| function createNoTrackSnapshot(instance) { | ||
| return () => instance.state; | ||
| } | ||
| /** | ||
| * Initialize adapter state for auto-tracking mode | ||
| */ | ||
| function initAutoTrackState(instance) { | ||
@@ -1878,5 +1674,2 @@ return { | ||
| } | ||
| /** | ||
| * Initialize adapter state for manual dependencies mode | ||
| */ | ||
| function initManualDepsState(instance) { | ||
@@ -1890,5 +1683,2 @@ return { | ||
| } | ||
| /** | ||
| * Initialize adapter state for no-tracking mode | ||
| */ | ||
| function initNoTrackState(instance) { | ||
@@ -1902,5 +1692,2 @@ return { | ||
| } | ||
| /** | ||
| * Disable getter tracking (call after render completes) | ||
| */ | ||
| function disableGetterTracking(adapterState, rawInstance) { | ||
@@ -2010,3 +1797,36 @@ if (adapterState.getterTracker) { | ||
| //#endregion | ||
| export { AuthVertex, BLAC_DEFAULTS, BLAC_ERROR_PREFIX, BLAC_ID_PATTERNS, BLAC_STATIC_PROPS, CounterCubit, CounterVertex, Cubit, DecrementEvent, ExternalDependencyManager, IncrementEvent, LogLevel, LoginEvent, LogoutEvent, PluginManager, ResetEvent, StateContainer, StateContainerRegistry, TodoCubit, Vertex, __resetIdCounters, captureTrackedPaths, clearActiveTracker, clearExternalDependencies, commitTrackedGetters, configureLogger, createArrayProxy, createAutoTrackSnapshot, createAutoTrackSubscribe, createBlocProxy, createGetterTracker, createIdGenerator, createLogger, createManualDepsSnapshot, createManualDepsSubscribe, createNoTrackSnapshot, createNoTrackSubscribe, createPluginManager, createProxy, createProxyForTarget, createProxyInternal, createProxyTrackerState, createTrackerState, debug, disableGetterTracking, error, generateId, generateIsolatedKey, generateSimpleId, getActiveTracker, getDescriptor, getGetterExecutionContext, getPluginManager, getStaticProp, getValueAtPath, globalRegistry, hasChanges, hasGetterChanges, hasInitHook, hasTrackedData, info, initAutoTrackState, initManualDepsState, initNoTrackState, invalidateRenderCache, isExcludedFromDevTools, isGetter, isIsolatedClass, isIsolatedKey, isKeepAliveClass, isProxyable, parsePath, resetGetterTracker, setActiveTracker, shallowEqual, startProxyTracking, startTracking, stopProxyTracking, warn }; | ||
| //#region src/decorators/blac.ts | ||
| /** | ||
| * Decorator to configure StateContainer classes. | ||
| * | ||
| * @example Decorator syntax (requires experimentalDecorators or TC39 decorators) | ||
| * ```typescript | ||
| * @blac({ isolated: true }) | ||
| * class FormBloc extends Cubit<FormState> {} | ||
| * | ||
| * @blac({ keepAlive: true }) | ||
| * class AuthBloc extends Cubit<AuthState> {} | ||
| * | ||
| * @blac({ excludeFromDevTools: true }) | ||
| * class InternalBloc extends Cubit<InternalState> {} | ||
| * ``` | ||
| * | ||
| * @example Function syntax (no decorator support needed) | ||
| * ```typescript | ||
| * const FormBloc = blac({ isolated: true })( | ||
| * class extends Cubit<FormState> {} | ||
| * ); | ||
| * ``` | ||
| */ | ||
| function blac(options) { | ||
| return function(target, _context) { | ||
| if ("isolated" in options && options.isolated) target[BLAC_STATIC_PROPS.ISOLATED] = true; | ||
| if ("keepAlive" in options && options.keepAlive) target[BLAC_STATIC_PROPS.KEEP_ALIVE] = true; | ||
| if ("excludeFromDevTools" in options && options.excludeFromDevTools) target[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true; | ||
| return target; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { AuthVertex, BLAC_DEFAULTS, BLAC_ERROR_PREFIX, BLAC_ID_PATTERNS, BLAC_STATIC_PROPS, CounterCubit, CounterVertex, Cubit, DecrementEvent, ExternalDependencyManager, IncrementEvent, LogLevel, LoginEvent, LogoutEvent, PluginManager, ResetEvent, StateContainer, StateContainerRegistry, TodoCubit, Vertex, __resetIdCounters, blac, captureTrackedPaths, clearActiveTracker, clearExternalDependencies, commitTrackedGetters, configureLogger, createArrayProxy, createAutoTrackSnapshot, createAutoTrackSubscribe, createBlocProxy, createGetterTracker, createIdGenerator, createLogger, createManualDepsSnapshot, createManualDepsSubscribe, createNoTrackSnapshot, createNoTrackSubscribe, createPluginManager, createProxy, createProxyForTarget, createProxyInternal, createProxyTrackerState, createTrackerState, debug, disableGetterTracking, error, generateId, generateIsolatedKey, generateSimpleId, getActiveTracker, getDescriptor, getGetterExecutionContext, getPluginManager, getStaticProp, getValueAtPath, globalRegistry, hasChanges, hasGetterChanges, hasInitHook, hasTrackedData, info, initAutoTrackState, initManualDepsState, initNoTrackState, invalidateRenderCache, isExcludedFromDevTools, isGetter, isIsolatedClass, isIsolatedKey, isKeepAliveClass, isProxyable, parsePath, resetGetterTracker, setActiveTracker, shallowEqual, startProxyTracking, startTracking, stopProxyTracking, warn }; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,20 +0,8 @@ | ||
| /** | ||
| * BlacPlugin - Plugin system for BlaC state management | ||
| * | ||
| * Provides a safe and powerful API for plugins to observe and interact with | ||
| * StateContainer instances without coupling to the core. | ||
| */ | ||
| import type { StateContainer } from '../core/StateContainer'; | ||
| import type { Vertex } from '../core/Vertex'; | ||
| import type { BaseEvent } from '../types/events'; | ||
| /** | ||
| * Instance metadata exposed to plugins | ||
| */ | ||
| export interface InstanceMetadata { | ||
| /** Unique instance ID */ | ||
| id: string; | ||
| /** Class name (e.g., 'CounterCubit') */ | ||
| className: string; | ||
| isDisposed: boolean; | ||
| /** Custom name if provided */ | ||
| name: string; | ||
@@ -24,34 +12,12 @@ lastStateChangeTimestamp: number; | ||
| createdAt: number; | ||
| /** Whether this is an isolated instance */ | ||
| isIsolated: boolean; | ||
| /** Call stack for state update (optional, for DevTools) */ | ||
| callstack?: string; | ||
| /** Previous state (optional, for state change events) */ | ||
| previousState?: any; | ||
| /** Current state (optional, for state change events) */ | ||
| currentState?: any; | ||
| } | ||
| /** | ||
| * Plugin context - provides safe access to BlaC internals | ||
| */ | ||
| export interface PluginContext { | ||
| /** | ||
| * Get metadata for an instance | ||
| */ | ||
| getInstanceMetadata(instance: StateContainer<any>): InstanceMetadata; | ||
| /** | ||
| * Get current state of an instance | ||
| */ | ||
| getState<S>(instance: StateContainer<S>): S; | ||
| /** | ||
| * Query all instances of a specific type | ||
| */ | ||
| queryInstances<T extends StateContainer<any>>(typeClass: new (...args: any[]) => T): T[]; | ||
| /** | ||
| * Query all registered types | ||
| */ | ||
| getAllTypes(): Array<new (...args: any[]) => StateContainer<any>>; | ||
| /** | ||
| * Get registry statistics | ||
| */ | ||
| getStats(): { | ||
@@ -63,55 +29,20 @@ registeredTypes: number; | ||
| } | ||
| /** | ||
| * Base plugin interface | ||
| */ | ||
| export interface BlacPlugin { | ||
| /** Plugin name for identification */ | ||
| readonly name: string; | ||
| /** Plugin version */ | ||
| readonly version: string; | ||
| /** | ||
| * Called when plugin is installed | ||
| * @param context - Plugin context for safe access to BlaC internals | ||
| */ | ||
| onInstall?(context: PluginContext): void; | ||
| /** | ||
| * Called when plugin is uninstalled | ||
| */ | ||
| onUninstall?(): void; | ||
| /** | ||
| * Called when a StateContainer instance is created | ||
| */ | ||
| onInstanceCreated?(instance: StateContainer<any>, context: PluginContext): void; | ||
| /** | ||
| * Called when state changes | ||
| */ | ||
| onStateChanged?<S>(instance: StateContainer<S>, previousState: S, currentState: S, callstack: string | undefined, context: PluginContext): void; | ||
| /** | ||
| * Called when an event is added (Vertex only) | ||
| */ | ||
| onEventAdded?<E extends BaseEvent>(vertex: Vertex<any, E>, event: E, context: PluginContext): void; | ||
| /** | ||
| * Called when an instance is disposed | ||
| */ | ||
| onInstanceDisposed?(instance: StateContainer<any>, context: PluginContext): void; | ||
| } | ||
| /** | ||
| * Plugin with initialization hook | ||
| */ | ||
| export interface BlacPluginWithInit extends BlacPlugin { | ||
| onInstall(context: PluginContext): void; | ||
| } | ||
| /** | ||
| * Plugin configuration options | ||
| */ | ||
| export interface PluginConfig { | ||
| /** Whether plugin is enabled */ | ||
| enabled?: boolean; | ||
| /** Environment filter (e.g., only run in development) */ | ||
| environment?: 'development' | 'production' | 'test' | 'all'; | ||
| } | ||
| /** | ||
| * Type guard for plugins with init | ||
| */ | ||
| export declare function hasInitHook(plugin: BlacPlugin): plugin is BlacPluginWithInit; | ||
| //# sourceMappingURL=BlacPlugin.d.ts.map |
@@ -1,10 +0,3 @@ | ||
| /** | ||
| * PluginManager - Manages plugins and provides plugin context | ||
| * TESTS ARE FOR AN OLDER VERSION AND NEED TO BE REWRITTEN | ||
| */ | ||
| import type { StateContainerRegistry } from '../core/StateContainerRegistry'; | ||
| import type { BlacPlugin, PluginConfig } from './BlacPlugin'; | ||
| /** | ||
| * Plugin manager for registering and coordinating plugins | ||
| */ | ||
| export declare class PluginManager { | ||
@@ -14,25 +7,7 @@ private plugins; | ||
| constructor(registry: StateContainerRegistry); | ||
| /** | ||
| * Install a plugin | ||
| */ | ||
| install(plugin: BlacPlugin, config?: PluginConfig): void; | ||
| /** | ||
| * Uninstall a plugin | ||
| */ | ||
| uninstall(pluginName: string): void; | ||
| /** | ||
| * Get installed plugin | ||
| */ | ||
| getPlugin(pluginName: string): BlacPlugin | undefined; | ||
| /** | ||
| * Get all installed plugins | ||
| */ | ||
| getAllPlugins(): BlacPlugin[]; | ||
| /** | ||
| * Check if plugin is installed | ||
| */ | ||
| hasPlugin(pluginName: string): boolean; | ||
| /** | ||
| * Clear all plugins (for testing) | ||
| */ | ||
| clear(): void; | ||
@@ -39,0 +14,0 @@ /** |
| import type { StateContainer } from '../core/StateContainer'; | ||
| export type ExtractState<T> = T extends StateContainer<infer S> ? S : never; | ||
| export type ExtractState<T> = T extends StateContainer<infer S, any> ? S : never; | ||
| export type ExtractProps<T> = T extends StateContainer<any, infer P> ? P : undefined; | ||
| export type ExtractConstructorArgs<T> = T extends new (...args: infer P) => any ? P : never[]; | ||
| export type BlocConstructor<TBloc extends StateContainer<any>> = (new (...args: any[]) => TBloc) & { | ||
| export type BlocConstructor<TBloc extends StateContainer<any, any>> = (new (...args: any[]) => TBloc) & { | ||
| resolve(instanceKey?: string, ...args: any[]): TBloc; | ||
@@ -6,0 +7,0 @@ get(instanceKey?: string): TBloc; |
+1
-1
| { | ||
| "name": "@blac/core", | ||
| "version": "2.0.0-rc.9", | ||
| "version": "2.0.0-rc.10", | ||
| "license": "MIT", | ||
@@ -5,0 +5,0 @@ "author": "Brendan Mullins <jsnanigans@gmail.com>", |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
33
6.45%16
-11.11%160739
-10.01%4706
-14.01%