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