@blac/core 2.0.6 → 2.0.7

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 (46) hide show
  1. package/README.md +2 -5
  2. package/dist/{StateContainerRegistry-CVPTMaHn.cjs → StateContainerRegistry-COxgpYAw.cjs} +6 -34
  3. package/dist/StateContainerRegistry-COxgpYAw.cjs.map +1 -0
  4. package/dist/{StateContainerRegistry-Brmferpf.js → StateContainerRegistry-DS_wyKck.js} +7 -29
  5. package/dist/StateContainerRegistry-DS_wyKck.js.map +1 -0
  6. package/dist/{config-BmFnPVM0.js → config-BD9MkJ0k.js} +4 -4
  7. package/dist/{config-BmFnPVM0.js.map → config-BD9MkJ0k.js.map} +1 -1
  8. package/dist/{config-BInS_9WT.cjs → config-DTuCbHcJ.cjs} +4 -4
  9. package/dist/{config-BInS_9WT.cjs.map → config-DTuCbHcJ.cjs.map} +1 -1
  10. package/dist/constants.d.cts +0 -8
  11. package/dist/constants.d.ts +0 -8
  12. package/dist/core/Cubit.d.ts +0 -17
  13. package/dist/core/StateContainer.d.ts +12 -113
  14. package/dist/core/StateContainerRegistry.d.ts +2 -3
  15. package/dist/core/symbols.d.ts +2 -0
  16. package/dist/debug.cjs +2 -2
  17. package/dist/debug.js +2 -2
  18. package/dist/decorators/blac.d.ts +3 -10
  19. package/dist/index.cjs +54 -146
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +1 -2
  22. package/dist/index.d.ts +1 -2
  23. package/dist/index.js +53 -145
  24. package/dist/index.js.map +1 -1
  25. package/dist/plugin/BlacPlugin.d.ts +0 -2
  26. package/dist/plugins.cjs +1 -1
  27. package/dist/plugins.js +1 -1
  28. package/dist/registry/management.d.ts +1 -1
  29. package/dist/{resolve-dependencies-Cvq0glJF.js → resolve-dependencies-8xtWXd53.js} +2 -2
  30. package/dist/{resolve-dependencies-Cvq0glJF.js.map → resolve-dependencies-8xtWXd53.js.map} +1 -1
  31. package/dist/{resolve-dependencies-B22YjFGk.cjs → resolve-dependencies-DJ2UBTq1.cjs} +2 -2
  32. package/dist/{resolve-dependencies-B22YjFGk.cjs.map → resolve-dependencies-DJ2UBTq1.cjs.map} +1 -1
  33. package/dist/{tracked-I_q9buYg.js → tracked-12W-U7tq.js} +3 -3
  34. package/dist/{tracked-I_q9buYg.js.map → tracked-12W-U7tq.js.map} +1 -1
  35. package/dist/{tracked-B_MUXIpe.cjs → tracked-DLnq137F.cjs} +3 -3
  36. package/dist/{tracked-B_MUXIpe.cjs.map → tracked-DLnq137F.cjs.map} +1 -1
  37. package/dist/tracking.cjs +1 -1
  38. package/dist/tracking.js +1 -1
  39. package/dist/types/utilities.d.ts +0 -1
  40. package/dist/utils/idGenerator.d.ts +0 -16
  41. package/dist/utils/static-props.d.ts +0 -7
  42. package/dist/watch-entry.cjs +1 -1
  43. package/dist/watch-entry.js +1 -1
  44. package/package.json +2 -1
  45. package/dist/StateContainerRegistry-Brmferpf.js.map +0 -1
  46. package/dist/StateContainerRegistry-CVPTMaHn.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BLAC_DEFAULTS","globalRegistry","globalRegistry","globalRegistry","BLAC_STATIC_PROPS"],"sources":["../src/utils/idGenerator.ts","../src/core/StateContainer.ts","../src/core/Cubit.ts","../src/registry/acquire.ts","../src/registry/borrow.ts","../src/registry/release.ts","../src/decorators/blac.ts"],"sourcesContent":["/**\n * Centralized ID Generation\n *\n * Provides consistent, collision-resistant ID generation for all BlaC subsystems.\n * Uses timestamp + counter + random suffix for uniqueness.\n */\n\n// Global counter map for ID generation\nconst globalCounters = new Map<string, number>();\n\n/**\n * Creates an ID generator with isolated counter state\n *\n * @param prefix - Prefix for generated IDs\n * @returns Object with next(), nextSimple(), and reset() methods\n *\n * @example\n * ```ts\n * const generator = createIdGenerator('sub');\n * const id1 = generator.next(); // \"sub:1698765432100_1_a3k9d7f2q\"\n * const id2 = generator.next(); // \"sub:1698765432101_2_b4n8e9g3r\"\n * ```\n */\nexport function createIdGenerator(prefix: string) {\n let counter = 0;\n return {\n next: () =>\n `${prefix}:${Date.now()}_${++counter}_${Math.random().toString(36).substring(2, 11)}`,\n nextSimple: () => `${prefix}:${++counter}`,\n reset: () => {\n counter = 0;\n },\n };\n}\n\n/**\n * Generate ID with timestamp, counter, and random suffix (tree-shakeable)\n *\n * Format: `${prefix}:${timestamp}_${counter}_${random}`\n *\n * @param prefix - Prefix for the ID (e.g., 'sub', 'consumer', 'stage')\n * @returns Branded ID string\n *\n * @example\n * const id = generateId('sub');\n * // Returns: \"sub:1698765432100_1_a3k9d7f2q\"\n */\nexport function generateId(prefix: string): string {\n const counter = (globalCounters.get(prefix) ?? 0) + 1;\n globalCounters.set(prefix, counter);\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return `${prefix}:${timestamp}_${counter}_${random}`;\n}\n\n/**\n * Generate simple ID with timestamp and random (no counter tracking)\n *\n * Format: `${prefix}:${timestamp}_${random}`\n *\n * @param prefix - Prefix for the ID\n * @returns Branded ID string\n *\n * @example\n * ```ts\n * const id = generateSimpleId('CounterBloc');\n * // Returns: \"CounterBloc:1698765432100_a3k9d7f2q\"\n * ```\n */\nexport function generateSimpleId(prefix: string, affix?: string): string {\n if (affix) {\n return `${prefix}:${affix}`;\n }\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return `${prefix}:${timestamp}_${random}`;\n}\n\n/**\n * Reset all counters for testing purposes\n * @internal\n */\nexport function __resetIdCounters(): void {\n globalCounters.clear();\n}\n\n/**\n * Generate a unique isolated instance key\n * Uses base36 encoding for compact, URL-safe identifiers\n *\n * Format: \"isolated-{9-char-random-string}\"\n * Example: \"isolated-k7x2m9p4q\"\n *\n * @returns A unique isolated instance key\n */\nexport function generateIsolatedKey(): string {\n const randomPart = Math.random().toString(36).slice(2, 11);\n return `isolated-${randomPart}`;\n}\n\n/**\n * Check if a key is an isolated instance key\n * @param key - The instance key to check\n * @returns true if the key is an isolated instance key\n */\nexport function isIsolatedKey(key: string): boolean {\n return key.startsWith('isolated-');\n}\n","import { generateSimpleId } from '../utils/idGenerator';\nimport { BLAC_DEFAULTS } from '../constants';\nimport { globalRegistry } from './StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\n/**\n * Configuration options for initializing a StateContainer instance\n */\nexport interface StateContainerConfig {\n /** Display name for the instance (defaults to class name) */\n name?: string;\n /** Enable debug logging for this instance */\n debug?: boolean;\n /** Custom instance identifier */\n instanceId?: string;\n}\n\nexport type HydrationStatus = 'idle' | 'hydrating' | 'hydrated' | 'error';\n\n/**\n * Listener function for state changes\n * @internal\n */\ntype StateListener<S> = (state: S) => void;\n\n/**\n * System events emitted by StateContainer lifecycle\n */\nexport type SystemEvent = 'stateChanged' | 'dispose' | 'hydrationChanged';\n\n/**\n * Payload types for each system event\n * @template S - State type\n */\nexport interface SystemEventPayloads<S> {\n /** Emitted when state changes via emit() or update() */\n stateChanged: { state: S; previousState: S };\n /** Emitted when the instance is disposed */\n dispose: void;\n /** Emitted when hydration status changes */\n hydrationChanged: {\n status: HydrationStatus;\n previousStatus: HydrationStatus;\n error?: Error;\n changedWhileHydrating: boolean;\n };\n}\n\n/**\n * Handler function for system events\n * @internal\n */\ntype SystemEventHandler<S, E extends SystemEvent> = (\n payload: SystemEventPayloads<S>[E],\n) => void;\n\nconst EMPTY_DEPS: ReadonlyMap<any, any> = new Map();\n\n/**\n * Abstract base class for all state containers in BlaC.\n * Provides lifecycle management, subscription handling, ref counting,\n * and integration with the global registry.\n *\n * @template S - State type managed by this container\n *\n * @example\n * ```ts\n * class CounterBloc extends StateContainer<{ count: number }> {\n * constructor() {\n * super({ count: 0 });\n * }\n * increment() {\n * this.emit({ count: this.state.count + 1 });\n * }\n * }\n * ```\n */\nexport abstract class StateContainer<S extends object = any> {\n static __excludeFromDevTools = false;\n static enableStackTrace = true;\n\n private _state: S;\n private readonly listeners = new Set<StateListener<S>>();\n private _disposed = false;\n private _hydrationStatus: HydrationStatus = 'idle';\n private _hydrationError?: Error;\n private _changedWhileHydrating = false;\n private hydrationPromise: Promise<void> | null = null;\n private resolveHydrationPromise?: () => void;\n private rejectHydrationPromise?: (error: Error) => void;\n private hydrationPromiseSettled = false;\n private config: StateContainerConfig = {};\n private readonly systemEventHandlers = new Map<\n SystemEvent,\n Set<SystemEventHandler<S, any>>\n >();\n\n /** Display name for this instance */\n name: string = this.constructor.name;\n /** Whether debug logging is enabled */\n debug: boolean = false;\n /** Unique identifier for this instance */\n instanceId: string = generateSimpleId(this.constructor.name, 'main');\n /** Timestamp when this instance was created */\n createdAt: number = Date.now();\n\n private _dependencies: Map<StateContainerConstructor, string> | null = null;\n\n get dependencies(): ReadonlyMap<StateContainerConstructor, string> {\n return this._dependencies ?? EMPTY_DEPS;\n }\n\n protected depend<T extends StateContainerConstructor>(\n Type: T,\n instanceKey?: string,\n ): () => InstanceType<T> {\n if (!this._dependencies) {\n this._dependencies = new Map();\n }\n this._dependencies.set(\n Type,\n instanceKey ?? BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY,\n );\n return () => globalRegistry.ensure(Type, instanceKey);\n }\n\n constructor(initialState: S) {\n this._state = initialState;\n }\n\n /**\n * Initialize configuration for this instance.\n * Called by the registry after construction.\n * @param config - Configuration options\n */\n initConfig(config: StateContainerConfig): void {\n this.config = { ...config };\n this.name = this.config.name || this.constructor.name;\n this.debug = this.config.debug ?? false;\n this.instanceId = generateSimpleId(\n this.constructor.name,\n this.config.instanceId,\n );\n\n globalRegistry.emit('created', this);\n }\n\n /** Current state value */\n get state(): Readonly<S> {\n return this._state;\n }\n\n /** Whether this instance has been disposed */\n get isDisposed(): boolean {\n return this._disposed;\n }\n\n /** Current hydration status for this instance */\n get hydrationStatus(): HydrationStatus {\n return this._hydrationStatus;\n }\n\n /** Error from the latest failed hydration, if any */\n get hydrationError(): Error | undefined {\n return this._hydrationError;\n }\n\n /** Whether this instance has completed hydration successfully */\n get isHydrated(): boolean {\n return this._hydrationStatus === 'hydrated';\n }\n\n /** Whether user state changes happened while hydration was pending */\n get changedWhileHydrating(): boolean {\n return this._changedWhileHydrating;\n }\n\n /**\n * Subscribe to state changes\n * @param listener - Function called when state changes\n * @returns Unsubscribe function\n */\n subscribe(listener: StateListener<S>): () => void {\n if (this._disposed) {\n throw new Error(`Cannot subscribe to disposed container ${this.name}`);\n }\n\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Dispose this instance and clean up resources.\n * Clears all listeners and emits the 'dispose' system event.\n */\n dispose(): void {\n if (this._disposed) return;\n\n if (this.debug) {\n console.log(`[${this.name}] Disposing...`);\n }\n\n this._disposed = true;\n\n if (this._hydrationStatus === 'hydrating') {\n this.failHydration(\n new Error(`Hydration cancelled because ${this.name} was disposed`),\n );\n }\n\n this.emitSystemEvent('dispose', undefined as void);\n\n this.listeners.clear();\n this.systemEventHandlers.clear();\n\n globalRegistry.emit('disposed', this);\n\n if (this.debug) {\n console.log(`[${this.name}] Disposed successfully`);\n }\n }\n\n /**\n * Emit a new state value and notify all listeners.\n * @param newState - The new state value\n * @protected\n */\n protected emit(newState: S): void {\n this.applyState(newState, 'default');\n }\n\n /**\n * Mark this instance as hydrating. Plugins should call this before starting\n * asynchronous rehydration work.\n */\n beginHydration(): void {\n if (this._disposed) {\n throw new Error(\n `Cannot begin hydration for disposed container ${this.name}`,\n );\n }\n\n this._changedWhileHydrating = false;\n this._hydrationError = undefined;\n this.hydrationPromise = null;\n this.resolveHydrationPromise = undefined;\n this.rejectHydrationPromise = undefined;\n this.hydrationPromiseSettled = false;\n this.ensureHydrationPromise();\n this.setHydrationStatus('hydrating');\n }\n\n /**\n * Apply hydrated state if no user writes happened since hydration started.\n * Returns false when hydration should be skipped.\n */\n applyHydratedState(newState: S): boolean {\n if (this._disposed) {\n return false;\n }\n\n if (this._hydrationStatus !== 'hydrating' || this._changedWhileHydrating) {\n return false;\n }\n\n this.applyState(newState, 'hydration');\n return true;\n }\n\n /**\n * Mark hydration as completed.\n */\n finishHydration(): void {\n if (this._hydrationStatus !== 'hydrating') {\n if (this._hydrationStatus === 'hydrated') {\n return;\n }\n if (this._hydrationStatus === 'error') {\n this.ensureHydrationPromise();\n }\n }\n\n this.setHydrationStatus('hydrated');\n this.resolveHydration();\n }\n\n /**\n * Mark hydration as failed.\n */\n failHydration(error: Error): void {\n const err =\n error instanceof Error ? error : new Error(`Hydration failed: ${error}`);\n\n this._hydrationError = err;\n this.setHydrationStatus('error', err);\n this.rejectHydration(err);\n }\n\n /**\n * Wait until the current hydration cycle finishes.\n */\n waitForHydration(): Promise<void> {\n if (this._hydrationStatus === 'idle' || this._hydrationStatus === 'hydrated') {\n return Promise.resolve();\n }\n\n if (this._hydrationStatus === 'error') {\n return Promise.reject(\n this._hydrationError ??\n new Error(`Hydration failed for container ${this.name}`),\n );\n }\n\n return this.ensureHydrationPromise();\n }\n\n private captureStackTrace(): string {\n if (\n !StateContainer.enableStackTrace ||\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production')\n ) {\n return '';\n }\n\n try {\n const error = new Error();\n const stack = error.stack || '';\n const lines = stack.split('\\n');\n const relevantLines = lines.slice(1);\n const formattedLines: string[] = [];\n\n for (const line of relevantLines) {\n if (!line.trim()) continue;\n\n if (\n line.includes('StateContainer.emit') ||\n line.includes('StateContainer.update') ||\n line.includes('StateContainer.captureStackTrace') ||\n line.includes('Cubit.patch')\n ) {\n continue;\n }\n\n if (\n line.includes('node_modules') ||\n line.includes('react-dom') ||\n line.includes('react_jsx') ||\n line.includes('.vite/deps') ||\n line.includes('executeDispatch') ||\n line.includes('runWithFiber') ||\n line.includes('invokeGuarded') ||\n line.includes('callCallback') ||\n line.includes('processDispatchQueue') ||\n line.includes('dispatchEvent') ||\n line.includes('batchedUpdates')\n ) {\n continue;\n }\n\n const formatted = this.formatStackLine(line);\n if (formatted) {\n formattedLines.push(formatted);\n }\n }\n\n return formattedLines.join('\\n');\n } catch {\n return '';\n }\n }\n\n private formatStackLine(line: string): string | null {\n const match = line.match(/at\\s+(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)/);\n if (!match) {\n const simpleMatch = line.match(/at\\s+(.+?):(\\d+):(\\d+)/);\n if (simpleMatch) {\n const [, url, lineNum, col] = simpleMatch;\n const cleanPath = this.cleanFilePath(url);\n return ` at ${cleanPath}:${lineNum}:${col}`;\n }\n return null;\n }\n\n const [, functionName, url, lineNum, col] = match;\n const cleanPath = this.cleanFilePath(url);\n\n return ` at ${functionName} (${cleanPath}:${lineNum}:${col})`;\n }\n\n private cleanFilePath(url: string): string {\n let path = url\n .replace(/http:\\/\\/localhost:\\d+\\/@fs/, '')\n .replace(/http:\\/\\/localhost:\\d+\\//, '')\n .replace(/\\?t=\\d+/, '')\n .replace(/\\?v=[a-f0-9]+/, '');\n\n const projectMatch = path.match(/\\/Projects\\/blac\\/(.+)/);\n if (projectMatch) {\n path = projectMatch[1];\n }\n\n const segments = path.split('/');\n if (segments.length > 3) {\n path = segments.slice(-3).join('/');\n }\n\n return path;\n }\n\n /** Timestamp of the last state update */\n lastUpdateTimestamp: number = Date.now();\n\n /**\n * Update state using a transform function.\n * @param updater - Function that receives current state and returns new state\n * @protected\n */\n protected update(updater: (current: S) => S): void {\n if (this._disposed) {\n throw new Error(\n `Cannot update state from disposed container ${this.name}`,\n );\n }\n this.emit(updater(this._state));\n }\n\n private applyState(newState: S, source: 'default' | 'hydration'): void {\n if (this._disposed) {\n throw new Error(`Cannot emit state from disposed container ${this.name}`);\n }\n\n if (this._state === newState) return;\n\n if (this._hydrationStatus === 'hydrating' && source !== 'hydration') {\n this._changedWhileHydrating = true;\n }\n\n const previousState = this._state;\n this._state = newState;\n\n this.emitSystemEvent('stateChanged', {\n state: newState,\n previousState,\n });\n\n const listeners = Array.from(this.listeners);\n for (const listener of listeners) {\n try {\n listener(newState);\n } catch (error) {\n console.error(`[${this.name}] Error in listener:`, error);\n }\n }\n\n const stackTrace = this.captureStackTrace();\n\n globalRegistry.emit(\n 'stateChanged',\n this,\n previousState,\n newState,\n stackTrace,\n );\n this.lastUpdateTimestamp = Date.now();\n }\n\n private setHydrationStatus(status: HydrationStatus, error?: Error): void {\n const previousStatus = this._hydrationStatus;\n this._hydrationStatus = status;\n this._hydrationError = error;\n\n this.emitSystemEvent('hydrationChanged', {\n status,\n previousStatus,\n error,\n changedWhileHydrating: this._changedWhileHydrating,\n });\n }\n\n private ensureHydrationPromise(): Promise<void> {\n if (!this.hydrationPromise || this.hydrationPromiseSettled) {\n this.hydrationPromiseSettled = false;\n this.hydrationPromise = new Promise<void>((resolve, reject) => {\n this.resolveHydrationPromise = () => {\n if (this.hydrationPromiseSettled) return;\n this.hydrationPromiseSettled = true;\n resolve();\n };\n this.rejectHydrationPromise = (error: Error) => {\n if (this.hydrationPromiseSettled) return;\n this.hydrationPromiseSettled = true;\n reject(error);\n };\n });\n this.hydrationPromise.catch(() => {});\n }\n\n return this.hydrationPromise;\n }\n\n private resolveHydration(): void {\n this.resolveHydrationPromise?.();\n }\n\n private rejectHydration(error: Error): void {\n this.ensureHydrationPromise();\n this.rejectHydrationPromise?.(error);\n }\n\n /**\n * Subscribe to system lifecycle events.\n * @param event - The event type to listen for\n * @param handler - Handler function called when event occurs\n * @returns Unsubscribe function\n * @protected\n */\n protected onSystemEvent = <E extends SystemEvent>(\n event: E,\n handler: SystemEventHandler<S, E>,\n ): (() => void) => {\n let handlers = this.systemEventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.systemEventHandlers.set(event, handlers);\n }\n handlers.add(handler as SystemEventHandler<S, any>);\n\n return () => {\n handlers?.delete(handler as SystemEventHandler<S, any>);\n };\n };\n\n private emitSystemEvent<E extends SystemEvent>(\n event: E,\n payload: SystemEventPayloads<S>[E],\n ): void {\n const handlers = this.systemEventHandlers.get(event);\n if (!handlers) return;\n\n for (const handler of handlers) {\n try {\n handler(payload);\n } catch (error) {\n console.error(`[${this.name}] Error in system event handler:`, error);\n }\n }\n }\n}\n","import { StateContainer } from './StateContainer';\n\n/**\n * Simple state container with direct state emission.\n * Extends StateContainer with public methods for emitting and updating state.\n *\n * @template S - State type\n */\nexport abstract class Cubit<S extends object = any> extends StateContainer<S> {\n constructor(initialState: S) {\n super(initialState);\n }\n\n /**\n * Replace state with a new value and notify all listeners\n * @param newState - The new state value\n */\n public emit(newState: S): void {\n super['emit'](newState);\n }\n\n /**\n * Transform current state using an updater function and emit the new state\n * @param updater - Function that receives current state and returns new state\n */\n public update(updater: (current: S) => S): void {\n super['update'](updater);\n }\n\n /**\n * Merge partial state changes into current state (only for object states)\n */\n public patch = ((partial: S extends object ? Partial<S> : never): void => {\n if (typeof this.state !== 'object' || this.state === null) {\n throw new Error('patch() is only available for object state types');\n }\n const current = this.state;\n let hasChanges = false;\n for (const key in partial) {\n if (!Object.is((current as any)[key], (partial as any)[key])) {\n hasChanges = true;\n break;\n }\n }\n if (hasChanges) {\n this.update((c) => ({ ...c, ...partial }) as S);\n }\n }) as S extends object ? (partial: Partial<S>) => void : never;\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function acquire<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n): InstanceType<T> {\n return globalRegistry.acquire(BlocClass, instanceKey, {\n canCreate: true,\n countRef: true,\n });\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function borrow<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n): InstanceType<T> {\n return globalRegistry.borrow(BlocClass, instanceKey);\n}\n\nexport function borrowSafe<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n):\n | { error: Error; instance: null }\n | { error: null; instance: InstanceType<T> } {\n return globalRegistry.borrowSafe(BlocClass, instanceKey);\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function release<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n forceDispose = false,\n): void {\n globalRegistry.release(BlocClass, instanceKey, forceDispose);\n}\n","import { BLAC_STATIC_PROPS } from '../constants';\n\n/**\n * Configuration options for the @blac decorator.\n * Only one option can be specified at a time (union type).\n */\nexport type BlacOptions =\n /** Mark bloc as isolated (each component gets its own instance) */\n | { isolated: true }\n /** Mark bloc to never be auto-disposed when ref count reaches 0 */\n | { keepAlive: true }\n /** Exclude bloc from DevTools tracking (prevents infinite loops) */\n | { excludeFromDevTools: true };\n\n/**\n * Decorator to configure StateContainer classes.\n *\n * @example Decorator syntax (requires experimentalDecorators or TC39 decorators)\n * ```ts\n * @blac({ isolated: true })\n * class FormBloc extends Cubit<FormState> {}\n *\n * @blac({ keepAlive: true })\n * class AuthBloc extends Cubit<AuthState> {}\n *\n * @blac({ excludeFromDevTools: true })\n * class InternalBloc extends Cubit<InternalState> {}\n * ```\n *\n * @example Function syntax (no decorator support needed)\n * ```ts\n * const FormBloc = blac({ isolated: true })(\n * class extends Cubit<FormState> {}\n * );\n * ```\n */\nexport function blac(options: BlacOptions) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n _context?: ClassDecoratorContext,\n ): T {\n if ('isolated' in options && options.isolated) {\n (target as any)[BLAC_STATIC_PROPS.ISOLATED] = true;\n }\n if ('keepAlive' in options && options.keepAlive) {\n (target as any)[BLAC_STATIC_PROPS.KEEP_ALIVE] = true;\n }\n if ('excludeFromDevTools' in options && options.excludeFromDevTools) {\n (target as any)[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;\n }\n return target;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["BLAC_DEFAULTS","globalRegistry","globalRegistry","globalRegistry","BLAC_STATIC_PROPS"],"sources":["../src/utils/idGenerator.ts","../src/core/symbols.ts","../src/core/StateContainer.ts","../src/core/Cubit.ts","../src/registry/acquire.ts","../src/registry/borrow.ts","../src/registry/release.ts","../src/decorators/blac.ts"],"sourcesContent":["/**\n * Centralized ID Generation\n *\n * Provides consistent, collision-resistant ID generation for all BlaC subsystems.\n * Uses timestamp + counter + random suffix for uniqueness.\n */\n\n// Global counter map for ID generation\nconst globalCounters = new Map<string, number>();\n\n/**\n * Creates an ID generator with isolated counter state\n *\n * @param prefix - Prefix for generated IDs\n * @returns Object with next(), nextSimple(), and reset() methods\n *\n * @example\n * ```ts\n * const generator = createIdGenerator('sub');\n * const id1 = generator.next(); // \"sub:1698765432100_1_a3k9d7f2q\"\n * const id2 = generator.next(); // \"sub:1698765432101_2_b4n8e9g3r\"\n * ```\n */\nexport function createIdGenerator(prefix: string) {\n let counter = 0;\n return {\n next: () =>\n `${prefix}:${Date.now()}_${++counter}_${Math.random().toString(36).substring(2, 11)}`,\n nextSimple: () => `${prefix}:${++counter}`,\n reset: () => {\n counter = 0;\n },\n };\n}\n\n/**\n * Generate ID with timestamp, counter, and random suffix (tree-shakeable)\n *\n * Format: `${prefix}:${timestamp}_${counter}_${random}`\n *\n * @param prefix - Prefix for the ID (e.g., 'sub', 'consumer', 'stage')\n * @returns Branded ID string\n *\n * @example\n * const id = generateId('sub');\n * // Returns: \"sub:1698765432100_1_a3k9d7f2q\"\n */\nexport function generateId(prefix: string): string {\n const counter = (globalCounters.get(prefix) ?? 0) + 1;\n globalCounters.set(prefix, counter);\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return `${prefix}:${timestamp}_${counter}_${random}`;\n}\n\n/**\n * Generate simple ID with timestamp and random (no counter tracking)\n *\n * Format: `${prefix}:${timestamp}_${random}`\n *\n * @param prefix - Prefix for the ID\n * @returns Branded ID string\n *\n * @example\n * ```ts\n * const id = generateSimpleId('CounterBloc');\n * // Returns: \"CounterBloc:1698765432100_a3k9d7f2q\"\n * ```\n */\nexport function generateSimpleId(prefix: string, affix?: string): string {\n if (affix) {\n return `${prefix}:${affix}`;\n }\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return `${prefix}:${timestamp}_${random}`;\n}\n\n/**\n * Reset all counters for testing purposes\n * @internal\n */\nexport function __resetIdCounters(): void {\n globalCounters.clear();\n}\n","export const EMIT = Symbol('blac.emit');\nexport const UPDATE = Symbol('blac.update');\n","import { generateSimpleId } from '../utils/idGenerator';\nimport { BLAC_DEFAULTS } from '../constants';\nimport { globalRegistry } from './StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\nimport { EMIT, UPDATE } from './symbols';\n\nexport interface StateContainerConfig {\n name?: string;\n debug?: boolean;\n instanceId?: string;\n}\n\nexport type HydrationStatus = 'idle' | 'hydrating' | 'hydrated' | 'error';\n\ntype StateListener<S> = (state: S) => void;\n\nexport type SystemEvent = 'stateChanged' | 'dispose' | 'hydrationChanged';\n\nexport interface SystemEventPayloads<S> {\n stateChanged: { state: S; previousState: S };\n dispose: void;\n hydrationChanged: {\n status: HydrationStatus;\n previousStatus: HydrationStatus;\n error?: Error;\n changedWhileHydrating: boolean;\n };\n}\n\ntype SystemEventHandler<S, E extends SystemEvent> = (\n payload: SystemEventPayloads<S>[E],\n) => void;\n\nconst EMPTY_DEPS: ReadonlyMap<any, any> = new Map();\n\nexport abstract class StateContainer<S extends object = any> {\n static __excludeFromDevTools = false;\n static enableStackTrace = true;\n\n private _state: S;\n private readonly _listeners = new Set<StateListener<S>>();\n private _disposed = false;\n private _hydrationStatus: HydrationStatus = 'idle';\n private _hydrationError?: Error;\n private _changedWhileHydrating = false;\n private _hydrationPromise: Promise<void> | null = null;\n private _resolveHydrationPromise?: () => void;\n private _rejectHydrationPromise?: (error: Error) => void;\n private _hydrationPromiseSettled = false;\n private _config: StateContainerConfig = {};\n private readonly _systemEventHandlers = new Map<\n SystemEvent,\n Set<SystemEventHandler<S, any>>\n >();\n private _dependencies: Map<StateContainerConstructor, string> | null = null;\n\n name: string = this.constructor.name;\n debug: boolean = false;\n instanceId: string = generateSimpleId(this.constructor.name, 'main');\n createdAt: number = Date.now();\n lastUpdateTimestamp: number = Date.now();\n\n get dependencies(): ReadonlyMap<StateContainerConstructor, string> {\n return this._dependencies ?? EMPTY_DEPS;\n }\n\n protected depend<T extends StateContainerConstructor>(\n Type: T,\n instanceKey?: string,\n ): () => InstanceType<T> {\n if (!this._dependencies) {\n this._dependencies = new Map();\n }\n this._dependencies.set(\n Type,\n instanceKey ?? BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY,\n );\n return () => globalRegistry.ensure(Type, instanceKey);\n }\n\n constructor(initialState: S) {\n this._state = initialState;\n }\n\n initConfig(config: StateContainerConfig): void {\n this._config = { ...config };\n this.name = this._config.name || this.constructor.name;\n this.debug = this._config.debug ?? false;\n this.instanceId = generateSimpleId(\n this.constructor.name,\n this._config.instanceId,\n );\n globalRegistry.emit('created', this);\n }\n\n get state(): Readonly<S> {\n return this._state;\n }\n\n get isDisposed(): boolean {\n return this._disposed;\n }\n\n get hydrationStatus(): HydrationStatus {\n return this._hydrationStatus;\n }\n\n get hydrationError(): Error | undefined {\n return this._hydrationError;\n }\n\n get isHydrated(): boolean {\n return this._hydrationStatus === 'hydrated';\n }\n\n get changedWhileHydrating(): boolean {\n return this._changedWhileHydrating;\n }\n\n subscribe(listener: StateListener<S>): () => void {\n if (this._disposed) {\n throw new Error(`Cannot subscribe to disposed container ${this.name}`);\n }\n this._listeners.add(listener);\n return () => this._listeners.delete(listener);\n }\n\n dispose(): void {\n if (this._disposed) return;\n\n if (this.debug) {\n console.log(`[${this.name}] Disposing...`);\n }\n\n this._disposed = true;\n\n if (this._hydrationStatus === 'hydrating') {\n this.failHydration(\n new Error(`Hydration cancelled because ${this.name} was disposed`),\n );\n }\n\n this.emitSystemEvent('dispose', undefined as void);\n\n this._listeners.clear();\n this._systemEventHandlers.clear();\n\n globalRegistry.emit('disposed', this);\n\n if (this.debug) {\n console.log(`[${this.name}] Disposed successfully`);\n }\n }\n\n protected [EMIT](newState: S): void {\n this.applyState(newState, 'default');\n }\n\n protected [UPDATE](updater: (current: S) => S): void {\n if (this._disposed) {\n throw new Error(\n `Cannot update state from disposed container ${this.name}`,\n );\n }\n this[EMIT](updater(this._state));\n }\n\n beginHydration(): void {\n if (this._disposed) {\n throw new Error(\n `Cannot begin hydration for disposed container ${this.name}`,\n );\n }\n\n this._changedWhileHydrating = false;\n this._hydrationError = undefined;\n this._hydrationPromise = null;\n this._resolveHydrationPromise = undefined;\n this._rejectHydrationPromise = undefined;\n this._hydrationPromiseSettled = false;\n this.ensureHydrationPromise();\n this.setHydrationStatus('hydrating');\n }\n\n applyHydratedState(newState: S): boolean {\n if (this._disposed) {\n return false;\n }\n\n if (this._hydrationStatus !== 'hydrating' || this._changedWhileHydrating) {\n return false;\n }\n\n this.applyState(newState, 'hydration');\n return true;\n }\n\n finishHydration(): void {\n if (this._hydrationStatus !== 'hydrating') {\n if (this._hydrationStatus === 'hydrated') {\n return;\n }\n if (this._hydrationStatus === 'error') {\n this.ensureHydrationPromise();\n }\n }\n\n this.setHydrationStatus('hydrated');\n this.resolveHydration();\n }\n\n failHydration(error: Error): void {\n const err =\n error instanceof Error ? error : new Error(`Hydration failed: ${error}`);\n\n this._hydrationError = err;\n this.setHydrationStatus('error', err);\n this.rejectHydration(err);\n }\n\n waitForHydration(): Promise<void> {\n if (\n this._hydrationStatus === 'idle' ||\n this._hydrationStatus === 'hydrated'\n ) {\n return Promise.resolve();\n }\n\n if (this._hydrationStatus === 'error') {\n return Promise.reject(\n this._hydrationError ??\n new Error(`Hydration failed for container ${this.name}`),\n );\n }\n\n return this.ensureHydrationPromise();\n }\n\n private captureStackTrace(): string {\n if (\n !StateContainer.enableStackTrace ||\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production')\n ) {\n return '';\n }\n\n try {\n const error = new Error();\n const stack = error.stack || '';\n const lines = stack.split('\\n');\n const relevantLines = lines.slice(1);\n const formattedLines: string[] = [];\n\n for (const line of relevantLines) {\n if (!line.trim()) continue;\n\n if (\n line.includes('StateContainer.emit') ||\n line.includes('StateContainer.update') ||\n line.includes('StateContainer.captureStackTrace') ||\n line.includes('[blac.emit]') ||\n line.includes('[blac.update]') ||\n line.includes('Cubit.patch')\n ) {\n continue;\n }\n\n if (\n line.includes('node_modules') ||\n line.includes('react-dom') ||\n line.includes('react_jsx') ||\n line.includes('.vite/deps') ||\n line.includes('executeDispatch') ||\n line.includes('runWithFiber') ||\n line.includes('invokeGuarded') ||\n line.includes('callCallback') ||\n line.includes('processDispatchQueue') ||\n line.includes('dispatchEvent') ||\n line.includes('batchedUpdates')\n ) {\n continue;\n }\n\n const formatted = this.formatStackLine(line);\n if (formatted) {\n formattedLines.push(formatted);\n }\n }\n\n return formattedLines.join('\\n');\n } catch {\n return '';\n }\n }\n\n private formatStackLine(line: string): string | null {\n const match = line.match(/at\\s+(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)/);\n if (!match) {\n const simpleMatch = line.match(/at\\s+(.+?):(\\d+):(\\d+)/);\n if (simpleMatch) {\n const [, url, lineNum, col] = simpleMatch;\n const cleanPath = this.cleanFilePath(url);\n return ` at ${cleanPath}:${lineNum}:${col}`;\n }\n return null;\n }\n\n const [, functionName, url, lineNum, col] = match;\n const cleanPath = this.cleanFilePath(url);\n\n return ` at ${functionName} (${cleanPath}:${lineNum}:${col})`;\n }\n\n private cleanFilePath(url: string): string {\n let path = url\n .replace(/http:\\/\\/localhost:\\d+\\/@fs/, '')\n .replace(/http:\\/\\/localhost:\\d+\\//, '')\n .replace(/\\?t=\\d+/, '')\n .replace(/\\?v=[a-f0-9]+/, '');\n\n const projectMatch = path.match(/\\/Projects\\/blac\\/(.+)/);\n if (projectMatch) {\n path = projectMatch[1];\n }\n\n const segments = path.split('/');\n if (segments.length > 3) {\n path = segments.slice(-3).join('/');\n }\n\n return path;\n }\n\n private applyState(newState: S, source: 'default' | 'hydration'): void {\n if (this._disposed) {\n throw new Error(`Cannot emit state from disposed container ${this.name}`);\n }\n\n if (this._state === newState) return;\n\n if (this._hydrationStatus === 'hydrating' && source !== 'hydration') {\n this._changedWhileHydrating = true;\n }\n\n const previousState = this._state;\n this._state = newState;\n\n this.emitSystemEvent('stateChanged', {\n state: newState,\n previousState,\n });\n\n const listeners = Array.from(this._listeners);\n for (const listener of listeners) {\n try {\n listener(newState);\n } catch (error) {\n console.error(`[${this.name}] Error in listener:`, error);\n }\n }\n\n const stackTrace = this.captureStackTrace();\n\n globalRegistry.emit(\n 'stateChanged',\n this,\n previousState,\n newState,\n stackTrace,\n );\n this.lastUpdateTimestamp = Date.now();\n }\n\n private setHydrationStatus(status: HydrationStatus, error?: Error): void {\n const previousStatus = this._hydrationStatus;\n this._hydrationStatus = status;\n this._hydrationError = error;\n\n this.emitSystemEvent('hydrationChanged', {\n status,\n previousStatus,\n error,\n changedWhileHydrating: this._changedWhileHydrating,\n });\n }\n\n private ensureHydrationPromise(): Promise<void> {\n if (!this._hydrationPromise || this._hydrationPromiseSettled) {\n this._hydrationPromiseSettled = false;\n this._hydrationPromise = new Promise<void>((resolve, reject) => {\n this._resolveHydrationPromise = () => {\n if (this._hydrationPromiseSettled) return;\n this._hydrationPromiseSettled = true;\n resolve();\n };\n this._rejectHydrationPromise = (error: Error) => {\n if (this._hydrationPromiseSettled) return;\n this._hydrationPromiseSettled = true;\n reject(error);\n };\n });\n this._hydrationPromise.catch(() => {});\n }\n\n return this._hydrationPromise;\n }\n\n private resolveHydration(): void {\n this._resolveHydrationPromise?.();\n }\n\n private rejectHydration(error: Error): void {\n this.ensureHydrationPromise();\n this._rejectHydrationPromise?.(error);\n }\n\n protected onSystemEvent = <E extends SystemEvent>(\n event: E,\n handler: SystemEventHandler<S, E>,\n ): (() => void) => {\n let handlers = this._systemEventHandlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this._systemEventHandlers.set(event, handlers);\n }\n handlers.add(handler as SystemEventHandler<S, any>);\n\n return () => {\n handlers?.delete(handler as SystemEventHandler<S, any>);\n };\n };\n\n private emitSystemEvent<E extends SystemEvent>(\n event: E,\n payload: SystemEventPayloads<S>[E],\n ): void {\n const handlers = this._systemEventHandlers.get(event);\n if (!handlers) return;\n\n for (const handler of handlers) {\n try {\n handler(payload);\n } catch (error) {\n console.error(`[${this.name}] Error in system event handler:`, error);\n }\n }\n }\n}\n","import { StateContainer } from './StateContainer';\nimport { EMIT, UPDATE } from './symbols';\n\nexport abstract class Cubit<S extends object = any> extends StateContainer<S> {\n constructor(initialState: S) {\n super(initialState);\n }\n\n public emit(newState: S): void {\n this[EMIT](newState);\n }\n\n public update(updater: (current: S) => S): void {\n this[UPDATE](updater);\n }\n\n public patch = ((partial: S extends object ? Partial<S> : never): void => {\n if (typeof this.state !== 'object' || this.state === null) {\n throw new Error('patch() is only available for object state types');\n }\n const current = this.state;\n let hasChanges = false;\n for (const key in partial) {\n if (!Object.is((current as any)[key], (partial as any)[key])) {\n hasChanges = true;\n break;\n }\n }\n if (hasChanges) {\n this.update((c) => ({ ...c, ...partial }) as S);\n }\n }) as S extends object ? (partial: Partial<S>) => void : never;\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function acquire<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n): InstanceType<T> {\n return globalRegistry.acquire(BlocClass, instanceKey, {\n canCreate: true,\n countRef: true,\n });\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function borrow<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n): InstanceType<T> {\n return globalRegistry.borrow(BlocClass, instanceKey);\n}\n\nexport function borrowSafe<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n):\n | { error: Error; instance: null }\n | { error: null; instance: InstanceType<T> } {\n return globalRegistry.borrowSafe(BlocClass, instanceKey);\n}\n","import { globalRegistry } from '../core/StateContainerRegistry';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function release<T extends StateContainerConstructor>(\n BlocClass: T,\n instanceKey?: string,\n forceDispose = false,\n): void {\n globalRegistry.release(BlocClass, instanceKey, forceDispose);\n}\n","import { BLAC_STATIC_PROPS } from '../constants';\n\n/**\n * Configuration options for the @blac decorator.\n * Only one option can be specified at a time (union type).\n */\nexport type BlacOptions =\n /** Mark bloc to never be auto-disposed when ref count reaches 0 */\n | { keepAlive: true }\n /** Exclude bloc from DevTools tracking (prevents infinite loops) */\n | { excludeFromDevTools: true };\n\n/**\n * Decorator to configure StateContainer classes.\n *\n * @example Decorator syntax (requires experimentalDecorators or TC39 decorators)\n * ```ts\n * @blac({ keepAlive: true })\n * class AuthBloc extends Cubit<AuthState> {}\n *\n * @blac({ excludeFromDevTools: true })\n * class InternalBloc extends Cubit<InternalState> {}\n * ```\n *\n * @example Function syntax (no decorator support needed)\n * ```ts\n * const AuthBloc = blac({ keepAlive: true })(\n * class extends Cubit<AuthState> {}\n * );\n * ```\n */\nexport function blac(options: BlacOptions) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n _context?: ClassDecoratorContext,\n ): T {\n if ('keepAlive' in options && options.keepAlive) {\n (target as any)[BLAC_STATIC_PROPS.KEEP_ALIVE] = true;\n }\n if ('excludeFromDevTools' in options && options.excludeFromDevTools) {\n (target as any)[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;\n }\n return target;\n };\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { StateContainer } from './core/StateContainer';
