@blac/core 2.0.0-rc.13 → 2.0.0-rc.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +105 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +133 -91
- package/dist/index.d.ts +133 -91
- package/dist/index.js +105 -69
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -276,6 +276,8 @@ var PluginManager = class {
|
|
|
276
276
|
};
|
|
277
277
|
/**
|
|
278
278
|
* Create a plugin manager instance
|
|
279
|
+
* @param registry - The StateContainerRegistry to monitor for lifecycle events
|
|
280
|
+
* @returns A new PluginManager instance
|
|
279
281
|
*/
|
|
280
282
|
function createPluginManager(registry) {
|
|
281
283
|
return new PluginManager(registry);
|
|
@@ -527,22 +529,28 @@ function getStaticProp(Type, propName, defaultValue) {
|
|
|
527
529
|
return Type[propName] ?? defaultValue;
|
|
528
530
|
}
|
|
529
531
|
/**
|
|
530
|
-
* Check if a class is marked as isolated
|
|
531
|
-
* Isolated classes create separate instances per component
|
|
532
|
+
* Check if a class is marked as isolated.
|
|
533
|
+
* Isolated classes create separate instances per component.
|
|
534
|
+
* @param Type - The class constructor to check
|
|
535
|
+
* @returns true if the class has `static isolated = true`
|
|
532
536
|
*/
|
|
533
537
|
function isIsolatedClass(Type) {
|
|
534
538
|
return getStaticProp(Type, BLAC_STATIC_PROPS.ISOLATED) === true;
|
|
535
539
|
}
|
|
536
540
|
/**
|
|
537
|
-
* Check if a class is marked as keepAlive
|
|
538
|
-
* KeepAlive classes are never auto-disposed when ref count reaches 0
|
|
541
|
+
* Check if a class is marked as keepAlive.
|
|
542
|
+
* KeepAlive classes are never auto-disposed when ref count reaches 0.
|
|
543
|
+
* @param Type - The class constructor to check
|
|
544
|
+
* @returns true if the class has `static keepAlive = true`
|
|
539
545
|
*/
|
|
540
546
|
function isKeepAliveClass(Type) {
|
|
541
547
|
return getStaticProp(Type, BLAC_STATIC_PROPS.KEEP_ALIVE) === true;
|
|
542
548
|
}
|
|
543
549
|
/**
|
|
544
|
-
* Check if a class should be excluded from DevTools
|
|
545
|
-
* Used to prevent infinite loops when DevTools tracks itself
|
|
550
|
+
* Check if a class should be excluded from DevTools.
|
|
551
|
+
* Used to prevent infinite loops when DevTools tracks itself.
|
|
552
|
+
* @param Type - The class constructor to check
|
|
553
|
+
* @returns true if the class has `static __excludeFromDevTools = true`
|
|
546
554
|
*/
|
|
547
555
|
function isExcludedFromDevTools(Type) {
|
|
548
556
|
return getStaticProp(Type, BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS) === true;
|
|
@@ -604,97 +612,111 @@ var StateContainerRegistry = class {
|
|
|
604
612
|
getInstancesMap(Type) {
|
|
605
613
|
return this.instancesByConstructor.get(Type) || /* @__PURE__ */ new Map();
|
|
606
614
|
}
|
|
615
|
+
trackExecutionContext(instance) {
|
|
616
|
+
const context = getGetterExecutionContext();
|
|
617
|
+
if (context.tracker && context.currentBloc && context.currentBloc !== instance) context.tracker.externalDependencies.add(instance);
|
|
618
|
+
}
|
|
607
619
|
/**
|
|
608
|
-
* Resolve an instance with ref counting (ownership semantics)
|
|
620
|
+
* Resolve an instance with ref counting (ownership semantics).
|
|
621
|
+
* Creates a new instance if one doesn't exist, or returns existing and increments ref count.
|
|
622
|
+
* @param Type - The StateContainer class constructor
|
|
623
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
624
|
+
* @param options - Resolution options
|
|
625
|
+
* @param options.canCreate - Whether to create new instance if not found (default: true)
|
|
626
|
+
* @param options.countRef - Whether to increment ref count (default: true)
|
|
627
|
+
* @param options.props - Props to pass to constructor if creating new instance
|
|
628
|
+
* @param options.trackExecutionContext - Whether to track cross-bloc dependency (default: false)
|
|
629
|
+
* @returns The state container instance
|
|
609
630
|
*/
|
|
610
|
-
resolve(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY,
|
|
631
|
+
resolve(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, options = {}) {
|
|
632
|
+
const { canCreate = true, countRef = true, props, trackExecutionContext = false } = options;
|
|
611
633
|
const registryConfig = this.typeConfigs.get(Type.name);
|
|
612
634
|
const isolated = isIsolatedClass(Type) || registryConfig?.isolated === true;
|
|
613
635
|
const config = { instanceId: instanceKey };
|
|
636
|
+
if (isolated && !canCreate) throw new Error(`${BLAC_ERROR_PREFIX} Cannot get isolated instance "${instanceKey}" of ${Type.name} when creation is disabled.`);
|
|
614
637
|
if (isolated) {
|
|
615
|
-
const instance$1 = new Type(
|
|
638
|
+
const instance$1 = new Type(props);
|
|
616
639
|
instance$1.initConfig(config);
|
|
617
640
|
this.registerType(Type);
|
|
641
|
+
if (trackExecutionContext) this.trackExecutionContext(instance$1);
|
|
618
642
|
return instance$1;
|
|
619
643
|
}
|
|
620
644
|
const instances = this.ensureInstancesMap(Type);
|
|
621
645
|
const entry = instances.get(instanceKey);
|
|
646
|
+
if (entry && (countRef || entry.refCount === 0)) entry.refCount++;
|
|
622
647
|
if (entry) {
|
|
623
|
-
entry.
|
|
648
|
+
if (trackExecutionContext) this.trackExecutionContext(entry.instance);
|
|
624
649
|
return entry.instance;
|
|
625
650
|
}
|
|
626
|
-
|
|
651
|
+
if (!canCreate) throw new Error(`${BLAC_ERROR_PREFIX} ${Type.name} instance "${instanceKey}" not found and creation is disabled.`);
|
|
652
|
+
const instance = new Type(props);
|
|
627
653
|
instance.initConfig(config);
|
|
628
654
|
instances.set(instanceKey, {
|
|
629
655
|
instance,
|
|
630
656
|
refCount: 1
|
|
631
657
|
});
|
|
632
658
|
this.registerType(Type);
|
|
659
|
+
if (trackExecutionContext) this.trackExecutionContext(instance);
|
|
633
660
|
return instance;
|
|
634
661
|
}
|
|
635
662
|
/**
|
|
636
|
-
* Get an existing instance without ref
|
|
663
|
+
* Get an existing instance without incrementing ref count (borrowing semantics).
|
|
664
|
+
* Tracks cross-bloc dependency for reactive updates.
|
|
665
|
+
* @param Type - The StateContainer class constructor
|
|
666
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
667
|
+
* @returns The state container instance
|
|
637
668
|
* @throws Error if instance doesn't exist
|
|
638
669
|
*/
|
|
639
670
|
get(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
return entry.instance;
|
|
671
|
+
return this.resolve(Type, instanceKey, {
|
|
672
|
+
canCreate: false,
|
|
673
|
+
trackExecutionContext: true
|
|
674
|
+
});
|
|
645
675
|
}
|
|
646
676
|
/**
|
|
647
|
-
* Safely get an existing instance (borrowing semantics with error handling)
|
|
648
|
-
* Returns discriminated union for type-safe conditional access
|
|
677
|
+
* Safely get an existing instance (borrowing semantics with error handling).
|
|
678
|
+
* Returns discriminated union for type-safe conditional access.
|
|
679
|
+
* @param Type - The StateContainer class constructor
|
|
680
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
681
|
+
* @returns Discriminated union with either the instance or an error
|
|
649
682
|
*/
|
|
650
683
|
getSafe(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
}
|
|
684
|
+
try {
|
|
685
|
+
return {
|
|
686
|
+
error: null,
|
|
687
|
+
instance: this.get(Type, instanceKey)
|
|
688
|
+
};
|
|
689
|
+
} catch (error$1) {
|
|
690
|
+
return {
|
|
691
|
+
error: error$1,
|
|
692
|
+
instance: null
|
|
693
|
+
};
|
|
694
|
+
}
|
|
662
695
|
}
|
|
663
696
|
/**
|
|
664
|
-
* Connect to an instance with borrowing semantics (for B2B communication)
|
|
697
|
+
* Connect to an instance with borrowing semantics (for B2B communication).
|
|
665
698
|
* Gets existing instance OR creates it if it doesn't exist, without incrementing ref count.
|
|
666
699
|
* Tracks cross-bloc dependency for reactive updates.
|
|
667
700
|
*
|
|
668
701
|
* Use this in bloc-to-bloc communication when you need to ensure an instance exists
|
|
669
702
|
* but don't want to claim ownership (no ref count increment).
|
|
670
|
-
*
|
|
671
|
-
* @param
|
|
672
|
-
* @
|
|
673
|
-
* @param constructorArgs - Constructor arguments (only used if creating new instance)
|
|
674
|
-
* @returns The bloc instance
|
|
703
|
+
* @param Type - The StateContainer class constructor
|
|
704
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
705
|
+
* @returns The state container instance
|
|
675
706
|
*/
|
|
676
|
-
connect(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const instance = new Type(constructorArgs);
|
|
683
|
-
const config = { instanceId: instanceKey };
|
|
684
|
-
instance.initConfig(config);
|
|
685
|
-
entry = {
|
|
686
|
-
instance,
|
|
687
|
-
refCount: 1
|
|
688
|
-
};
|
|
689
|
-
instances.set(instanceKey, entry);
|
|
690
|
-
this.registerType(Type);
|
|
691
|
-
}
|
|
692
|
-
const context = getGetterExecutionContext();
|
|
693
|
-
if (context.tracker && context.currentBloc && context.currentBloc !== entry.instance) context.tracker.externalDependencies.add(entry.instance);
|
|
694
|
-
return entry.instance;
|
|
707
|
+
connect(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
|
|
708
|
+
return this.resolve(Type, instanceKey, {
|
|
709
|
+
canCreate: true,
|
|
710
|
+
countRef: false,
|
|
711
|
+
trackExecutionContext: true
|
|
712
|
+
});
|
|
695
713
|
}
|
|
696
714
|
/**
|
|
697
|
-
* Release a reference to an instance
|
|
715
|
+
* Release a reference to an instance.
|
|
716
|
+
* Decrements ref count and disposes when it reaches 0 (unless keepAlive).
|
|
717
|
+
* @param Type - The StateContainer class constructor
|
|
718
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
719
|
+
* @param forceDispose - Force immediate disposal regardless of ref count
|
|
698
720
|
*/
|
|
699
721
|
release(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY, forceDispose = false) {
|
|
700
722
|
const instances = this.ensureInstancesMap(Type);
|
|
@@ -713,7 +735,9 @@ var StateContainerRegistry = class {
|
|
|
713
735
|
}
|
|
714
736
|
}
|
|
715
737
|
/**
|
|
716
|
-
* Get all instances of a specific type
|
|
738
|
+
* Get all instances of a specific type.
|
|
739
|
+
* @param Type - The StateContainer class constructor
|
|
740
|
+
* @returns Array of all instances
|
|
717
741
|
*/
|
|
718
742
|
getAll(Type) {
|
|
719
743
|
const instances = this.ensureInstancesMap(Type);
|
|
@@ -722,7 +746,10 @@ var StateContainerRegistry = class {
|
|
|
722
746
|
return result;
|
|
723
747
|
}
|
|
724
748
|
/**
|
|
725
|
-
* Safely iterate over all instances of a type
|
|
749
|
+
* Safely iterate over all instances of a type.
|
|
750
|
+
* Skips disposed instances and catches callback errors.
|
|
751
|
+
* @param Type - The StateContainer class constructor
|
|
752
|
+
* @param callback - Function to call for each instance
|
|
726
753
|
*/
|
|
727
754
|
forEach(Type, callback) {
|
|
728
755
|
const instances = this.ensureInstancesMap(Type);
|
|
@@ -736,7 +763,8 @@ var StateContainerRegistry = class {
|
|
|
736
763
|
}
|
|
737
764
|
}
|
|
738
765
|
/**
|
|
739
|
-
* Clear all instances of a specific type
|
|
766
|
+
* Clear all instances of a specific type (disposes them).
|
|
767
|
+
* @param Type - The StateContainer class constructor
|
|
740
768
|
*/
|
|
741
769
|
clear(Type) {
|
|
742
770
|
const instances = this.ensureInstancesMap(Type);
|
|
@@ -744,13 +772,19 @@ var StateContainerRegistry = class {
|
|
|
744
772
|
instances.clear();
|
|
745
773
|
}
|
|
746
774
|
/**
|
|
747
|
-
* Get reference count for an instance
|
|
775
|
+
* Get reference count for an instance.
|
|
776
|
+
* @param Type - The StateContainer class constructor
|
|
777
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
778
|
+
* @returns Current ref count (0 if instance doesn't exist)
|
|
748
779
|
*/
|
|
749
780
|
getRefCount(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
|
|
750
781
|
return this.ensureInstancesMap(Type).get(instanceKey)?.refCount ?? 0;
|
|
751
782
|
}
|
|
752
783
|
/**
|
|
753
|
-
* Check if an instance exists
|
|
784
|
+
* Check if an instance exists.
|
|
785
|
+
* @param Type - The StateContainer class constructor
|
|
786
|
+
* @param instanceKey - Instance key (defaults to 'default')
|
|
787
|
+
* @returns true if instance exists
|
|
754
788
|
*/
|
|
755
789
|
hasInstance(Type, instanceKey = BLAC_DEFAULTS.DEFAULT_INSTANCE_KEY) {
|
|
756
790
|
return this.ensureInstancesMap(Type).has(instanceKey);
|
|
@@ -767,7 +801,8 @@ var StateContainerRegistry = class {
|
|
|
767
801
|
this.typeConfigs.clear();
|
|
768
802
|
}
|
|
769
803
|
/**
|
|
770
|
-
* Get registry statistics
|
|
804
|
+
* Get registry statistics for debugging.
|
|
805
|
+
* @returns Object with registeredTypes, totalInstances, and typeBreakdown
|
|
771
806
|
*/
|
|
772
807
|
getStats() {
|
|
773
808
|
const typeBreakdown = {};
|
|
@@ -785,7 +820,8 @@ var StateContainerRegistry = class {
|
|
|
785
820
|
};
|
|
786
821
|
}
|
|
787
822
|
/**
|
|
788
|
-
* Get all registered types (for plugin system)
|
|
823
|
+
* Get all registered types (for plugin system).
|
|
824
|
+
* @returns Array of all registered StateContainer class constructors
|
|
789
825
|
*/
|
|
790
826
|
getTypes() {
|
|
791
827
|
return Array.from(this.types);
|
|
@@ -890,11 +926,11 @@ var StateContainer = class StateContainer {
|
|
|
890
926
|
* @template S - Optional state type override for generic StateContainers
|
|
891
927
|
* @template T - The StateContainer type (inferred from class)
|
|
892
928
|
* @param instanceKey - Optional instance key (defaults to 'default')
|
|
893
|
-
* @param
|
|
929
|
+
* @param options - Resolution options (canCreate, countRef, props, trackExecutionContext)
|
|
894
930
|
* @returns The state container instance
|
|
895
931
|
*/
|
|
896
|
-
static resolve(instanceKey,
|
|
897
|
-
return StateContainer._registry.resolve(this, instanceKey,
|
|
932
|
+
static resolve(instanceKey, options) {
|
|
933
|
+
return StateContainer._registry.resolve(this, instanceKey, options);
|
|
898
934
|
}
|
|
899
935
|
/**
|
|
900
936
|
* Get an existing instance without incrementing ref count (borrowing semantics).
|
|
@@ -920,14 +956,14 @@ var StateContainer = class StateContainer {
|
|
|
920
956
|
/**
|
|
921
957
|
* Connect to an instance for bloc-to-bloc communication (borrowing semantics).
|
|
922
958
|
* Gets or creates instance without incrementing ref count.
|
|
959
|
+
* Tracks cross-bloc dependency for reactive updates.
|
|
923
960
|
* @template S - Optional state type override for generic StateContainers
|
|
924
961
|
* @template T - The StateContainer type (inferred from class)
|
|
925
962
|
* @param instanceKey - Optional instance key (defaults to 'default')
|
|
926
|
-
* @param constructorArgs - Arguments to pass to constructor if creating new instance
|
|
927
963
|
* @returns The state container instance
|
|
928
964
|
*/
|
|
929
|
-
static connect(instanceKey
|
|
930
|
-
return StateContainer._registry.connect(this, instanceKey
|
|
965
|
+
static connect(instanceKey) {
|
|
966
|
+
return StateContainer._registry.connect(this, instanceKey);
|
|
931
967
|
}
|
|
932
968
|
/**
|
|
933
969
|
* Release a reference to an instance.
|