@navios/di 0.7.1 → 0.8.0
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/CHANGELOG.md +23 -0
- package/lib/browser/index.d.mts +52 -2
- package/lib/browser/index.d.mts.map +1 -1
- package/lib/browser/index.mjs +114 -15
- package/lib/browser/index.mjs.map +1 -1
- package/lib/{container-BuAutHGg.d.mts → container-Bp1W-pWJ.d.mts} +53 -3
- package/lib/{container-BuAutHGg.d.mts.map → container-Bp1W-pWJ.d.mts.map} +1 -1
- package/lib/{container-Pb_Y4Z4x.mjs → container-DAKOvAgr.mjs} +119 -18
- package/lib/container-DAKOvAgr.mjs.map +1 -0
- package/lib/{container-DnzgpfBe.cjs → container-DENMeJ87.cjs} +119 -18
- package/lib/container-DENMeJ87.cjs.map +1 -0
- package/lib/{container-oGTgX2iX.d.cts → container-YPwvmlK2.d.cts} +53 -3
- package/lib/{container-oGTgX2iX.d.cts.map → container-YPwvmlK2.d.cts.map} +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.d.cts +1 -1
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +1 -1
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +1 -1
- package/lib/testing/index.cjs +1 -1
- package/lib/testing/index.d.cts +1 -1
- package/lib/testing/index.d.mts +1 -1
- package/lib/testing/index.mjs +1 -1
- package/package.json +1 -1
- package/src/internal/context/request-context.mts +11 -0
- package/src/internal/core/instance-resolver.mts +11 -0
- package/src/internal/core/token-processor.mts +60 -1
- package/src/internal/holder/base-holder-manager.mts +106 -10
- package/src/internal/holder/request-storage.mts +7 -14
- package/src/internal/holder/singleton-storage.mts +3 -16
- package/lib/container-DnzgpfBe.cjs.map +0 -1
- package/lib/container-Pb_Y4Z4x.mjs.map +0 -1
|
@@ -509,9 +509,14 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
509
509
|
*/ var BaseHolderManager = class BaseHolderManager {
|
|
510
510
|
logger;
|
|
511
511
|
_holders;
|
|
512
|
+
/**
|
|
513
|
+
* Reverse dependency index: maps a dependency name to the set of holder names that depend on it.
|
|
514
|
+
* This allows O(1) lookup of dependents instead of O(n) iteration.
|
|
515
|
+
*/ _dependents;
|
|
512
516
|
constructor(logger = null) {
|
|
513
517
|
this.logger = logger;
|
|
514
518
|
this._holders = /* @__PURE__ */ new Map();
|
|
519
|
+
this._dependents = /* @__PURE__ */ new Map();
|
|
515
520
|
}
|
|
516
521
|
/**
|
|
517
522
|
* Protected getter for accessing the holders map from subclasses.
|
|
@@ -519,23 +524,81 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
519
524
|
return this._holders;
|
|
520
525
|
}
|
|
521
526
|
/**
|
|
522
|
-
* Deletes a holder by name.
|
|
527
|
+
* Deletes a holder by name and cleans up the reverse dependency index.
|
|
523
528
|
* @param name The name of the holder to delete
|
|
524
529
|
* @returns true if the holder was deleted, false if it didn't exist
|
|
525
530
|
*/ delete(name) {
|
|
531
|
+
const holder = this._holders.get(name);
|
|
532
|
+
if (holder) this.removeFromDependentsIndex(name, holder.deps);
|
|
526
533
|
return this._holders.delete(name);
|
|
527
534
|
}
|
|
528
535
|
/**
|
|
536
|
+
* Registers a holder's dependencies in the reverse index.
|
|
537
|
+
* Call this after creating a holder with dependencies.
|
|
538
|
+
* @param holderName The name of the holder that has dependencies
|
|
539
|
+
* @param deps The set of dependency names
|
|
540
|
+
*/ registerDependencies(holderName, deps) {
|
|
541
|
+
for (const dep of deps) {
|
|
542
|
+
let dependents = this._dependents.get(dep);
|
|
543
|
+
if (!dependents) {
|
|
544
|
+
dependents = /* @__PURE__ */ new Set();
|
|
545
|
+
this._dependents.set(dep, dependents);
|
|
546
|
+
}
|
|
547
|
+
dependents.add(holderName);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Removes a holder from the reverse dependency index.
|
|
552
|
+
* @param holderName The name of the holder to remove
|
|
553
|
+
* @param deps The set of dependency names to clean up
|
|
554
|
+
*/ removeFromDependentsIndex(holderName, deps) {
|
|
555
|
+
for (const dep of deps) {
|
|
556
|
+
const dependents = this._dependents.get(dep);
|
|
557
|
+
if (dependents) {
|
|
558
|
+
dependents.delete(holderName);
|
|
559
|
+
if (dependents.size === 0) this._dependents.delete(dep);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Gets all holder names that depend on the given instance name.
|
|
565
|
+
* O(1) lookup using the reverse dependency index.
|
|
566
|
+
* @param instanceName The instance name to find dependents for
|
|
567
|
+
* @returns Array of holder names that depend on this instance
|
|
568
|
+
*/ getDependents(instanceName) {
|
|
569
|
+
const dependents = this._dependents.get(instanceName);
|
|
570
|
+
return dependents ? Array.from(dependents) : [];
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
529
573
|
* Filters holders based on a predicate function.
|
|
530
574
|
* @param predicate Function to test each holder
|
|
531
575
|
* @returns A new Map containing only the holders that match the predicate
|
|
576
|
+
* @deprecated Use forEachHolder() for iteration to avoid allocations
|
|
532
577
|
*/ filter(predicate) {
|
|
533
|
-
|
|
578
|
+
const result = /* @__PURE__ */ new Map();
|
|
579
|
+
for (const [key, value] of this._holders) if (predicate(value, key)) result.set(key, value);
|
|
580
|
+
return result;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Iterates over holders with a callback. More efficient than filter() as it
|
|
584
|
+
* avoids creating intermediate arrays and Maps.
|
|
585
|
+
* @param callback Function called for each holder with (holder, name)
|
|
586
|
+
*/ forEachHolder(callback) {
|
|
587
|
+
for (const [name, holder] of this._holders) callback(holder, name);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Finds the first holder matching a predicate. More efficient than filter()
|
|
591
|
+
* when only one result is needed.
|
|
592
|
+
* @param predicate Function to test each holder
|
|
593
|
+
* @returns The first matching holder or undefined
|
|
594
|
+
*/ findHolder(predicate) {
|
|
595
|
+
for (const [name, holder] of this._holders) if (predicate(holder, name)) return holder;
|
|
534
596
|
}
|
|
535
597
|
/**
|
|
536
|
-
* Clears all holders from this manager.
|
|
598
|
+
* Clears all holders from this manager and the reverse dependency index.
|
|
537
599
|
*/ clear() {
|
|
538
600
|
this._holders.clear();
|
|
601
|
+
this._dependents.clear();
|
|
539
602
|
}
|
|
540
603
|
/**
|
|
541
604
|
* Gets the number of holders currently managed.
|
|
@@ -619,12 +682,14 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
619
682
|
if (waiterHolder && getHolder) {
|
|
620
683
|
const cycle = CircularDetector.detectCycle(waiterHolder.name, holder.name, getHolder);
|
|
621
684
|
if (cycle) return [DIError.circularDependency(cycle)];
|
|
622
|
-
waiterHolder.waitingFor.add(holder.name);
|
|
685
|
+
if (process.env.NODE_ENV !== "production") waiterHolder.waitingFor.add(holder.name);
|
|
623
686
|
}
|
|
624
687
|
try {
|
|
625
688
|
await holder.creationPromise;
|
|
626
689
|
} finally {
|
|
627
|
-
if (
|
|
690
|
+
if (process.env.NODE_ENV !== "production") {
|
|
691
|
+
if (waiterHolder) waiterHolder.waitingFor.delete(holder.name);
|
|
692
|
+
}
|
|
628
693
|
}
|
|
629
694
|
return BaseHolderManager.waitForHolderReady(holder, waiterHolder, getHolder);
|
|
630
695
|
case InstanceStatus.Destroying: return [DIError.instanceDestroying(holder.name)];
|
|
@@ -751,10 +816,11 @@ var RequestStorage = class {
|
|
|
751
816
|
return null;
|
|
752
817
|
}
|
|
753
818
|
findDependents(instanceName) {
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
return
|
|
819
|
+
const requestDependents = this.contextHolder.getDependents(instanceName);
|
|
820
|
+
const singletonDependents = this.holderManager.getDependents(instanceName);
|
|
821
|
+
if (requestDependents.length === 0) return singletonDependents;
|
|
822
|
+
if (singletonDependents.length === 0) return requestDependents;
|
|
823
|
+
return [...requestDependents, ...singletonDependents];
|
|
758
824
|
}
|
|
759
825
|
};
|
|
760
826
|
|
|
@@ -960,16 +1026,13 @@ var SingletonStorage = class {
|
|
|
960
1026
|
return this.manager.getAllNames();
|
|
961
1027
|
}
|
|
962
1028
|
forEach(callback) {
|
|
963
|
-
|
|
1029
|
+
this.manager.forEachHolder((holder, name) => callback(name, holder));
|
|
964
1030
|
}
|
|
965
1031
|
findByInstance(instance) {
|
|
966
|
-
|
|
967
|
-
return null;
|
|
1032
|
+
return this.manager.findHolder((h) => h.instance === instance) ?? null;
|
|
968
1033
|
}
|
|
969
1034
|
findDependents(instanceName) {
|
|
970
|
-
|
|
971
|
-
for (const [name, holder] of this.manager.filter(() => true)) if (holder.deps.has(instanceName)) dependents.push(name);
|
|
972
|
-
return dependents;
|
|
1035
|
+
return this.manager.getDependents(instanceName);
|
|
973
1036
|
}
|
|
974
1037
|
};
|
|
975
1038
|
|
|
@@ -1197,6 +1260,8 @@ var SingletonStorage = class {
|
|
|
1197
1260
|
*/ async handleInstantiationSuccess(instanceName, holder, ctx, deferred, instance, scopedContainer) {
|
|
1198
1261
|
holder.instance = instance;
|
|
1199
1262
|
holder.status = InstanceStatus.Created;
|
|
1263
|
+
if (ctx.deps.size > 0) if (scopedContainer) scopedContainer.getRequestContextHolder().registerDependencies(instanceName, ctx.deps);
|
|
1264
|
+
else this.manager.registerDependencies(instanceName, ctx.deps);
|
|
1200
1265
|
if (ctx.deps.size > 0) ctx.deps.forEach((dependency) => {
|
|
1201
1266
|
holder.destroyListeners.push(this.serviceLocator.getEventBus().on(dependency, "destroy", () => {
|
|
1202
1267
|
this.logger?.log(`[InstanceResolver] Dependency ${dependency} destroyed, invalidating ${instanceName}`);
|
|
@@ -1652,12 +1717,42 @@ var SingletonStorage = class {
|
|
|
1652
1717
|
//#endregion
|
|
1653
1718
|
//#region src/internal/core/token-processor.mts
|
|
1654
1719
|
/**
|
|
1720
|
+
* Simple LRU cache for instance name generation.
|
|
1721
|
+
* Uses a Map which maintains insertion order for efficient LRU eviction.
|
|
1722
|
+
*/ var InstanceNameCache = class {
|
|
1723
|
+
cache = /* @__PURE__ */ new Map();
|
|
1724
|
+
maxSize;
|
|
1725
|
+
constructor(maxSize = 1e3) {
|
|
1726
|
+
this.maxSize = maxSize;
|
|
1727
|
+
}
|
|
1728
|
+
get(key) {
|
|
1729
|
+
const value = this.cache.get(key);
|
|
1730
|
+
if (value !== void 0) {
|
|
1731
|
+
this.cache.delete(key);
|
|
1732
|
+
this.cache.set(key, value);
|
|
1733
|
+
}
|
|
1734
|
+
return value;
|
|
1735
|
+
}
|
|
1736
|
+
set(key, value) {
|
|
1737
|
+
if (this.cache.has(key)) this.cache.delete(key);
|
|
1738
|
+
else if (this.cache.size >= this.maxSize) {
|
|
1739
|
+
const firstKey = this.cache.keys().next().value;
|
|
1740
|
+
if (firstKey !== void 0) this.cache.delete(firstKey);
|
|
1741
|
+
}
|
|
1742
|
+
this.cache.set(key, value);
|
|
1743
|
+
}
|
|
1744
|
+
clear() {
|
|
1745
|
+
this.cache.clear();
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
/**
|
|
1655
1749
|
* Handles token validation, normalization, and instance name generation.
|
|
1656
1750
|
*
|
|
1657
1751
|
* Provides utilities for resolving tokens to their underlying InjectionToken,
|
|
1658
1752
|
* validating arguments against schemas, and generating unique instance identifiers.
|
|
1659
1753
|
*/ var TokenProcessor = class {
|
|
1660
1754
|
logger;
|
|
1755
|
+
instanceNameCache = new InstanceNameCache();
|
|
1661
1756
|
constructor(logger = null) {
|
|
1662
1757
|
this.logger = logger;
|
|
1663
1758
|
}
|
|
@@ -1716,10 +1811,16 @@ var SingletonStorage = class {
|
|
|
1716
1811
|
}
|
|
1717
1812
|
/**
|
|
1718
1813
|
* Generates a unique instance name based on token and arguments.
|
|
1814
|
+
* Results are cached using an LRU cache for performance.
|
|
1719
1815
|
*/ generateInstanceName(token, args) {
|
|
1720
1816
|
if (!args) return token.toString();
|
|
1721
|
-
const
|
|
1722
|
-
|
|
1817
|
+
const tokenStr = token.toString();
|
|
1818
|
+
const cacheKey = `${tokenStr}:${JSON.stringify(args)}`;
|
|
1819
|
+
const cached = this.instanceNameCache.get(cacheKey);
|
|
1820
|
+
if (cached !== void 0) return cached;
|
|
1821
|
+
const result = `${tokenStr}:${Object.entries(args).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)).map(([key, value]) => `${key}=${this.formatArgValue(value)}`).join(",").replaceAll(/"/g, "").replaceAll(/:/g, "=")}`;
|
|
1822
|
+
this.instanceNameCache.set(cacheKey, result);
|
|
1823
|
+
return result;
|
|
1723
1824
|
}
|
|
1724
1825
|
/**
|
|
1725
1826
|
* Formats a single argument value for instance name generation.
|
|
@@ -2515,4 +2616,4 @@ Object.defineProperty(exports, 'wrapSyncInit', {
|
|
|
2515
2616
|
return wrapSyncInit;
|
|
2516
2617
|
}
|
|
2517
2618
|
});
|
|
2518
|
-
//# sourceMappingURL=container-
|
|
2619
|
+
//# sourceMappingURL=container-DENMeJ87.cjs.map
|