2
2
  export type { HydrationStatus, StateContainerConfig, SystemEvent, SystemEventPayloads, } from './core/StateContainer';
3
3
  export { Cubit } from './core/Cubit';
4
+ export { EMIT, UPDATE } from './core/symbols';
4
5
  export { acquire, borrow, borrowSafe, ensure, release, clear, clearAll, register, hasInstance, getRefCount, getAll, forEach, getRegistry, setRegistry, getStats, } from './registry';
5
6
  export { globalRegistry } from './core/StateContainerRegistry';
6
7
  export type { LifecycleEvent, LifecycleListener, InstanceEntry, } from './core/StateContainerRegistry';
@@ -13,5 +14,3 @@ export { tracked, createTrackedContext, TrackedContext, type TrackedResult, type
13
14
  export type { StateContainerConstructor, ExtractState, ExtractStateMutable, ExtractConstructorArgs, BlocInstanceType, BlocConstructor, InstanceReadonlyState, InstanceState, StateContainerInstance, } from './types/utilities';
14
15
  export type { Brand, BrandedId, InstanceId } from './types/branded';
15
16
  export { instanceId } from './types/branded';
16
- export { isIsolatedClass } from './utils/static-props';
17
- export { generateIsolatedKey } from './utils/idGenerator';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { StateContainer } from './core/StateContainer';
2
2
  export type { HydrationStatus, StateContainerConfig, SystemEvent, SystemEventPayloads, } from './core/StateContainer';
3
3
  export { Cubit } from './core/Cubit';
4
+ export { EMIT, UPDATE } from './core/symbols';
4
5
  export { acquire, borrow, borrowSafe, ensure, release, clear, clearAll, register, hasInstance, getRefCount, getAll, forEach, getRegistry, setRegistry, getStats, } from './registry';
5
6
  export { globalRegistry } from './core/StateContainerRegistry';
6
7
  export type { LifecycleEvent, LifecycleListener, InstanceEntry, } from './core/StateContainerRegistry';
@@ -13,5 +14,3 @@ export { tracked, createTrackedContext, TrackedContext, type TrackedResult, type
13
14
  export type { StateContainerConstructor, ExtractState, ExtractStateMutable, ExtractConstructorArgs, BlocInstanceType, BlocConstructor, InstanceReadonlyState, InstanceState, StateContainerInstance, } from './types/utilities';
14
15
  export type { Brand, BrandedId, InstanceId } from './types/branded';
15
16
  export { instanceId } from './types/branded';
16
- export { isIsolatedClass } from './utils/static-props';
17
- export { generateIsolatedKey } from './utils/idGenerator';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { a as BLAC_DEFAULTS, i as PluginManager, n as globalRegistry, r as isIsolatedClass, s as BLAC_STATIC_PROPS, t as getPluginManager } from "./StateContainerRegistry-Brmferpf.js";
2
- import { a as watch, i as instance, n as createTrackedContext, o as ensure, r as tracked, t as TrackedContext } from "./tracked-I_q9buYg.js";
3
- import { a as clearAll, c as getAll, i as clear, l as getRefCount, n as getStats, o as register, r as setRegistry, s as forEach, t as getRegistry, u as hasInstance } from "./config-BmFnPVM0.js";
1
+ import { i as BLAC_DEFAULTS, n as globalRegistry, o as BLAC_STATIC_PROPS, r as PluginManager, t as getPluginManager } from "./StateContainerRegistry-DS_wyKck.js";
2
+ import { a as watch, i as instance, n as createTrackedContext, o as ensure, r as tracked, t as TrackedContext } from "./tracked-12W-U7tq.js";
3
+ import { a as clearAll, c as getAll, i as clear, l as getRefCount, n as getStats, o as register, r as setRegistry, s as forEach, t as getRegistry, u as hasInstance } from "./config-BD9MkJ0k.js";
4
4
  import { t as instanceId } from "./branded-mwGzzPF1.js";
5
5
  //#region src/utils/idGenerator.ts
6
6
  /**
@@ -21,40 +21,13 @@ function generateSimpleId(prefix, affix) {
21
21
  if (affix) return `${prefix}:${affix}`;
22
22
  return `${prefix}:${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
23
23
  }
24
- /**
25
- * Generate a unique isolated instance key
26
- * Uses base36 encoding for compact, URL-safe identifiers
27
- *
28
- * Format: "isolated-{9-char-random-string}"
29
- * Example: "isolated-k7x2m9p4q"
30
- *
31
- * @returns A unique isolated instance key
32
- */
33
- function generateIsolatedKey() {
34
- return `isolated-${Math.random().toString(36).slice(2, 11)}`;
35
- }
24
+ //#endregion
25
+ //#region src/core/symbols.ts
26
+ const EMIT = Symbol("blac.emit");
27
+ const UPDATE = Symbol("blac.update");
36
28
  //#endregion
37
29
  //#region src/core/StateContainer.ts
38
30
  const EMPTY_DEPS = /* @__PURE__ */ new Map();
39
- /**
40
- * Abstract base class for all state containers in BlaC.
41
- * Provides lifecycle management, subscription handling, ref counting,
42
- * and integration with the global registry.
43
- *
44
- * @template S - State type managed by this container
45
- *
46
- * @example
47
- * ```ts
48
- * class CounterBloc extends StateContainer<{ count: number }> {
49
- * constructor() {
50
- * super({ count: 0 });
51
- * }
52
- * increment() {
53
- * this.emit({ count: this.state.count + 1 });
54
- * }
55
- * }
56
- * ```
57
- */
58
31
  var StateContainer = class StateContainer {
59
32
  static {
60
33
  this.__excludeFromDevTools = false;
@@ -71,25 +44,25 @@ var StateContainer = class StateContainer {
71
44
  return () => globalRegistry.ensure(Type, instanceKey);
72
45
  }
73
46
  constructor(initialState) {
74
- this.listeners = /* @__PURE__ */ new Set();
47
+ this._listeners = /* @__PURE__ */ new Set();
75
48
  this._disposed = false;
76
49
  this._hydrationStatus = "idle";
77
50
  this._changedWhileHydrating = false;
78
- this.hydrationPromise = null;
79
- this.hydrationPromiseSettled = false;
80
- this.config = {};
81
- this.systemEventHandlers = /* @__PURE__ */ new Map();
51
+ this._hydrationPromise = null;
52
+ this._hydrationPromiseSettled = false;
53
+ this._config = {};
54
+ this._systemEventHandlers = /* @__PURE__ */ new Map();
55
+ this._dependencies = null;
82
56
  this.name = this.constructor.name;
83
57
  this.debug = false;
84
58
  this.instanceId = generateSimpleId(this.constructor.name, "main");
85
59
  this.createdAt = Date.now();
86
- this._dependencies = null;
87
60
  this.lastUpdateTimestamp = Date.now();
88
61
  this.onSystemEvent = (event, handler) => {
89
- let handlers = this.systemEventHandlers.get(event);
62
+ let handlers = this._systemEventHandlers.get(event);
90
63
  if (!handlers) {
91
64
  handlers = /* @__PURE__ */ new Set();
92
- this.systemEventHandlers.set(event, handlers);
65
+ this._systemEventHandlers.set(event, handlers);
93
66
  }
94
67
  handlers.add(handler);
95
68
  return () => {
@@ -98,103 +71,71 @@ var StateContainer = class StateContainer {
98
71
  };
99
72
  this._state = initialState;
100
73
  }
101
- /**
102
- * Initialize configuration for this instance.
103
- * Called by the registry after construction.
104
- * @param config - Configuration options
105
- */
106
74
  initConfig(config) {
107
- this.config = { ...config };
108
- this.name = this.config.name || this.constructor.name;
109
- this.debug = this.config.debug ?? false;
110
- this.instanceId = generateSimpleId(this.constructor.name, this.config.instanceId);
75
+ this._config = { ...config };
76
+ this.name = this._config.name || this.constructor.name;
77
+ this.debug = this._config.debug ?? false;
78
+ this.instanceId = generateSimpleId(this.constructor.name, this._config.instanceId);
111
79
  globalRegistry.emit("created", this);
112
80
  }
113
- /** Current state value */
114
81
  get state() {
115
82
  return this._state;
116
83
  }
117
- /** Whether this instance has been disposed */
118
84
  get isDisposed() {
119
85
  return this._disposed;
120
86
  }
121
- /** Current hydration status for this instance */
122
87
  get hydrationStatus() {
123
88
  return this._hydrationStatus;
124
89
  }
125
- /** Error from the latest failed hydration, if any */
126
90
  get hydrationError() {
127
91
  return this._hydrationError;
128
92
  }
129
- /** Whether this instance has completed hydration successfully */
130
93
  get isHydrated() {
131
94
  return this._hydrationStatus === "hydrated";
132
95
  }
133
- /** Whether user state changes happened while hydration was pending */
134
96
  get changedWhileHydrating() {
135
97
  return this._changedWhileHydrating;
136
98
  }
137
- /**
138
- * Subscribe to state changes
139
- * @param listener - Function called when state changes
140
- * @returns Unsubscribe function
141
- */
142
99
  subscribe(listener) {
143
100
  if (this._disposed) throw new Error(`Cannot subscribe to disposed container ${this.name}`);
144
- this.listeners.add(listener);
145
- return () => this.listeners.delete(listener);
101
+ this._listeners.add(listener);
102
+ return () => this._listeners.delete(listener);
146
103
  }
147
- /**
148
- * Dispose this instance and clean up resources.
149
- * Clears all listeners and emits the 'dispose' system event.
150
- */
151
104
  dispose() {
152
105
  if (this._disposed) return;
153
106
  if (this.debug) console.log(`[${this.name}] Disposing...`);
154
107
  this._disposed = true;
155
108
  if (this._hydrationStatus === "hydrating") this.failHydration(/* @__PURE__ */ new Error(`Hydration cancelled because ${this.name} was disposed`));
156
109
  this.emitSystemEvent("dispose", void 0);
157
- this.listeners.clear();
158
- this.systemEventHandlers.clear();
110
+ this._listeners.clear();
111
+ this._systemEventHandlers.clear();
159
112
  globalRegistry.emit("disposed", this);
160
113
  if (this.debug) console.log(`[${this.name}] Disposed successfully`);
161
114
  }
162
- /**
163
- * Emit a new state value and notify all listeners.
164
- * @param newState - The new state value
165
- * @protected
166
- */
167
- emit(newState) {
115
+ [EMIT](newState) {
168
116
  this.applyState(newState, "default");
169
117
  }
170
- /**
171
- * Mark this instance as hydrating. Plugins should call this before starting
172
- * asynchronous rehydration work.
173
- */
118
+ [UPDATE](updater) {
119
+ if (this._disposed) throw new Error(`Cannot update state from disposed container ${this.name}`);
120
+ this[EMIT](updater(this._state));
121
+ }
174
122
  beginHydration() {
175
123
  if (this._disposed) throw new Error(`Cannot begin hydration for disposed container ${this.name}`);
176
124
  this._changedWhileHydrating = false;
177
125
  this._hydrationError = void 0;
178
- this.hydrationPromise = null;
179
- this.resolveHydrationPromise = void 0;
180
- this.rejectHydrationPromise = void 0;
181
- this.hydrationPromiseSettled = false;
126
+ this._hydrationPromise = null;
127
+ this._resolveHydrationPromise = void 0;
128
+ this._rejectHydrationPromise = void 0;
129
+ this._hydrationPromiseSettled = false;
182
130
  this.ensureHydrationPromise();
183
131
  this.setHydrationStatus("hydrating");
184
132
  }
185
- /**
186
- * Apply hydrated state if no user writes happened since hydration started.
187
- * Returns false when hydration should be skipped.
188
- */
189
133
  applyHydratedState(newState) {
190
134
  if (this._disposed) return false;
191
135
  if (this._hydrationStatus !== "hydrating" || this._changedWhileHydrating) return false;
192
136
  this.applyState(newState, "hydration");
193
137
  return true;
194
138
  }
195
- /**
196
- * Mark hydration as completed.
197
- */
198
139
  finishHydration() {
199
140
  if (this._hydrationStatus !== "hydrating") {
200
141
  if (this._hydrationStatus === "hydrated") return;
@@ -203,18 +144,12 @@ var StateContainer = class StateContainer {
203
144
  this.setHydrationStatus("hydrated");
204
145
  this.resolveHydration();
205
146
  }
206
- /**
207
- * Mark hydration as failed.
208
- */
209
147
  failHydration(error) {
210
148
  const err = error instanceof Error ? error : /* @__PURE__ */ new Error(`Hydration failed: ${error}`);
211
149
  this._hydrationError = err;
212
150
  this.setHydrationStatus("error", err);
213
151
  this.rejectHydration(err);
214
152
  }
215
- /**
216
- * Wait until the current hydration cycle finishes.
217
- */
218
153
  waitForHydration() {
219
154
  if (this._hydrationStatus === "idle" || this._hydrationStatus === "hydrated") return Promise.resolve();
220
155
  if (this._hydrationStatus === "error") return Promise.reject(this._hydrationError ?? /* @__PURE__ */ new Error(`Hydration failed for container ${this.name}`));
@@ -227,7 +162,7 @@ var StateContainer = class StateContainer {
227
162
  const formattedLines = [];
228
163
  for (const line of relevantLines) {
229
164
  if (!line.trim()) continue;
230
- if (line.includes("StateContainer.emit") || line.includes("StateContainer.update") || line.includes("StateContainer.captureStackTrace") || line.includes("Cubit.patch")) continue;
165
+ if (line.includes("StateContainer.emit") || line.includes("StateContainer.update") || line.includes("StateContainer.captureStackTrace") || line.includes("[blac.emit]") || line.includes("[blac.update]") || line.includes("Cubit.patch")) continue;
231
166
  if (line.includes("node_modules") || line.includes("react-dom") || line.includes("react_jsx") || line.includes(".vite/deps") || line.includes("executeDispatch") || line.includes("runWithFiber") || line.includes("invokeGuarded") || line.includes("callCallback") || line.includes("processDispatchQueue") || line.includes("dispatchEvent") || line.includes("batchedUpdates")) continue;
232
167
  const formatted = this.formatStackLine(line);
233
168
  if (formatted) formattedLines.push(formatted);
@@ -258,15 +193,6 @@ var StateContainer = class StateContainer {
258
193
  if (segments.length > 3) path = segments.slice(-3).join("/");
259
194
  return path;
260
195
  }
261
- /**
262
- * Update state using a transform function.
263
- * @param updater - Function that receives current state and returns new state
264
- * @protected
265
- */
266
- update(updater) {
267
- if (this._disposed) throw new Error(`Cannot update state from disposed container ${this.name}`);
268
- this.emit(updater(this._state));
269
- }
270
196
  applyState(newState, source) {
271
197
  if (this._disposed) throw new Error(`Cannot emit state from disposed container ${this.name}`);
272
198
  if (this._state === newState) return;
@@ -277,7 +203,7 @@ var StateContainer = class StateContainer {
277
203
  state: newState,
278
204
  previousState
279
205
  });
280
- const listeners = Array.from(this.listeners);
206
+ const listeners = Array.from(this._listeners);
281
207
  for (const listener of listeners) try {
282
208
  listener(newState);
283
209
  } catch (error) {
@@ -299,33 +225,33 @@ var StateContainer = class StateContainer {
299
225
  });
300
226
  }
301
227
  ensureHydrationPromise() {
302
- if (!this.hydrationPromise || this.hydrationPromiseSettled) {
303
- this.hydrationPromiseSettled = false;
304
- this.hydrationPromise = new Promise((resolve, reject) => {
305
- this.resolveHydrationPromise = () => {
306
- if (this.hydrationPromiseSettled) return;
307
- this.hydrationPromiseSettled = true;
228
+ if (!this._hydrationPromise || this._hydrationPromiseSettled) {
229
+ this._hydrationPromiseSettled = false;
230
+ this._hydrationPromise = new Promise((resolve, reject) => {
231
+ this._resolveHydrationPromise = () => {
232
+ if (this._hydrationPromiseSettled) return;
233
+ this._hydrationPromiseSettled = true;
308
234
  resolve();
309
235
  };
310
- this.rejectHydrationPromise = (error) => {
311
- if (this.hydrationPromiseSettled) return;
312
- this.hydrationPromiseSettled = true;
236
+ this._rejectHydrationPromise = (error) => {
237
+ if (this._hydrationPromiseSettled) return;
238
+ this._hydrationPromiseSettled = true;
313
239
  reject(error);
314
240
  };
315
241
  });
316
- this.hydrationPromise.catch(() => {});
242
+ this._hydrationPromise.catch(() => {});
317
243
  }
318
- return this.hydrationPromise;
244
+ return this._hydrationPromise;
319
245
  }
320
246
  resolveHydration() {
321
- this.resolveHydrationPromise?.();
247
+ this._resolveHydrationPromise?.();
322
248
  }
323
249
  rejectHydration(error) {
324
250
  this.ensureHydrationPromise();
325
- this.rejectHydrationPromise?.(error);
251
+ this._rejectHydrationPromise?.(error);
326
252
  }
327
253
  emitSystemEvent(event, payload) {
328
- const handlers = this.systemEventHandlers.get(event);
254
+ const handlers = this._systemEventHandlers.get(event);
329
255
  if (!handlers) return;
330
256
  for (const handler of handlers) try {
331
257
  handler(payload);
@@ -336,12 +262,6 @@ var StateContainer = class StateContainer {
336
262
  };
337
263
  //#endregion
338
264
  //#region src/core/Cubit.ts
339
- /**
340
- * Simple state container with direct state emission.
341
- * Extends StateContainer with public methods for emitting and updating state.
342
- *
343
- * @template S - State type
344
- */
345
265
  var Cubit = class extends StateContainer {
346
266
  constructor(initialState) {
347
267
  super(initialState);
@@ -359,19 +279,11 @@ var Cubit = class extends StateContainer {
359
279
  }));
360
280
  });
361
281
  }
362
- /**
363
- * Replace state with a new value and notify all listeners
364
- * @param newState - The new state value
365
- */
366
282
  emit(newState) {
367
- super["emit"](newState);
283
+ this[EMIT](newState);
368
284
  }
369
- /**
370
- * Transform current state using an updater function and emit the new state
371
- * @param updater - Function that receives current state and returns new state
372
- */
373
285
  update(updater) {
374
- super["update"](updater);
286
+ this[UPDATE](updater);
375
287
  }
376
288
  };
377
289
  //#endregion
@@ -402,9 +314,6 @@ function release(BlocClass, instanceKey, forceDispose = false) {
402
314
  *
403
315
  * @example Decorator syntax (requires experimentalDecorators or TC39 decorators)
404
316
  * ```ts
405
- * @blac({ isolated: true })
406
- * class FormBloc extends Cubit<FormState> {}
407
- *
408
317
  * @blac({ keepAlive: true })
409
318
  * class AuthBloc extends Cubit<AuthState> {}
410
319
  *
@@ -414,20 +323,19 @@ function release(BlocClass, instanceKey, forceDispose = false) {
414
323
  *
415
324
  * @example Function syntax (no decorator support needed)
416
325
  * ```ts
417
- * const FormBloc = blac({ isolated: true })(
418
- * class extends Cubit<FormState> {}
326
+ * const AuthBloc = blac({ keepAlive: true })(
327
+ * class extends Cubit<AuthState> {}
419
328
  * );
420
329
  * ```
421
330
  */
422
331
  function blac(options) {
423
332
  return function(target, _context) {
424
- if ("isolated" in options && options.isolated) target[BLAC_STATIC_PROPS.ISOLATED] = true;
425
333
  if ("keepAlive" in options && options.keepAlive) target[BLAC_STATIC_PROPS.KEEP_ALIVE] = true;
426
334
  if ("excludeFromDevTools" in options && options.excludeFromDevTools) target[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;
427
335
  return target;
428
336
  };
429
337
  }
430
338
  //#endregion
431
- export { Cubit, PluginManager, StateContainer, TrackedContext, acquire, blac, borrow, borrowSafe, clear, clearAll, createTrackedContext, ensure, forEach, generateIsolatedKey, getAll, getPluginManager, getRefCount, getRegistry, getStats, globalRegistry, hasInstance, instance, instanceId, isIsolatedClass, register, release, setRegistry, tracked, watch };
339
+ export { Cubit, EMIT, PluginManager, StateContainer, TrackedContext, UPDATE, acquire, blac, borrow, borrowSafe, clear, clearAll, createTrackedContext, ensure, forEach, getAll, getPluginManager, getRefCount, getRegistry, getStats, globalRegistry, hasInstance, instance, instanceId, register, release, setRegistry, tracked, watch };
432
340
 
433
341
  //# sourceMappingURL=index.js.map