@blac/core 2.0.0-rc.16 → 2.0.0-rc.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -196,17 +196,17 @@ var PluginManager = class {
196
196
  * Setup lifecycle hooks to notify plugins
197
197
  */
198
198
  setupLifecycleHooks() {
199
- this.registry.on("created", (instance) => {
200
- this.notifyPlugins("onInstanceCreated", instance);
199
+ this.registry.on("created", (instance$1) => {
200
+ this.notifyPlugins("onInstanceCreated", instance$1);
201
201
  });
202
- this.registry.on("stateChanged", (instance, previousState, currentState, callstack) => {
203
- this.notifyPlugins("onStateChanged", instance, previousState, currentState, callstack);
202
+ this.registry.on("stateChanged", (instance$1, previousState, currentState, callstack) => {
203
+ this.notifyPlugins("onStateChanged", instance$1, previousState, currentState, callstack);
204
204
  });
205
205
  this.registry.on("eventAdded", (vertex, event) => {
206
206
  this.notifyPlugins("onEventAdded", vertex, event);
207
207
  });
208
- this.registry.on("disposed", (instance) => {
209
- this.notifyPlugins("onInstanceDisposed", instance);
208
+ this.registry.on("disposed", (instance$1) => {
209
+ this.notifyPlugins("onInstanceDisposed", instance$1);
210
210
  });
211
211
  }
212
212
  /**
@@ -228,23 +228,23 @@ var PluginManager = class {
228
228
  */
229
229
  createPluginContext() {
230
230
  return {
231
- getInstanceMetadata: (instance) => {
231
+ getInstanceMetadata: (instance$1) => {
232
232
  return {
233
- id: instance.instanceId,
234
- className: instance.constructor.name,
235
- isDisposed: instance.isDisposed,
236
- name: instance.name,
237
- lastStateChangeTimestamp: instance.lastUpdateTimestamp,
238
- createdAt: instance.createdAt,
239
- state: instance.state,
240
- isIsolated: instance.instanceId.startsWith("isolated-")
233
+ id: instance$1.instanceId,
234
+ className: instance$1.constructor.name,
235
+ isDisposed: instance$1.isDisposed,
236
+ name: instance$1.name,
237
+ lastStateChangeTimestamp: instance$1.lastUpdateTimestamp,
238
+ createdAt: instance$1.createdAt,
239
+ state: instance$1.state,
240
+ isIsolated: instance$1.instanceId.startsWith("isolated-")
241
241
  };
242
242
  },
243
- getState: (instance) => {
244
- return instance.state;
243
+ getState: (instance$1) => {
244
+ return instance$1.state;
245
245
  },
246
246
  queryInstances: (typeClass) => {
247
- return typeClass.getAll();
247
+ return this.registry.getAll(typeClass);
248
248
  },
249
249
  getAllTypes: () => {
250
250
  return this.registry.getTypes();
@@ -336,7 +336,7 @@ const getterExecutionContext = {
336
336
  depth: 0,
337
337
  visitedBlocs: /* @__PURE__ */ new Set()
338
338
  };
339
- const MAX_GETTER_DEPTH = BLAC_DEFAULTS.MAX_GETTER_DEPTH;
339
+ const MAX_GETTER_DEPTH$1 = BLAC_DEFAULTS.MAX_GETTER_DEPTH;
340
340
  /**
341
341
  * @internal
342
342
  */
@@ -373,7 +373,7 @@ function isGetter(obj, prop) {
373
373
  /**
374
374
  * @internal
375
375
  */
376
- function createGetterTracker() {
376
+ function createGetterState() {
377
377
  return {
378
378
  trackedValues: /* @__PURE__ */ new Map(),
379
379
  currentlyAccessing: /* @__PURE__ */ new Set(),
@@ -424,8 +424,8 @@ function createBlocProxy(bloc) {
424
424
  tracker.trackedValues.set(prop, cachedValue);
425
425
  return cachedValue;
426
426
  }
427
- if (getterExecutionContext.depth >= MAX_GETTER_DEPTH) {
428
- console.warn(`${BLAC_ERROR_PREFIX} Maximum getter depth (${MAX_GETTER_DEPTH}) exceeded. Possible circular dependency in getter "${String(prop)}" on ${target.constructor.name}. Returning undefined to prevent stack overflow.`);
427
+ if (getterExecutionContext.depth >= MAX_GETTER_DEPTH$1) {
428
+ console.warn(`${BLAC_ERROR_PREFIX} Maximum getter depth (${MAX_GETTER_DEPTH$1}) exceeded. Possible circular dependency in getter "${String(prop)}" on ${target.constructor.name}. Returning undefined to prevent stack overflow.`);
429
429
  return;
430
430
  }
431
431
  if (getterExecutionContext.visitedBlocs.has(target)) {
@@ -501,7 +501,7 @@ function clearExternalDependencies(tracker) {
501
501
  /**
502
502
  * @internal
503
503
  */
504
- function resetGetterTracker(tracker) {
504
+ function resetGetterState(tracker) {
505
505
  tracker.trackedValues.clear();
506
506
  tracker.currentlyAccessing.clear();
507
507
  tracker.trackedGetters.clear();
@@ -511,6 +511,19 @@ function resetGetterTracker(tracker) {
511
511
  tracker.externalDependencies.clear();
512
512
  }
513
513
 
514
+ //#endregion
515
+ //#region src/core/markers.ts
516
+ /**
517
+ * Marker symbols for identifying container types.
518
+ * These are in a separate file to avoid circular dependencies.
519
+ * @internal
520
+ */
521
+ /**
522
+ * Marker symbol to identify stateless containers at the type level.
523
+ * Used by React hooks to prevent `useBloc` from accepting stateless containers.
524
+ */
525
+ const STATELESS_MARKER = Symbol("STATELESS_CONTAINER");
526
+
514
527
  //#endregion
515
528
  //#region src/utils/static-props.ts
516
529
  /**
@@ -555,6 +568,15 @@ function isKeepAliveClass(Type) {
555
568
  function isExcludedFromDevTools(Type) {
556
569
  return getStaticProp(Type, BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS) === true;
557
570
  }
571
+ /**
572
+ * Check if a class is a stateless container (StatelessCubit or StatelessVertex).
573
+ * Stateless containers don't have state, emit, update, or subscribe methods.
574
+ * @param Type - The class constructor to check
575
+ * @returns true if the class is a stateless container
576
+ */
577
+ function isStatelessClass(Type) {
578
+ return Type[STATELESS_MARKER] === true;
579
+ }
558
580
 
559
581
  //#endregion
560
582
  //#region src/core/StateContainerRegistry.ts
@@ -565,7 +587,8 @@ function isExcludedFromDevTools(Type) {
565
587
  * @example
566
588
  * ```ts
567
589
  * const registry = new StateContainerRegistry();
568
- * const instance = registry.resolve(MyBloc);
590
+ * const instance = registry.acquire(MyBloc); // ownership, must release
591
+ * const other = registry.ensure(OtherBloc); // no ownership, bloc-to-bloc
569
592
  * registry.on('stateChanged', (container, prev, next) => {
570
593
  * console.log('State changed:', prev, '->', next);
571
594
  * });
@@ -612,34 +635,35 @@ var StateContainerRegistry = class {
612
635
  getInstancesMap(Type) {
613
636
  return this.instancesByConstructor.get(Type) || /* @__PURE__ */ new Map();
614
637
  }
615
- trackExecutionContext(instance) {
638
+ trackExecutionContext(instance$1) {
616
639
  const context = getGetterExecutionContext();
617
- if (context.tracker && context.currentBloc && context.currentBloc !== instance) context.tracker.externalDependencies.add(instance);
640
+ if (context.tracker && context.currentBloc && context.currentBloc !== instance$1) context.tracker.externalDependencies.add(instance$1);
618
641
  }
619
642
  /**
620
- * Resolve an instance with ref counting (ownership semantics).
643
+ * Acquire an instance with ref counting (ownership semantics).
621
644
  * Creates a new instance if one doesn't exist, or returns existing and increments ref count.
645
+ * You must call `release()` when done to decrement the ref count.
622
646
  * @param Type - The StateContainer class constructor
623
647
  * @param instanceKey - Instance key (defaults to 'default')
624
- * @param options - Resolution options
648
+ * @param options - Acquisition options
625
649
  * @param options.canCreate - Whether to create new instance if not found (default: true)
626
650
  * @param options.countRef - Whether to increment ref count (default: true)
627
651
  * @param options.props - Props to pass to constructor if creating new instance
628
652
  * @param options.trackExecutionContext - Whether to track cross-bloc dependency (default: false)
629
653
  * @returns The state container instance
630
654
  */
631
- resolve(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, options = {}) {
655
+ acquire(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, options = {}) {
632
656
  const { canCreate = true, countRef = true, props, trackExecutionContext = false } = options;
633
657
  const registryConfig = this.typeConfigs.get(Type.name);
634
658
  const isolated = isIsolatedClass(Type) || registryConfig?.isolated === true;
635
659
  const config = { instanceId: instanceKey };
636
660
  if (isolated && !canCreate) throw new Error(`${BLAC_ERROR_PREFIX} Cannot get isolated instance "${instanceKey}" of ${Type.name} when creation is disabled.`);
637
661
  if (isolated) {
638
- const instance$1 = new Type(props);
639
- instance$1.initConfig(config);
662
+ const instance$2 = new Type(props);
663
+ instance$2.initConfig(config);
640
664
  this.registerType(Type);
641
- if (trackExecutionContext) this.trackExecutionContext(instance$1);
642
- return instance$1;
665
+ if (trackExecutionContext) this.trackExecutionContext(instance$2);
666
+ return instance$2;
643
667
  }
644
668
  const instances = this.ensureInstancesMap(Type);
645
669
  const entry = instances.get(instanceKey);
@@ -649,42 +673,42 @@ var StateContainerRegistry = class {
649
673
  return entry.instance;
650
674
  }
651
675
  if (!canCreate) throw new Error(`${BLAC_ERROR_PREFIX} ${Type.name} instance "${instanceKey}" not found and creation is disabled.`);
652
- const instance = new Type(props);
653
- instance.initConfig(config);
676
+ const instance$1 = new Type(props);
677
+ instance$1.initConfig(config);
654
678
  instances.set(instanceKey, {
655
- instance,
679
+ instance: instance$1,
656
680
  refCount: 1
657
681
  });
658
682
  this.registerType(Type);
659
- if (trackExecutionContext) this.trackExecutionContext(instance);
660
- return instance;
683
+ if (trackExecutionContext) this.trackExecutionContext(instance$1);
684
+ return instance$1;
661
685
  }
662
686
  /**
663
- * Get an existing instance without incrementing ref count (borrowing semantics).
687
+ * Borrow an existing instance without incrementing ref count (borrowing semantics).
664
688
  * Tracks cross-bloc dependency for reactive updates.
665
689
  * @param Type - The StateContainer class constructor
666
690
  * @param instanceKey - Instance key (defaults to 'default')
667
691
  * @returns The state container instance
668
692
  * @throws Error if instance doesn't exist
669
693
  */
670
- get(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
671
- return this.resolve(Type, instanceKey, {
694
+ borrow(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
695
+ return this.acquire(Type, instanceKey, {
672
696
  canCreate: false,
673
697
  trackExecutionContext: true
674
698
  });
675
699
  }
676
700
  /**
677
- * Safely get an existing instance (borrowing semantics with error handling).
701
+ * Safely borrow an existing instance (borrowing semantics with error handling).
678
702
  * Returns discriminated union for type-safe conditional access.
679
703
  * @param Type - The StateContainer class constructor
680
704
  * @param instanceKey - Instance key (defaults to 'default')
681
705
  * @returns Discriminated union with either the instance or an error
682
706
  */
683
- getSafe(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
707
+ borrowSafe(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
684
708
  try {
685
709
  return {
686
710
  error: null,
687
- instance: this.get(Type, instanceKey)
711
+ instance: this.borrow(Type, instanceKey)
688
712
  };
689
713
  } catch (error$1) {
690
714
  return {
@@ -694,7 +718,7 @@ var StateContainerRegistry = class {
694
718
  }
695
719
  }
696
720
  /**
697
- * Connect to an instance with borrowing semantics (for B2B communication).
721
+ * Ensure an instance exists without taking ownership (for bloc-to-bloc communication).
698
722
  * Gets existing instance OR creates it if it doesn't exist, without incrementing ref count.
699
723
  * Tracks cross-bloc dependency for reactive updates.
700
724
  *
@@ -704,8 +728,8 @@ var StateContainerRegistry = class {
704
728
  * @param instanceKey - Instance key (defaults to 'default')
705
729
  * @returns The state container instance
706
730
  */
707
- connect(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
708
- return this.resolve(Type, instanceKey, {
731
+ ensure(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
732
+ return this.acquire(Type, instanceKey, {
709
733
  canCreate: true,
710
734
  countRef: false,
711
735
  trackExecutionContext: true
@@ -754,9 +778,9 @@ var StateContainerRegistry = class {
754
778
  forEach(Type, callback) {
755
779
  const instances = this.ensureInstancesMap(Type);
756
780
  for (const entry of instances.values()) {
757
- const instance = entry.instance;
758
- if (!instance.isDisposed) try {
759
- callback(instance);
781
+ const instance$1 = entry.instance;
782
+ if (!instance$1.isDisposed) try {
783
+ callback(instance$1);
760
784
  } catch (error$1) {
761
785
  console.error(`${BLAC_ERROR_PREFIX} forEach callback error for ${Type.name}:`, error$1);
762
786
  }
@@ -834,9 +858,9 @@ var StateContainerRegistry = class {
834
858
  */
835
859
  on(event, listener) {
836
860
  if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
837
- const instance = this.listeners.get(event);
838
- if (!instance) throw new Error(`${BLAC_ERROR_PREFIX} Failed to register listener for event '${event}'`);
839
- instance.add(listener);
861
+ const instance$1 = this.listeners.get(event);
862
+ if (!instance$1) throw new Error(`${BLAC_ERROR_PREFIX} Failed to register listener for event '${event}'`);
863
+ instance$1.add(listener);
840
864
  return () => {
841
865
  this.listeners.get(event)?.delete(listener);
842
866
  };
@@ -898,132 +922,7 @@ var StateContainer = class StateContainer {
898
922
  this.__excludeFromDevTools = false;
899
923
  }
900
924
  static {
901
- this._registry = globalRegistry;
902
- }
903
- /**
904
- * Get the global StateContainerRegistry
905
- * @returns The registry managing all state container instances
906
- */
907
- static getRegistry() {
908
- return StateContainer._registry;
909
- }
910
- /**
911
- * Replace the global registry (clears existing instances)
912
- * @param registry - The new registry to use
913
- */
914
- static setRegistry(registry) {
915
- StateContainer._registry.clearAll();
916
- StateContainer._registry = registry;
917
- }
918
- /**
919
- * Register this class with the global registry
920
- * @param isolated - Whether instances should be isolated (component-scoped)
921
- */
922
- static register(isolated = false) {
923
- StateContainer._registry.register(this, isolated);
924
- }
925
- /**
926
- * Resolve an instance with ref counting (ownership semantics).
927
- * Creates a new instance if one doesn't exist, or returns existing and increments ref count.
928
- * @template S - Optional state type override for generic StateContainers
929
- * @template T - The StateContainer type (inferred from class)
930
- * @param instanceKey - Optional instance key (defaults to 'default')
931
- * @param options - Resolution options (canCreate, countRef, props, trackExecutionContext)
932
- * @returns The state container instance
933
- */
934
- static resolve(instanceKey, options) {
935
- return StateContainer._registry.resolve(this, instanceKey, options);
936
- }
937
- /**
938
- * Get an existing instance without incrementing ref count (borrowing semantics).
939
- * @template S - Optional state type override for generic StateContainers
940
- * @template T - The StateContainer type (inferred from class)
941
- * @param instanceKey - Optional instance key (defaults to 'default')
942
- * @returns The state container instance
943
- * @throws Error if instance doesn't exist
944
- */
945
- static get(instanceKey) {
946
- return StateContainer._registry.get(this, instanceKey);
947
- }
948
- /**
949
- * Safely get an existing instance with error handling.
950
- * @template S - Optional state type override for generic StateContainers
951
- * @template T - The StateContainer type (inferred from class)
952
- * @param instanceKey - Optional instance key (defaults to 'default')
953
- * @returns Discriminated union with either the instance or an error
954
- */
955
- static getSafe(instanceKey) {
956
- return StateContainer._registry.getSafe(this, instanceKey);
957
- }
958
- /**
959
- * Connect to an instance for bloc-to-bloc communication (borrowing semantics).
960
- * Gets or creates instance without incrementing ref count.
961
- * Tracks cross-bloc dependency for reactive updates.
962
- * @template S - Optional state type override for generic StateContainers
963
- * @template T - The StateContainer type (inferred from class)
964
- * @param instanceKey - Optional instance key (defaults to 'default')
965
- * @returns The state container instance
966
- */
967
- static connect(instanceKey) {
968
- return StateContainer._registry.connect(this, instanceKey);
969
- }
970
- /**
971
- * Release a reference to an instance.
972
- * Decrements ref count and disposes when it reaches 0 (unless keepAlive).
973
- * @param instanceKey - Optional instance key (defaults to 'default')
974
- * @param forceDispose - Force immediate disposal regardless of ref count
975
- */
976
- static release(instanceKey, forceDispose = false) {
977
- StateContainer._registry.release(this, instanceKey, forceDispose);
978
- }
979
- /**
980
- * Get all instances of this class
981
- * @returns Array of all instances
982
- */
983
- static getAll() {
984
- return StateContainer._registry.getAll(this);
985
- }
986
- /**
987
- * Iterate over all instances of this class
988
- * @param callback - Function to call for each instance
989
- */
990
- static forEach(callback) {
991
- StateContainer._registry.forEach(this, callback);
992
- }
993
- /**
994
- * Clear all instances of this class (disposes them)
995
- */
996
- static clear() {
997
- StateContainer._registry.clear(this);
998
- }
999
- /**
1000
- * Clear all instances from all registered types
1001
- */
1002
- static clearAllInstances() {
1003
- StateContainer._registry.clearAll();
1004
- }
1005
- /**
1006
- * Get registry statistics for debugging
1007
- * @returns Object with registeredTypes, totalInstances, and typeBreakdown
1008
- */
1009
- static getStats() {
1010
- return StateContainer._registry.getStats();
1011
- }
1012
- /**
1013
- * Get reference count for an instance
1014
- * @param instanceKey - Optional instance key (defaults to 'default')
1015
- * @returns Current ref count (0 if instance doesn't exist)
1016
- */
1017
- static getRefCount(instanceKey) {
1018
- return StateContainer._registry.getRefCount(this, instanceKey);
1019
- }
1020
- /**
1021
- * Check if an instance exists
1022
- * @param instanceKey - Optional instance key (defaults to 'default')
1023
- * @returns true if instance exists
1024
- */
1025
- static hasInstance(instanceKey) {
1026
- return StateContainer._registry.hasInstance(this, instanceKey);
925
+ this.enableStackTrace = true;
1027
926
  }
1028
927
  /** Current props value passed to this container */
1029
928
  get props() {
@@ -1063,7 +962,7 @@ var StateContainer = class StateContainer {
1063
962
  this.name = this.config.name || this.constructor.name;
1064
963
  this.debug = this.config.debug ?? false;
1065
964
  this.instanceId = generateSimpleId(this.constructor.name, this.config.instanceId);
1066
- StateContainer._registry.emit("created", this);
965
+ globalRegistry.emit("created", this);
1067
966
  }
1068
967
  /** Current state value */
1069
968
  get state() {
@@ -1094,7 +993,7 @@ var StateContainer = class StateContainer {
1094
993
  this.emitSystemEvent("dispose", void 0);
1095
994
  this.listeners.clear();
1096
995
  this.systemEventHandlers.clear();
1097
- StateContainer._registry.emit("disposed", this);
996
+ globalRegistry.emit("disposed", this);
1098
997
  if (this.debug) console.log(`[${this.name}] Disposed successfully`);
1099
998
  }
1100
999
  /**
@@ -1117,12 +1016,9 @@ var StateContainer = class StateContainer {
1117
1016
  console.error(`[${this.name}] Error in listener:`, error$1);
1118
1017
  }
1119
1018
  const stackTrace = this.captureStackTrace();
1120
- StateContainer._registry.emit("stateChanged", this, previousState, newState, stackTrace);
1019
+ globalRegistry.emit("stateChanged", this, previousState, newState, stackTrace);
1121
1020
  this.lastUpdateTimestamp = Date.now();
1122
1021
  }
1123
- static {
1124
- this.enableStackTrace = true;
1125
- }
1126
1022
  captureStackTrace() {
1127
1023
  if (!StateContainer.enableStackTrace || typeof process !== "undefined" && process.env?.NODE_ENV === "production") return "";
1128
1024
  try {
@@ -1281,7 +1177,7 @@ var Vertex = class extends StateContainer {
1281
1177
  this.eventQueue = [];
1282
1178
  this.add = (event) => {
1283
1179
  const enrichedEvent = this.enrichEvent(event);
1284
- StateContainer._registry.emit("eventAdded", this, enrichedEvent);
1180
+ globalRegistry.emit("eventAdded", this, enrichedEvent);
1285
1181
  this.processEvent(enrichedEvent);
1286
1182
  };
1287
1183
  }
@@ -1345,6 +1241,223 @@ var Vertex = class extends StateContainer {
1345
1241
  onEventError(_event, _error) {}
1346
1242
  };
1347
1243
 
1244
+ //#endregion
1245
+ //#region src/core/StatelessCubit.ts
1246
+ /**
1247
+ * A Cubit without state management capabilities.
1248
+ * Use this for action-only containers that don't need to manage or emit state.
1249
+ *
1250
+ * StatelessCubit:
1251
+ * - Has no `emit()`, `update()`, or `patch()` methods
1252
+ * - Has no accessible `state` property
1253
+ * - Cannot be subscribed to (throws error)
1254
+ * - Is rejected by `useBloc` hook (use `useBlocActions` instead)
1255
+ *
1256
+ * @template P - Props type (optional)
1257
+ *
1258
+ * @example
1259
+ * ```typescript
1260
+ * class AnalyticsService extends StatelessCubit {
1261
+ * trackPageView(page: string) {
1262
+ * analytics.track('page_view', { page });
1263
+ * }
1264
+ *
1265
+ * trackClick(element: string) {
1266
+ * analytics.track('click', { element });
1267
+ * }
1268
+ * }
1269
+ *
1270
+ * // In React component:
1271
+ * const analytics = useBlocActions(AnalyticsService);
1272
+ * analytics.trackPageView('/home');
1273
+ * ```
1274
+ */
1275
+ var StatelessCubit = class extends Cubit {
1276
+ static {
1277
+ this[STATELESS_MARKER] = true;
1278
+ }
1279
+ constructor() {
1280
+ super({});
1281
+ this.patch = (_partial) => {
1282
+ throw new Error(`${this.name} is a StatelessCubit and does not support patch(). Use a regular Cubit if you need state management.`);
1283
+ };
1284
+ }
1285
+ /**
1286
+ * State is not available on StatelessCubit.
1287
+ * @throws Always throws an error when accessed.
1288
+ */
1289
+ get state() {
1290
+ throw new Error(`${this.name} is a StatelessCubit and does not have state. Use a regular Cubit if you need state management.`);
1291
+ }
1292
+ /**
1293
+ * Subscriptions are not available on StatelessCubit.
1294
+ * @throws Always throws an error when called.
1295
+ */
1296
+ subscribe(_listener) {
1297
+ throw new Error(`${this.name} is a StatelessCubit and does not support subscriptions. Use useBlocActions() instead of useBloc() in React.`);
1298
+ }
1299
+ /**
1300
+ * emit() is not available on StatelessCubit.
1301
+ * TypeScript will show an error if you try to call this method.
1302
+ */
1303
+ emit(_newState) {
1304
+ throw new Error(`${this.name} is a StatelessCubit and does not support emit(). Use a regular Cubit if you need state management.`);
1305
+ }
1306
+ /**
1307
+ * update() is not available on StatelessCubit.
1308
+ * TypeScript will show an error if you try to call this method.
1309
+ */
1310
+ update(_updater) {
1311
+ throw new Error(`${this.name} is a StatelessCubit and does not support update(). Use a regular Cubit if you need state management.`);
1312
+ }
1313
+ };
1314
+
1315
+ //#endregion
1316
+ //#region src/core/StatelessVertex.ts
1317
+ /**
1318
+ * An event-driven container without state management capabilities.
1319
+ * Use this for event processing that only produces side effects (logging, analytics, etc).
1320
+ *
1321
+ * StatelessVertex:
1322
+ * - Processes events via `add()` method
1323
+ * - Handlers receive only the event (no `emit` function)
1324
+ * - Has no accessible `state` property
1325
+ * - Cannot be subscribed to (throws error)
1326
+ * - Is rejected by `useBloc` hook (use `useBlocActions` instead)
1327
+ *
1328
+ * @template E - Event union type (discriminated by 'type' property)
1329
+ * @template P - Props type (optional)
1330
+ *
1331
+ * @example
1332
+ * ```typescript
1333
+ * type LogEvent =
1334
+ * | { type: 'info'; message: string }
1335
+ * | { type: 'error'; message: string; error: Error }
1336
+ * | { type: 'warn'; message: string };
1337
+ *
1338
+ * class LoggingVertex extends StatelessVertex<LogEvent> {
1339
+ * constructor() {
1340
+ * super();
1341
+ * this.createHandlers({
1342
+ * info: (event) => console.log('[INFO]', event.message),
1343
+ * error: (event) => console.error('[ERROR]', event.message, event.error),
1344
+ * warn: (event) => console.warn('[WARN]', event.message),
1345
+ * });
1346
+ * }
1347
+ *
1348
+ * info = (message: string) => this.add({ type: 'info', message });
1349
+ * error = (message: string, error: Error) => this.add({ type: 'error', message, error });
1350
+ * warn = (message: string) => this.add({ type: 'warn', message });
1351
+ * }
1352
+ *
1353
+ * // In React component:
1354
+ * const logger = useBlocActions(LoggingVertex);
1355
+ * logger.info('Page loaded');
1356
+ * ```
1357
+ */
1358
+ var StatelessVertex = class extends StateContainer {
1359
+ static {
1360
+ this[STATELESS_MARKER] = true;
1361
+ }
1362
+ constructor() {
1363
+ super({});
1364
+ this.handlers = /* @__PURE__ */ new Map();
1365
+ this.isProcessing = false;
1366
+ this.eventQueue = [];
1367
+ this.add = (event) => {
1368
+ const enrichedEvent = this.enrichEvent(event);
1369
+ globalRegistry.emit("eventAdded", this, enrichedEvent);
1370
+ this.processEvent(enrichedEvent);
1371
+ };
1372
+ }
1373
+ /**
1374
+ * State is not available on StatelessVertex.
1375
+ * @throws Always throws an error when accessed.
1376
+ */
1377
+ get state() {
1378
+ throw new Error(`${this.name} is a StatelessVertex and does not have state. Use a regular Vertex if you need state management.`);
1379
+ }
1380
+ /**
1381
+ * Subscriptions are not available on StatelessVertex.
1382
+ * @throws Always throws an error when called.
1383
+ */
1384
+ subscribe(_listener) {
1385
+ throw new Error(`${this.name} is a StatelessVertex and does not support subscriptions. Use useBlocActions() instead of useBloc() in React.`);
1386
+ }
1387
+ /**
1388
+ * Register all event handlers with exhaustive type checking.
1389
+ * TypeScript will error if any event type from the union is missing.
1390
+ *
1391
+ * Unlike regular Vertex, handlers do NOT receive an emit function
1392
+ * since StatelessVertex cannot emit state.
1393
+ *
1394
+ * @param handlers - Map of event type to handler function
1395
+ */
1396
+ createHandlers(handlers) {
1397
+ for (const [eventType, handler] of Object.entries(handlers)) this.handlers.set(eventType, handler);
1398
+ }
1399
+ /** @internal */
1400
+ enrichEvent(event) {
1401
+ return {
1402
+ ...event,
1403
+ timestamp: Date.now()
1404
+ };
1405
+ }
1406
+ /** @internal */
1407
+ processEvent(event) {
1408
+ if (this.isProcessing) {
1409
+ this.eventQueue.push(event);
1410
+ return;
1411
+ }
1412
+ this.isProcessing = true;
1413
+ try {
1414
+ this.handleEvent(event);
1415
+ while (this.eventQueue.length > 0) {
1416
+ const nextEvent = this.eventQueue.shift();
1417
+ this.handleEvent(nextEvent);
1418
+ }
1419
+ } finally {
1420
+ this.isProcessing = false;
1421
+ }
1422
+ }
1423
+ /** @internal */
1424
+ handleEvent(event) {
1425
+ const handler = this.handlers.get(event.type);
1426
+ if (!handler) {
1427
+ if (this.debug) console.warn(`No handler registered for event type: ${event.type}`);
1428
+ return;
1429
+ }
1430
+ try {
1431
+ handler(event);
1432
+ } catch (error$1) {
1433
+ if (this.debug) console.error(`Error handling event ${event.type}:`, error$1);
1434
+ this.onEventError(event, error$1);
1435
+ }
1436
+ }
1437
+ /**
1438
+ * Called when an error occurs during event processing.
1439
+ * Override to implement custom error handling.
1440
+ *
1441
+ * @param _event - The event that caused the error
1442
+ * @param _error - The error that occurred
1443
+ */
1444
+ onEventError(_event, _error) {}
1445
+ /**
1446
+ * emit() is not available on StatelessVertex.
1447
+ * @internal
1448
+ */
1449
+ emit(_newState) {
1450
+ throw new Error(`${this.name} is a StatelessVertex and does not support emit(). Use a regular Vertex if you need state management.`);
1451
+ }
1452
+ /**
1453
+ * update() is not available on StatelessVertex.
1454
+ * @internal
1455
+ */
1456
+ update(_updater) {
1457
+ throw new Error(`${this.name} is a StatelessVertex and does not support update(). Use a regular Vertex if you need state management.`);
1458
+ }
1459
+ };
1460
+
1348
1461
  //#endregion
1349
1462
  //#region src/plugin/BlacPlugin.ts
1350
1463
  /**
@@ -1392,7 +1505,7 @@ function isProxyable(value) {
1392
1505
  *
1393
1506
  * @internal
1394
1507
  */
1395
- function createProxyTrackerState() {
1508
+ function createProxyState() {
1396
1509
  return {
1397
1510
  trackedPaths: /* @__PURE__ */ new Set(),
1398
1511
  isTracking: false,
@@ -1410,7 +1523,7 @@ function createProxyTrackerState() {
1410
1523
  *
1411
1524
  * @internal
1412
1525
  */
1413
- function startProxyTracking(state) {
1526
+ function startProxy(state) {
1414
1527
  state.isTracking = true;
1415
1528
  state.trackedPaths.clear();
1416
1529
  }
@@ -1421,7 +1534,7 @@ function startProxyTracking(state) {
1421
1534
  *
1422
1535
  * @internal
1423
1536
  */
1424
- function stopProxyTracking(state) {
1537
+ function stopProxy(state) {
1425
1538
  state.isTracking = false;
1426
1539
  return new Set(state.trackedPaths);
1427
1540
  }
@@ -1460,7 +1573,7 @@ function createArrayProxy(state, target, path, depth = 0) {
1460
1573
  if (!isNaN(index) && index >= 0) fullPath = path ? `${path}[${index}]` : `[${index}]`;
1461
1574
  else fullPath = path ? `${path}.${prop}` : prop;
1462
1575
  } else return value;
1463
- if (isProxyable(value)) return createProxyInternal(state, value, fullPath, depth + 1);
1576
+ if (isProxyable(value)) return createInternal(state, value, fullPath, depth + 1);
1464
1577
  if (state.isTracking) state.trackedPaths.add(fullPath);
1465
1578
  return value;
1466
1579
  } });
@@ -1481,7 +1594,7 @@ function createArrayProxy(state, target, path, depth = 0) {
1481
1594
  *
1482
1595
  * @internal
1483
1596
  */
1484
- function createProxyInternal(state, target, path = "", depth = 0) {
1597
+ function createInternal(state, target, path = "", depth = 0) {
1485
1598
  if (!state.isTracking || !isProxyable(target)) return target;
1486
1599
  if (depth >= state.maxDepth) return target;
1487
1600
  if (state.proxyCache.has(target)) return state.proxyCache.get(target);
@@ -1502,7 +1615,7 @@ function createProxyInternal(state, target, path = "", depth = 0) {
1502
1615
  if (typeof prop === "string" && state.isTracking) {
1503
1616
  if (!prop.startsWith("_") && !prop.startsWith("$$")) state.trackedPaths.add(fullPath);
1504
1617
  }
1505
- if (isProxyable(value)) return createProxyInternal(state, value, fullPath, depth + 1);
1618
+ if (isProxyable(value)) return createInternal(state, value, fullPath, depth + 1);
1506
1619
  return value;
1507
1620
  },
1508
1621
  has: (obj, prop) => {
@@ -1530,11 +1643,11 @@ function createProxyInternal(state, target, path = "", depth = 0) {
1530
1643
  *
1531
1644
  * @internal
1532
1645
  */
1533
- function createProxyForTarget(state, target) {
1646
+ function createForTarget(state, target) {
1534
1647
  if (state.lastProxiedState === target && state.lastProxy) return state.lastProxy;
1535
1648
  state.proxyCache = /* @__PURE__ */ new WeakMap();
1536
1649
  state.boundFunctionsCache = null;
1537
- const proxy = createProxyInternal(state, target, "", 0);
1650
+ const proxy = createInternal(state, target, "", 0);
1538
1651
  state.lastProxiedState = target;
1539
1652
  state.lastProxy = proxy;
1540
1653
  return proxy;
@@ -1675,9 +1788,9 @@ function optimizeTrackedPaths(paths) {
1675
1788
  /**
1676
1789
  * @internal
1677
1790
  */
1678
- function createTrackerState() {
1791
+ function createDependencyState() {
1679
1792
  return {
1680
- proxyTrackerState: createProxyTrackerState(),
1793
+ proxyState: createProxyState(),
1681
1794
  previousRenderPaths: /* @__PURE__ */ new Set(),
1682
1795
  currentRenderPaths: /* @__PURE__ */ new Set(),
1683
1796
  pathCache: /* @__PURE__ */ new Map(),
@@ -1688,21 +1801,21 @@ function createTrackerState() {
1688
1801
  /**
1689
1802
  * @internal
1690
1803
  */
1691
- function startTracking(tracker) {
1692
- startProxyTracking(tracker.proxyTrackerState);
1804
+ function startDependency(tracker) {
1805
+ startProxy(tracker.proxyState);
1693
1806
  }
1694
1807
  /**
1695
1808
  * @internal
1696
1809
  */
1697
- function createProxy(tracker, state) {
1698
- return createProxyForTarget(tracker.proxyTrackerState, state);
1810
+ function createDependencyProxy(tracker, state) {
1811
+ return createForTarget(tracker.proxyState, state);
1699
1812
  }
1700
1813
  /**
1701
1814
  * @internal
1702
1815
  */
1703
- function captureTrackedPaths(tracker, state) {
1816
+ function capturePaths(tracker, state) {
1704
1817
  tracker.previousRenderPaths = tracker.currentRenderPaths;
1705
- tracker.currentRenderPaths = optimizeTrackedPaths(stopProxyTracking(tracker.proxyTrackerState));
1818
+ tracker.currentRenderPaths = optimizeTrackedPaths(stopProxy(tracker.proxyState));
1706
1819
  if (tracker.previousRenderPaths.size === 0 && tracker.currentRenderPaths.size === 0) return;
1707
1820
  const trackedPathsUnion = new Set(tracker.previousRenderPaths);
1708
1821
  for (const path of tracker.currentRenderPaths) trackedPathsUnion.add(path);
@@ -1723,7 +1836,7 @@ function captureTrackedPaths(tracker, state) {
1723
1836
  /**
1724
1837
  * @internal
1725
1838
  */
1726
- function hasChanges(tracker, state) {
1839
+ function hasDependencyChanges(tracker, state) {
1727
1840
  if (tracker.pathCache.size === 0) return true;
1728
1841
  tracker.lastCheckedValues.clear();
1729
1842
  for (const [path, info$1] of tracker.pathCache.entries()) {
@@ -1741,7 +1854,294 @@ function hasChanges(tracker, state) {
1741
1854
  * @internal
1742
1855
  */
1743
1856
  function hasTrackedData(tracker) {
1744
- return tracker.proxyTrackerState.trackedPaths.size > 0 || tracker.pathCache.size > 0 || tracker.previousRenderPaths.size > 0;
1857
+ return tracker.proxyState.trackedPaths.size > 0 || tracker.pathCache.size > 0 || tracker.previousRenderPaths.size > 0;
1858
+ }
1859
+
1860
+ //#endregion
1861
+ //#region src/tracking/tracking-proxy.ts
1862
+ /**
1863
+ * Create a new tracking proxy state.
1864
+ */
1865
+ function createState() {
1866
+ return {
1867
+ dependencyState: createDependencyState(),
1868
+ getterState: createGetterState(),
1869
+ dependencies: /* @__PURE__ */ new Set(),
1870
+ isTracking: false
1871
+ };
1872
+ }
1873
+ /**
1874
+ * Start tracking on a tracking proxy.
1875
+ */
1876
+ function startTracking(tracker) {
1877
+ tracker.isTracking = true;
1878
+ tracker.dependencies.clear();
1879
+ tracker.getterState.isTracking = true;
1880
+ tracker.getterState.externalDependencies.clear();
1881
+ startDependency(tracker.dependencyState);
1882
+ }
1883
+ /**
1884
+ * Stop tracking and collect all dependencies.
1885
+ */
1886
+ function stopTracking(tracker, bloc) {
1887
+ tracker.isTracking = false;
1888
+ tracker.getterState.isTracking = false;
1889
+ capturePaths(tracker.dependencyState, bloc.state);
1890
+ commitTrackedGetters(tracker.getterState);
1891
+ const allDeps = new Set(tracker.dependencies);
1892
+ for (const dep of tracker.getterState.externalDependencies) allDeps.add(dep);
1893
+ tracker.getterState.externalDependencies.clear();
1894
+ return allDeps;
1895
+ }
1896
+ /**
1897
+ * Check if tracked state or getters have changed.
1898
+ */
1899
+ function hasChanges(tracker, bloc) {
1900
+ invalidateRenderCache(tracker.getterState);
1901
+ const stateChanged = hasDependencyChanges(tracker.dependencyState, bloc.state);
1902
+ const getterChanged = hasGetterChanges(bloc, tracker.getterState);
1903
+ return stateChanged || getterChanged;
1904
+ }
1905
+ const MAX_GETTER_DEPTH = BLAC_DEFAULTS.MAX_GETTER_DEPTH;
1906
+ /**
1907
+ * Create a tracking proxy for a bloc instance.
1908
+ * Tracks both state property access and getter access.
1909
+ */
1910
+ function createTrackingProxy(bloc, tracker) {
1911
+ tracker.dependencies.add(bloc);
1912
+ const stateProxyCache = /* @__PURE__ */ new WeakMap();
1913
+ return new Proxy(bloc, { get(target, prop, receiver) {
1914
+ if (prop === "state") {
1915
+ if (!tracker.isTracking) return target.state;
1916
+ const rawState = target.state;
1917
+ if (rawState === null || typeof rawState !== "object") return rawState;
1918
+ if (stateProxyCache.has(rawState)) return stateProxyCache.get(rawState);
1919
+ const stateProxy = createDependencyProxy(tracker.dependencyState, rawState);
1920
+ stateProxyCache.set(rawState, stateProxy);
1921
+ return stateProxy;
1922
+ }
1923
+ if (typeof prop === "symbol") return Reflect.get(target, prop, receiver);
1924
+ const value = Reflect.get(target, prop, receiver);
1925
+ if (typeof value === "function") return value.bind(target);
1926
+ if (tracker.isTracking && isGetter(target, prop)) {
1927
+ tracker.getterState.currentlyAccessing.add(prop);
1928
+ if (tracker.getterState.cacheValid && tracker.getterState.renderCache.has(prop)) {
1929
+ const cachedValue = tracker.getterState.renderCache.get(prop);
1930
+ tracker.getterState.trackedValues.set(prop, cachedValue);
1931
+ return cachedValue;
1932
+ }
1933
+ const context = getGetterExecutionContext();
1934
+ if (context.depth >= MAX_GETTER_DEPTH) {
1935
+ console.warn(`${BLAC_ERROR_PREFIX} Maximum getter depth (${MAX_GETTER_DEPTH}) exceeded. Possible circular dependency in getter "${String(prop)}" on ${target.constructor.name}.`);
1936
+ return;
1937
+ }
1938
+ if (context.visitedBlocs.has(target)) {
1939
+ console.warn(`${BLAC_ERROR_PREFIX} Circular dependency detected: getter "${String(prop)}" on ${target.constructor.name}.`);
1940
+ return;
1941
+ }
1942
+ const prevContext = {
1943
+ tracker: context.tracker,
1944
+ currentBloc: context.currentBloc,
1945
+ depth: context.depth,
1946
+ visitedBlocs: new Set(context.visitedBlocs)
1947
+ };
1948
+ context.tracker = tracker.getterState;
1949
+ context.currentBloc = target;
1950
+ context.depth++;
1951
+ context.visitedBlocs.add(target);
1952
+ try {
1953
+ const getterValue = getDescriptor(target, prop).get.call(target);
1954
+ tracker.getterState.trackedValues.set(prop, getterValue);
1955
+ return getterValue;
1956
+ } catch (error$1) {
1957
+ tracker.getterState.currentlyAccessing.delete(prop);
1958
+ throw error$1;
1959
+ } finally {
1960
+ context.tracker = prevContext.tracker;
1961
+ context.currentBloc = prevContext.currentBloc;
1962
+ context.depth = prevContext.depth;
1963
+ context.visitedBlocs = prevContext.visitedBlocs;
1964
+ }
1965
+ }
1966
+ return value;
1967
+ } });
1968
+ }
1969
+
1970
+ //#endregion
1971
+ //#region src/tracking/dependency-manager.ts
1972
+ /**
1973
+ * Manages subscriptions to state container dependencies.
1974
+ * Provides efficient sync mechanism to add/remove subscriptions
1975
+ * as dependencies change between callback invocations.
1976
+ */
1977
+ var DependencyManager = class {
1978
+ constructor() {
1979
+ this.subscriptions = /* @__PURE__ */ new Map();
1980
+ this.currentDeps = /* @__PURE__ */ new Set();
1981
+ }
1982
+ /**
1983
+ * Sync subscriptions with a new set of dependencies.
1984
+ * Adds subscriptions for new deps, removes subscriptions for stale deps.
1985
+ *
1986
+ * @param newDeps - The new set of dependencies to subscribe to
1987
+ * @param onChange - Callback to invoke when any dependency changes
1988
+ * @param exclude - Optional instance to exclude from subscriptions (e.g., primary bloc)
1989
+ * @returns true if the dependency set changed, false if unchanged
1990
+ */
1991
+ sync(newDeps, onChange, exclude) {
1992
+ const filteredNewDeps = /* @__PURE__ */ new Set();
1993
+ for (const dep of newDeps) if (dep !== exclude && !dep.isDisposed) filteredNewDeps.add(dep);
1994
+ if (this.areSetsEqual(this.currentDeps, filteredNewDeps)) return false;
1995
+ for (const dep of this.currentDeps) if (!filteredNewDeps.has(dep)) {
1996
+ const unsub = this.subscriptions.get(dep);
1997
+ if (unsub) {
1998
+ unsub();
1999
+ this.subscriptions.delete(dep);
2000
+ }
2001
+ }
2002
+ for (const dep of filteredNewDeps) if (!this.currentDeps.has(dep) && !this.subscriptions.has(dep)) {
2003
+ const unsub = dep.subscribe(onChange);
2004
+ this.subscriptions.set(dep, unsub);
2005
+ }
2006
+ this.currentDeps = filteredNewDeps;
2007
+ return true;
2008
+ }
2009
+ /**
2010
+ * Add a single dependency subscription.
2011
+ */
2012
+ add(dep, onChange) {
2013
+ if (this.subscriptions.has(dep) || dep.isDisposed) return;
2014
+ const unsub = dep.subscribe(onChange);
2015
+ this.subscriptions.set(dep, unsub);
2016
+ this.currentDeps.add(dep);
2017
+ }
2018
+ /**
2019
+ * Check if a dependency is currently subscribed.
2020
+ */
2021
+ has(dep) {
2022
+ return this.currentDeps.has(dep);
2023
+ }
2024
+ /**
2025
+ * Get the current set of dependencies.
2026
+ */
2027
+ getDependencies() {
2028
+ return new Set(this.currentDeps);
2029
+ }
2030
+ /**
2031
+ * Clean up all active subscriptions.
2032
+ */
2033
+ cleanup() {
2034
+ for (const unsub of this.subscriptions.values()) unsub();
2035
+ this.subscriptions.clear();
2036
+ this.currentDeps.clear();
2037
+ }
2038
+ areSetsEqual(a, b) {
2039
+ if (a.size !== b.size) return false;
2040
+ for (const item of a) if (!b.has(item)) return false;
2041
+ return true;
2042
+ }
2043
+ };
2044
+
2045
+ //#endregion
2046
+ //#region src/tracking/tracked.ts
2047
+ /**
2048
+ * Run a callback while tracking all bloc dependencies accessed.
2049
+ * Returns both the result and the set of discovered dependencies.
2050
+ *
2051
+ * @example
2052
+ * ```ts
2053
+ * const { result, dependencies } = tracked(() => {
2054
+ * const user = ensure(UserBloc);
2055
+ * return user.fullName; // getter that may access other blocs
2056
+ * });
2057
+ * // dependencies contains UserBloc + any blocs accessed in fullName getter
2058
+ * ```
2059
+ */
2060
+ function tracked(callback, options) {
2061
+ const tracker = createState();
2062
+ startTracking(tracker);
2063
+ let result;
2064
+ try {
2065
+ result = callback();
2066
+ } finally {
2067
+ stopTracking(tracker, { state: null });
2068
+ }
2069
+ const dependencies = new Set(tracker.dependencies);
2070
+ for (const dep of tracker.getterState.externalDependencies) dependencies.add(dep);
2071
+ if (options?.exclude) dependencies.delete(options.exclude);
2072
+ return {
2073
+ result,
2074
+ dependencies
2075
+ };
2076
+ }
2077
+ /**
2078
+ * Context for running tracked callbacks with bloc proxies.
2079
+ * Provides methods to create proxies and check for changes.
2080
+ */
2081
+ var TrackedContext = class {
2082
+ constructor() {
2083
+ this.proxiedBlocs = /* @__PURE__ */ new WeakMap();
2084
+ this.primaryBlocs = /* @__PURE__ */ new Set();
2085
+ this.tracker = createState();
2086
+ }
2087
+ /**
2088
+ * Get a tracking proxy for a bloc instance.
2089
+ * The proxy will track state and getter accesses.
2090
+ */
2091
+ proxy(bloc) {
2092
+ const cached = this.proxiedBlocs.get(bloc);
2093
+ if (cached) return cached;
2094
+ const proxied = createTrackingProxy(bloc, this.tracker);
2095
+ this.proxiedBlocs.set(bloc, proxied);
2096
+ this.primaryBlocs.add(bloc);
2097
+ return proxied;
2098
+ }
2099
+ /**
2100
+ * Start tracking for a new callback execution.
2101
+ */
2102
+ start() {
2103
+ startTracking(this.tracker);
2104
+ }
2105
+ /**
2106
+ * Stop tracking and get discovered dependencies.
2107
+ * Excludes primary blocs (those explicitly proxied via proxy()).
2108
+ */
2109
+ stop() {
2110
+ const allDeps = /* @__PURE__ */ new Set();
2111
+ for (const bloc of this.primaryBlocs) {
2112
+ const deps = stopTracking(this.tracker, bloc);
2113
+ for (const dep of deps) if (!this.primaryBlocs.has(dep)) allDeps.add(dep);
2114
+ }
2115
+ for (const dep of this.tracker.getterState.externalDependencies) if (!this.primaryBlocs.has(dep)) allDeps.add(dep);
2116
+ return allDeps;
2117
+ }
2118
+ /**
2119
+ * Check if any tracked state or getters have changed.
2120
+ */
2121
+ changed() {
2122
+ for (const bloc of this.primaryBlocs) if (hasChanges(this.tracker, bloc)) return true;
2123
+ return false;
2124
+ }
2125
+ /**
2126
+ * Get all primary blocs (those explicitly proxied).
2127
+ */
2128
+ getPrimaryBlocs() {
2129
+ return new Set(this.primaryBlocs);
2130
+ }
2131
+ /**
2132
+ * Reset the context for reuse.
2133
+ */
2134
+ reset() {
2135
+ this.tracker = createState();
2136
+ this.proxiedBlocs = /* @__PURE__ */ new WeakMap();
2137
+ this.primaryBlocs.clear();
2138
+ }
2139
+ };
2140
+ /**
2141
+ * Create a new tracked context for manual control over tracking.
2142
+ */
2143
+ function createTrackedContext() {
2144
+ return new TrackedContext();
1745
2145
  }
1746
2146
 
1747
2147
  //#endregion
@@ -1750,16 +2150,13 @@ function hasTrackedData(tracker) {
1750
2150
  * Manages subscriptions to external bloc dependencies for getter tracking.
1751
2151
  * When a getter accesses another bloc's state, this manager ensures
1752
2152
  * re-renders occur when those external dependencies change.
2153
+ *
2154
+ * @deprecated Use DependencyManager from tracking module instead.
2155
+ * This class is kept for backward compatibility.
1753
2156
  */
1754
- var ExternalDependencyManager = class {
2157
+ var ExternalDepsManager = class {
1755
2158
  constructor() {
1756
- this.subscriptions = [];
1757
- this.previousDeps = /* @__PURE__ */ new Set();
1758
- }
1759
- areDependenciesEqual(oldDeps, newDeps) {
1760
- if (oldDeps.size !== newDeps.size) return false;
1761
- for (const dep of newDeps) if (!oldDeps.has(dep)) return false;
1762
- return true;
2159
+ this.manager = new DependencyManager();
1763
2160
  }
1764
2161
  /**
1765
2162
  * Update subscriptions to external bloc dependencies.
@@ -1769,32 +2166,22 @@ var ExternalDependencyManager = class {
1769
2166
  * @param onGetterChange - Callback to invoke when external dependency changes
1770
2167
  * @returns true if subscriptions were updated, false if unchanged
1771
2168
  */
1772
- updateSubscriptions(getterTracker, rawInstance, onGetterChange) {
1773
- if (!getterTracker?.externalDependencies) return false;
1774
- const currentDeps = getterTracker.externalDependencies;
1775
- if (this.areDependenciesEqual(this.previousDeps, currentDeps)) {
1776
- clearExternalDependencies(getterTracker);
1777
- return false;
1778
- }
1779
- this.cleanup();
1780
- for (const externalBloc of currentDeps) {
1781
- if (externalBloc === rawInstance) continue;
1782
- const unsub = externalBloc.subscribe(() => {
1783
- invalidateRenderCache(getterTracker);
1784
- if (hasGetterChanges(rawInstance, getterTracker)) onGetterChange();
1785
- });
1786
- this.subscriptions.push(unsub);
1787
- }
1788
- this.previousDeps = new Set(currentDeps);
1789
- clearExternalDependencies(getterTracker);
1790
- return true;
2169
+ updateSubscriptions(getterState, rawInstance, onGetterChange) {
2170
+ if (!getterState?.externalDependencies) return false;
2171
+ const currentDeps = getterState.externalDependencies;
2172
+ const onExternalChange = () => {
2173
+ invalidateRenderCache(getterState);
2174
+ if (hasGetterChanges(rawInstance, getterState)) onGetterChange();
2175
+ };
2176
+ const changed = this.manager.sync(currentDeps, onExternalChange, rawInstance);
2177
+ clearExternalDependencies(getterState);
2178
+ return changed;
1791
2179
  }
1792
2180
  /**
1793
2181
  * Clean up all active subscriptions
1794
2182
  */
1795
2183
  cleanup() {
1796
- this.subscriptions.forEach((unsub) => unsub());
1797
- this.subscriptions = [];
2184
+ this.manager.cleanup();
1798
2185
  }
1799
2186
  };
1800
2187
  /**
@@ -1804,21 +2191,21 @@ var ExternalDependencyManager = class {
1804
2191
  * @param adapterState - The adapter state for tracking
1805
2192
  * @returns Subscribe function for use with useSyncExternalStore
1806
2193
  */
1807
- function createAutoTrackSubscribe(instance, adapterState) {
2194
+ function autoTrackSubscribe(instance$1, adapterState) {
1808
2195
  return (callback) => {
1809
- return instance.subscribe(() => {
1810
- const tracker = adapterState.tracker || (adapterState.tracker = createTrackerState());
1811
- const hasStateDeps = tracker.pathCache && tracker.pathCache.size > 0;
1812
- const hasGetterDeps = adapterState.getterTracker && adapterState.getterTracker.trackedGetters.size > 0;
1813
- const isPrimitiveState = instance.state !== null && typeof instance.state !== "object" && typeof instance.state !== "function";
2196
+ return instance$1.subscribe(() => {
2197
+ const depState = adapterState.dependencyState || (adapterState.dependencyState = createDependencyState());
2198
+ const hasStateDeps = depState.pathCache && depState.pathCache.size > 0;
2199
+ const hasGetterDeps = adapterState.getterState && adapterState.getterState.trackedGetters.size > 0;
2200
+ const isPrimitiveState = instance$1.state !== null && typeof instance$1.state !== "object" && typeof instance$1.state !== "function";
1814
2201
  if (!hasStateDeps && !hasGetterDeps && !isPrimitiveState) return;
1815
- let stateChanged = hasChanges(tracker, instance.state);
2202
+ let stateChanged = hasDependencyChanges(depState, instance$1.state);
1816
2203
  if (!hasStateDeps && hasGetterDeps) stateChanged = false;
1817
2204
  if (stateChanged) {
1818
2205
  callback();
1819
2206
  return;
1820
2207
  }
1821
- if (hasGetterChanges(instance, adapterState.getterTracker)) callback();
2208
+ if (hasGetterChanges(instance$1, adapterState.getterState)) callback();
1822
2209
  });
1823
2210
  };
1824
2211
  }
@@ -1830,10 +2217,10 @@ function createAutoTrackSubscribe(instance, adapterState) {
1830
2217
  * @param config - Configuration with dependencies function
1831
2218
  * @returns Subscribe function for use with useSyncExternalStore
1832
2219
  */
1833
- function createManualDepsSubscribe(instance, adapterState, config) {
2220
+ function manualDepsSubscribe(instance$1, adapterState, config) {
1834
2221
  return (callback) => {
1835
- return instance.subscribe(() => {
1836
- const newDeps = config.dependencies(instance.state, instance);
2222
+ return instance$1.subscribe(() => {
2223
+ const newDeps = config.dependencies(instance$1.state, instance$1);
1837
2224
  if (!adapterState.manualDepsCache || !shallowEqual(adapterState.manualDepsCache, newDeps)) {
1838
2225
  adapterState.manualDepsCache = newDeps;
1839
2226
  callback();
@@ -1847,8 +2234,8 @@ function createManualDepsSubscribe(instance, adapterState, config) {
1847
2234
  * @param instance - The state container instance
1848
2235
  * @returns Subscribe function for use with useSyncExternalStore
1849
2236
  */
1850
- function createNoTrackSubscribe(instance) {
1851
- return (callback) => instance.subscribe(callback);
2237
+ function noTrackSubscribe(instance$1) {
2238
+ return (callback) => instance$1.subscribe(callback);
1852
2239
  }
1853
2240
  /**
1854
2241
  * Create a snapshot function for auto-tracking mode.
@@ -1857,18 +2244,18 @@ function createNoTrackSubscribe(instance) {
1857
2244
  * @param adapterState - The adapter state for tracking
1858
2245
  * @returns Snapshot function for use with useSyncExternalStore
1859
2246
  */
1860
- function createAutoTrackSnapshot(instance, adapterState) {
2247
+ function autoTrackSnapshot(instance$1, adapterState) {
1861
2248
  return () => {
1862
- const tracker = adapterState.tracker || (adapterState.tracker = createTrackerState());
1863
- if (hasTrackedData(tracker)) captureTrackedPaths(tracker, instance.state);
1864
- if (adapterState.getterTracker) {
1865
- invalidateRenderCache(adapterState.getterTracker);
1866
- commitTrackedGetters(adapterState.getterTracker);
1867
- adapterState.getterTracker.isTracking = true;
1868
- setActiveTracker(instance, adapterState.getterTracker);
2249
+ const depState = adapterState.dependencyState || (adapterState.dependencyState = createDependencyState());
2250
+ if (hasTrackedData(depState)) capturePaths(depState, instance$1.state);
2251
+ if (adapterState.getterState) {
2252
+ invalidateRenderCache(adapterState.getterState);
2253
+ commitTrackedGetters(adapterState.getterState);
2254
+ adapterState.getterState.isTracking = true;
2255
+ setActiveTracker(instance$1, adapterState.getterState);
1869
2256
  }
1870
- startTracking(tracker);
1871
- return createProxy(tracker, instance.state);
2257
+ startDependency(depState);
2258
+ return createDependencyProxy(depState, instance$1.state);
1872
2259
  };
1873
2260
  }
1874
2261
  /**
@@ -1879,10 +2266,10 @@ function createAutoTrackSnapshot(instance, adapterState) {
1879
2266
  * @param config - Configuration with dependencies function
1880
2267
  * @returns Snapshot function for use with useSyncExternalStore
1881
2268
  */
1882
- function createManualDepsSnapshot(instance, adapterState, config) {
2269
+ function manualDepsSnapshot(instance$1, adapterState, config) {
1883
2270
  return () => {
1884
- adapterState.manualDepsCache = config.dependencies(instance.state, instance);
1885
- return instance.state;
2271
+ adapterState.manualDepsCache = config.dependencies(instance$1.state, instance$1);
2272
+ return instance$1.state;
1886
2273
  };
1887
2274
  }
1888
2275
  /**
@@ -1891,8 +2278,8 @@ function createManualDepsSnapshot(instance, adapterState, config) {
1891
2278
  * @param instance - The state container instance
1892
2279
  * @returns Snapshot function for use with useSyncExternalStore
1893
2280
  */
1894
- function createNoTrackSnapshot(instance) {
1895
- return () => instance.state;
2281
+ function noTrackSnapshot(instance$1) {
2282
+ return () => instance$1.state;
1896
2283
  }
1897
2284
  /**
1898
2285
  * Initialize adapter state for auto-tracking mode.
@@ -1900,12 +2287,12 @@ function createNoTrackSnapshot(instance) {
1900
2287
  * @param instance - The state container instance
1901
2288
  * @returns Initialized adapter state
1902
2289
  */
1903
- function initAutoTrackState(instance) {
2290
+ function autoTrackInit(instance$1) {
1904
2291
  return {
1905
- tracker: null,
2292
+ dependencyState: null,
1906
2293
  manualDepsCache: null,
1907
- getterTracker: createGetterTracker(),
1908
- proxiedBloc: createBlocProxy(instance)
2294
+ getterState: createGetterState(),
2295
+ proxiedBloc: createBlocProxy(instance$1)
1909
2296
  };
1910
2297
  }
1911
2298
  /**
@@ -1914,12 +2301,12 @@ function initAutoTrackState(instance) {
1914
2301
  * @param instance - The state container instance
1915
2302
  * @returns Initialized adapter state
1916
2303
  */
1917
- function initManualDepsState(instance) {
2304
+ function manualDepsInit(instance$1) {
1918
2305
  return {
1919
- tracker: null,
2306
+ dependencyState: null,
1920
2307
  manualDepsCache: null,
1921
- getterTracker: null,
1922
- proxiedBloc: instance
2308
+ getterState: null,
2309
+ proxiedBloc: instance$1
1923
2310
  };
1924
2311
  }
1925
2312
  /**
@@ -1928,12 +2315,12 @@ function initManualDepsState(instance) {
1928
2315
  * @param instance - The state container instance
1929
2316
  * @returns Initialized adapter state
1930
2317
  */
1931
- function initNoTrackState(instance) {
2318
+ function noTrackInit(instance$1) {
1932
2319
  return {
1933
- tracker: null,
2320
+ dependencyState: null,
1934
2321
  manualDepsCache: null,
1935
- getterTracker: null,
1936
- proxiedBloc: instance
2322
+ getterState: null,
2323
+ proxiedBloc: instance$1
1937
2324
  };
1938
2325
  }
1939
2326
  /**
@@ -1943,8 +2330,8 @@ function initNoTrackState(instance) {
1943
2330
  * @param rawInstance - The raw bloc instance
1944
2331
  */
1945
2332
  function disableGetterTracking(adapterState, rawInstance) {
1946
- if (adapterState.getterTracker) {
1947
- adapterState.getterTracker.isTracking = false;
2333
+ if (adapterState.getterState) {
2334
+ adapterState.getterState.isTracking = false;
1948
2335
  clearActiveTracker(rawInstance);
1949
2336
  }
1950
2337
  }
@@ -2170,65 +2557,407 @@ function blac(options) {
2170
2557
  };
2171
2558
  }
2172
2559
 
2560
+ //#endregion
2561
+ //#region src/registry/acquire.ts
2562
+ function acquire(BlocClass, instanceKey, options) {
2563
+ return globalRegistry.acquire(BlocClass, instanceKey, {
2564
+ canCreate: true,
2565
+ countRef: true,
2566
+ props: options?.props
2567
+ });
2568
+ }
2569
+
2570
+ //#endregion
2571
+ //#region src/registry/borrow.ts
2572
+ function borrow(BlocClass, instanceKey) {
2573
+ return globalRegistry.borrow(BlocClass, instanceKey);
2574
+ }
2575
+ function borrowSafe(BlocClass, instanceKey) {
2576
+ return globalRegistry.borrowSafe(BlocClass, instanceKey);
2577
+ }
2578
+
2579
+ //#endregion
2580
+ //#region src/registry/ensure.ts
2581
+ function ensure(BlocClass, instanceKey) {
2582
+ return globalRegistry.ensure(BlocClass, instanceKey);
2583
+ }
2584
+
2585
+ //#endregion
2586
+ //#region src/registry/release.ts
2587
+ function release(BlocClass, instanceKey, forceDispose = false) {
2588
+ globalRegistry.release(BlocClass, instanceKey, forceDispose);
2589
+ }
2590
+
2591
+ //#endregion
2592
+ //#region src/registry/queries.ts
2593
+ function hasInstance(BlocClass, instanceKey) {
2594
+ return globalRegistry.hasInstance(BlocClass, instanceKey);
2595
+ }
2596
+ function getRefCount(BlocClass, instanceKey) {
2597
+ return globalRegistry.getRefCount(BlocClass, instanceKey);
2598
+ }
2599
+ function getAll(BlocClass) {
2600
+ return globalRegistry.getAll(BlocClass);
2601
+ }
2602
+ function forEach(BlocClass, callback) {
2603
+ globalRegistry.forEach(BlocClass, callback);
2604
+ }
2605
+
2606
+ //#endregion
2607
+ //#region src/registry/management.ts
2608
+ function clear(BlocClass) {
2609
+ globalRegistry.clear(BlocClass);
2610
+ }
2611
+ function clearAll() {
2612
+ globalRegistry.clearAll();
2613
+ }
2614
+ function register(BlocClass, isolated = false) {
2615
+ globalRegistry.register(BlocClass, isolated);
2616
+ }
2617
+
2618
+ //#endregion
2619
+ //#region src/registry/config.ts
2620
+ let _registry = globalRegistry;
2621
+ function getRegistry() {
2622
+ return _registry;
2623
+ }
2624
+ function setRegistry(registry) {
2625
+ _registry.clearAll();
2626
+ _registry = registry;
2627
+ }
2628
+ function getStats() {
2629
+ return _registry.getStats();
2630
+ }
2631
+
2632
+ //#endregion
2633
+ //#region src/waitUntil/errors.ts
2634
+ var WaitUntilTimeoutError = class extends Error {
2635
+ constructor(timeout) {
2636
+ super(`waitUntil timed out after ${timeout}ms`);
2637
+ this.name = "WaitUntilTimeoutError";
2638
+ }
2639
+ };
2640
+ var WaitUntilAbortedError = class extends Error {
2641
+ constructor() {
2642
+ super("waitUntil was aborted");
2643
+ this.name = "WaitUntilAbortedError";
2644
+ }
2645
+ };
2646
+ var WaitUntilDisposedError = class extends Error {
2647
+ constructor(blocName) {
2648
+ super(`waitUntil failed: ${blocName} was disposed while waiting`);
2649
+ this.name = "WaitUntilDisposedError";
2650
+ }
2651
+ };
2652
+
2653
+ //#endregion
2654
+ //#region src/waitUntil/waitUntil.ts
2655
+ function waitUntil(BlocClass, selectorOrPredicate, predicateOrOptions, maybeOptions) {
2656
+ if (typeof predicateOrOptions !== "function") return waitUntilSimple(BlocClass, selectorOrPredicate, predicateOrOptions);
2657
+ else return waitUntilSelector(BlocClass, selectorOrPredicate, predicateOrOptions, maybeOptions);
2658
+ }
2659
+ function waitUntilSimple(BlocClass, predicate, options) {
2660
+ const { instanceId = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, timeout, signal } = options ?? {};
2661
+ return new Promise((resolve, reject) => {
2662
+ if (signal?.aborted) {
2663
+ reject(new WaitUntilAbortedError());
2664
+ return;
2665
+ }
2666
+ const bloc = ensure(BlocClass, instanceId);
2667
+ if (bloc.isDisposed) {
2668
+ reject(new WaitUntilDisposedError(BlocClass.name));
2669
+ return;
2670
+ }
2671
+ const tracker = createState();
2672
+ const proxiedBloc = createTrackingProxy(bloc, tracker);
2673
+ const externalDepsManager = new DependencyManager();
2674
+ const runPredicate = () => {
2675
+ startTracking(tracker);
2676
+ try {
2677
+ return predicate(proxiedBloc);
2678
+ } finally {
2679
+ const deps = stopTracking(tracker, bloc);
2680
+ for (const dep of tracker.getterState.externalDependencies) deps.add(dep);
2681
+ deps.delete(bloc);
2682
+ externalDepsManager.sync(deps, checkCondition, bloc);
2683
+ }
2684
+ };
2685
+ if (runPredicate()) {
2686
+ resolve(bloc);
2687
+ return;
2688
+ }
2689
+ let unsubscribe = null;
2690
+ let unsubscribeDispose = null;
2691
+ let timeoutId = null;
2692
+ let abortHandler = null;
2693
+ const cleanup = () => {
2694
+ unsubscribe?.();
2695
+ unsubscribeDispose?.();
2696
+ externalDepsManager.cleanup();
2697
+ if (timeoutId) clearTimeout(timeoutId);
2698
+ if (abortHandler && signal) signal.removeEventListener("abort", abortHandler);
2699
+ };
2700
+ function checkCondition() {
2701
+ try {
2702
+ if (runPredicate()) {
2703
+ cleanup();
2704
+ resolve(bloc);
2705
+ }
2706
+ } catch (error$1) {
2707
+ cleanup();
2708
+ reject(error$1);
2709
+ }
2710
+ }
2711
+ unsubscribe = bloc.subscribe(checkCondition);
2712
+ unsubscribeDispose = getRegistry().on("disposed", (instance$1) => {
2713
+ if (instance$1 === bloc) {
2714
+ cleanup();
2715
+ reject(new WaitUntilDisposedError(BlocClass.name));
2716
+ }
2717
+ });
2718
+ if (timeout !== void 0) timeoutId = setTimeout(() => {
2719
+ cleanup();
2720
+ reject(new WaitUntilTimeoutError(timeout));
2721
+ }, timeout);
2722
+ if (signal) {
2723
+ abortHandler = () => {
2724
+ cleanup();
2725
+ reject(new WaitUntilAbortedError());
2726
+ };
2727
+ signal.addEventListener("abort", abortHandler);
2728
+ }
2729
+ });
2730
+ }
2731
+ function waitUntilSelector(BlocClass, selector, predicate, options) {
2732
+ const { instanceId = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, timeout, signal } = options ?? {};
2733
+ return new Promise((resolve, reject) => {
2734
+ if (signal?.aborted) {
2735
+ reject(new WaitUntilAbortedError());
2736
+ return;
2737
+ }
2738
+ const bloc = ensure(BlocClass, instanceId);
2739
+ if (bloc.isDisposed) {
2740
+ reject(new WaitUntilDisposedError(BlocClass.name));
2741
+ return;
2742
+ }
2743
+ const tracker = createState();
2744
+ const proxiedBloc = createTrackingProxy(bloc, tracker);
2745
+ const externalDepsManager = new DependencyManager();
2746
+ const runSelector = () => {
2747
+ startTracking(tracker);
2748
+ try {
2749
+ const value = selector(proxiedBloc);
2750
+ return {
2751
+ value,
2752
+ matches: predicate(value)
2753
+ };
2754
+ } finally {
2755
+ const deps = stopTracking(tracker, bloc);
2756
+ for (const dep of tracker.getterState.externalDependencies) deps.add(dep);
2757
+ deps.delete(bloc);
2758
+ externalDepsManager.sync(deps, checkCondition, bloc);
2759
+ }
2760
+ };
2761
+ const initial = runSelector();
2762
+ if (initial.matches) {
2763
+ resolve(initial.value);
2764
+ return;
2765
+ }
2766
+ let unsubscribe = null;
2767
+ let unsubscribeDispose = null;
2768
+ let timeoutId = null;
2769
+ let abortHandler = null;
2770
+ const cleanup = () => {
2771
+ unsubscribe?.();
2772
+ unsubscribeDispose?.();
2773
+ externalDepsManager.cleanup();
2774
+ if (timeoutId) clearTimeout(timeoutId);
2775
+ if (abortHandler && signal) signal.removeEventListener("abort", abortHandler);
2776
+ };
2777
+ function checkCondition() {
2778
+ try {
2779
+ const result = runSelector();
2780
+ if (result.matches) {
2781
+ cleanup();
2782
+ resolve(result.value);
2783
+ }
2784
+ } catch (error$1) {
2785
+ cleanup();
2786
+ reject(error$1);
2787
+ }
2788
+ }
2789
+ unsubscribe = bloc.subscribe(checkCondition);
2790
+ unsubscribeDispose = getRegistry().on("disposed", (instance$1) => {
2791
+ if (instance$1 === bloc) {
2792
+ cleanup();
2793
+ reject(new WaitUntilDisposedError(BlocClass.name));
2794
+ }
2795
+ });
2796
+ if (timeout !== void 0) timeoutId = setTimeout(() => {
2797
+ cleanup();
2798
+ reject(new WaitUntilTimeoutError(timeout));
2799
+ }, timeout);
2800
+ if (signal) {
2801
+ abortHandler = () => {
2802
+ cleanup();
2803
+ reject(new WaitUntilAbortedError());
2804
+ };
2805
+ signal.addEventListener("abort", abortHandler);
2806
+ }
2807
+ });
2808
+ }
2809
+
2810
+ //#endregion
2811
+ //#region src/watch/watch.ts
2812
+ const STOP = Symbol("watch.STOP");
2813
+ const BLOC_REF_MARKER = Symbol("BlocRef");
2814
+ /**
2815
+ * Create a reference to a specific bloc instance.
2816
+ *
2817
+ * @example
2818
+ * ```ts
2819
+ * watch(instance(UserBloc, 'user-123'), (userBloc) => {
2820
+ * console.log(userBloc.state.name);
2821
+ * });
2822
+ * ```
2823
+ */
2824
+ function instance(BlocClass, instanceId) {
2825
+ return {
2826
+ [BLOC_REF_MARKER]: true,
2827
+ blocClass: BlocClass,
2828
+ instanceId
2829
+ };
2830
+ }
2831
+ function isBlocRef(input) {
2832
+ return typeof input === "object" && input !== null && BLOC_REF_MARKER in input;
2833
+ }
2834
+ function resolveBloc(input) {
2835
+ if (isBlocRef(input)) return ensure(input.blocClass, input.instanceId);
2836
+ return ensure(input, BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY);
2837
+ }
2838
+ function isArray(input) {
2839
+ return Array.isArray(input);
2840
+ }
2841
+ function watchImpl(blocsOrBloc, callback) {
2842
+ const isSingle = !isArray(blocsOrBloc);
2843
+ const instances = (isSingle ? [blocsOrBloc] : blocsOrBloc).map(resolveBloc);
2844
+ const tracker = createState();
2845
+ const proxiedInstances = instances.map((inst) => createTrackingProxy(inst, tracker));
2846
+ const externalDepsManager = new DependencyManager();
2847
+ let disposed = false;
2848
+ const primarySubscriptions = [];
2849
+ const cleanup = () => {
2850
+ if (disposed) return;
2851
+ disposed = true;
2852
+ primarySubscriptions.forEach((unsub) => unsub());
2853
+ externalDepsManager.cleanup();
2854
+ };
2855
+ const runCallback = () => {
2856
+ if (disposed) return;
2857
+ startTracking(tracker);
2858
+ let result;
2859
+ try {
2860
+ result = callback(isSingle ? proxiedInstances[0] : proxiedInstances);
2861
+ } finally {
2862
+ const externalDeps = /* @__PURE__ */ new Set();
2863
+ for (const inst of instances) {
2864
+ const deps = stopTracking(tracker, inst);
2865
+ for (const dep of deps) externalDeps.add(dep);
2866
+ }
2867
+ for (const dep of tracker.getterState.externalDependencies) externalDeps.add(dep);
2868
+ for (const inst of instances) externalDeps.delete(inst);
2869
+ externalDepsManager.sync(externalDeps, runCallback);
2870
+ }
2871
+ if (result === STOP) cleanup();
2872
+ };
2873
+ const onChange = () => {
2874
+ if (disposed) return;
2875
+ runCallback();
2876
+ };
2877
+ for (const inst of instances) primarySubscriptions.push(inst.subscribe(onChange));
2878
+ runCallback();
2879
+ return cleanup;
2880
+ }
2881
+ const watch = Object.assign(watchImpl, { STOP });
2882
+
2173
2883
  //#endregion
2174
2884
  exports.BLAC_DEFAULTS = BLAC_DEFAULTS;
2175
2885
  exports.BLAC_ERROR_PREFIX = BLAC_ERROR_PREFIX;
2176
2886
  exports.BLAC_ID_PATTERNS = BLAC_ID_PATTERNS;
2177
2887
  exports.BLAC_STATIC_PROPS = BLAC_STATIC_PROPS;
2178
2888
  exports.Cubit = Cubit;
2179
- exports.ExternalDependencyManager = ExternalDependencyManager;
2889
+ exports.DependencyManager = DependencyManager;
2890
+ exports.ExternalDepsManager = ExternalDepsManager;
2180
2891
  exports.LogLevel = LogLevel;
2181
2892
  exports.PluginManager = PluginManager;
2893
+ exports.STATELESS_MARKER = STATELESS_MARKER;
2182
2894
  exports.StateContainer = StateContainer;
2183
2895
  exports.StateContainerRegistry = StateContainerRegistry;
2896
+ exports.StatelessCubit = StatelessCubit;
2897
+ exports.StatelessVertex = StatelessVertex;
2898
+ exports.TrackedContext = TrackedContext;
2184
2899
  exports.Vertex = Vertex;
2900
+ exports.WaitUntilAbortedError = WaitUntilAbortedError;
2901
+ exports.WaitUntilDisposedError = WaitUntilDisposedError;
2902
+ exports.WaitUntilTimeoutError = WaitUntilTimeoutError;
2185
2903
  exports.__resetIdCounters = __resetIdCounters;
2904
+ exports.acquire = acquire;
2905
+ exports.autoTrackInit = autoTrackInit;
2906
+ exports.autoTrackSnapshot = autoTrackSnapshot;
2907
+ exports.autoTrackSubscribe = autoTrackSubscribe;
2186
2908
  exports.blac = blac;
2187
- exports.captureTrackedPaths = captureTrackedPaths;
2909
+ exports.borrow = borrow;
2910
+ exports.borrowSafe = borrowSafe;
2911
+ exports.capturePaths = capturePaths;
2912
+ exports.clear = clear;
2188
2913
  exports.clearActiveTracker = clearActiveTracker;
2914
+ exports.clearAll = clearAll;
2189
2915
  exports.clearExternalDependencies = clearExternalDependencies;
2190
2916
  exports.commitTrackedGetters = commitTrackedGetters;
2191
2917
  exports.configureBlac = configureBlac;
2192
2918
  exports.configureLogger = configureLogger;
2193
2919
  exports.createArrayProxy = createArrayProxy;
2194
- exports.createAutoTrackSnapshot = createAutoTrackSnapshot;
2195
- exports.createAutoTrackSubscribe = createAutoTrackSubscribe;
2196
2920
  exports.createBlocProxy = createBlocProxy;
2197
- exports.createGetterTracker = createGetterTracker;
2921
+ exports.createDependencyProxy = createDependencyProxy;
2922
+ exports.createDependencyState = createDependencyState;
2923
+ exports.createForTarget = createForTarget;
2924
+ exports.createGetterState = createGetterState;
2198
2925
  exports.createIdGenerator = createIdGenerator;
2926
+ exports.createInternal = createInternal;
2199
2927
  exports.createLogger = createLogger;
2200
- exports.createManualDepsSnapshot = createManualDepsSnapshot;
2201
- exports.createManualDepsSubscribe = createManualDepsSubscribe;
2202
- exports.createNoTrackSnapshot = createNoTrackSnapshot;
2203
- exports.createNoTrackSubscribe = createNoTrackSubscribe;
2204
2928
  exports.createPluginManager = createPluginManager;
2205
- exports.createProxy = createProxy;
2206
- exports.createProxyForTarget = createProxyForTarget;
2207
- exports.createProxyInternal = createProxyInternal;
2208
- exports.createProxyTrackerState = createProxyTrackerState;
2209
- exports.createTrackerState = createTrackerState;
2929
+ exports.createProxyState = createProxyState;
2930
+ exports.createTrackedContext = createTrackedContext;
2931
+ exports.createTrackingProxy = createTrackingProxy;
2932
+ exports.createTrackingProxyState = createState;
2210
2933
  exports.debug = debug;
2211
2934
  exports.disableGetterTracking = disableGetterTracking;
2935
+ exports.ensure = ensure;
2212
2936
  exports.error = error;
2937
+ exports.forEach = forEach;
2213
2938
  exports.generateId = generateId;
2214
2939
  exports.generateIsolatedKey = generateIsolatedKey;
2215
2940
  exports.generateSimpleId = generateSimpleId;
2216
2941
  exports.getActiveTracker = getActiveTracker;
2942
+ exports.getAll = getAll;
2217
2943
  exports.getBlacConfig = getBlacConfig;
2218
2944
  exports.getDescriptor = getDescriptor;
2219
2945
  exports.getGetterExecutionContext = getGetterExecutionContext;
2220
2946
  exports.getPluginManager = getPluginManager;
2947
+ exports.getRefCount = getRefCount;
2948
+ exports.getRegistry = getRegistry;
2221
2949
  exports.getStaticProp = getStaticProp;
2950
+ exports.getStats = getStats;
2222
2951
  exports.getValueAtPath = getValueAtPath;
2223
2952
  exports.globalRegistry = globalRegistry;
2224
- exports.hasChanges = hasChanges;
2953
+ exports.hasDependencyChanges = hasDependencyChanges;
2225
2954
  exports.hasGetterChanges = hasGetterChanges;
2226
2955
  exports.hasInitHook = hasInitHook;
2956
+ exports.hasInstance = hasInstance;
2227
2957
  exports.hasTrackedData = hasTrackedData;
2958
+ exports.hasTrackingProxyChanges = hasChanges;
2228
2959
  exports.info = info;
2229
- exports.initAutoTrackState = initAutoTrackState;
2230
- exports.initManualDepsState = initManualDepsState;
2231
- exports.initNoTrackState = initNoTrackState;
2960
+ exports.instance = instance;
2232
2961
  exports.invalidateRenderCache = invalidateRenderCache;
2233
2962
  exports.isDevMode = isDevMode;
2234
2963
  exports.isExcludedFromDevTools = isExcludedFromDevTools;
@@ -2237,13 +2966,28 @@ exports.isIsolatedClass = isIsolatedClass;
2237
2966
  exports.isIsolatedKey = isIsolatedKey;
2238
2967
  exports.isKeepAliveClass = isKeepAliveClass;
2239
2968
  exports.isProxyable = isProxyable;
2969
+ exports.isStatelessClass = isStatelessClass;
2970
+ exports.manualDepsInit = manualDepsInit;
2971
+ exports.manualDepsSnapshot = manualDepsSnapshot;
2972
+ exports.manualDepsSubscribe = manualDepsSubscribe;
2973
+ exports.noTrackInit = noTrackInit;
2974
+ exports.noTrackSnapshot = noTrackSnapshot;
2975
+ exports.noTrackSubscribe = noTrackSubscribe;
2240
2976
  exports.parsePath = parsePath;
2977
+ exports.register = register;
2978
+ exports.release = release;
2241
2979
  exports.resetBlacConfig = resetBlacConfig;
2242
- exports.resetGetterTracker = resetGetterTracker;
2980
+ exports.resetGetterState = resetGetterState;
2243
2981
  exports.setActiveTracker = setActiveTracker;
2982
+ exports.setRegistry = setRegistry;
2244
2983
  exports.shallowEqual = shallowEqual;
2245
- exports.startProxyTracking = startProxyTracking;
2246
- exports.startTracking = startTracking;
2247
- exports.stopProxyTracking = stopProxyTracking;
2984
+ exports.startDependency = startDependency;
2985
+ exports.startProxy = startProxy;
2986
+ exports.startTrackingProxy = startTracking;
2987
+ exports.stopProxy = stopProxy;
2988
+ exports.stopTrackingProxy = stopTracking;
2989
+ exports.tracked = tracked;
2990
+ exports.waitUntil = waitUntil;
2248
2991
  exports.warn = warn;
2992
+ exports.watch = watch;
2249
2993
  //# sourceMappingURL=index.cjs.map