@navios/di 0.7.0 → 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 +31 -0
- package/lib/browser/index.d.mts +62 -2
- package/lib/browser/index.d.mts.map +1 -1
- package/lib/browser/index.mjs +132 -15
- package/lib/browser/index.mjs.map +1 -1
- package/lib/{container-CXDYDJSM.d.mts → container-Bp1W-pWJ.d.mts} +63 -3
- package/lib/container-Bp1W-pWJ.d.mts.map +1 -0
- package/lib/{container-Bv6PZZLJ.mjs → container-DAKOvAgr.mjs} +137 -18
- package/lib/container-DAKOvAgr.mjs.map +1 -0
- package/lib/{container-BCv3XS6m.cjs → container-DENMeJ87.cjs} +137 -18
- package/lib/container-DENMeJ87.cjs.map +1 -0
- package/lib/{container-b6mDUdGq.d.cts → container-YPwvmlK2.d.cts} +63 -3
- package/lib/container-YPwvmlK2.d.cts.map +1 -0
- 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/src/token/registry.mts +21 -0
- package/lib/container-BCv3XS6m.cjs.map +0 -1
- package/lib/container-Bv6PZZLJ.mjs.map +0 -1
- package/lib/container-CXDYDJSM.d.mts.map +0 -1
- package/lib/container-b6mDUdGq.d.cts.map +0 -1
|
@@ -104,6 +104,7 @@ var FactoryInjectionToken = class {
|
|
|
104
104
|
//#endregion
|
|
105
105
|
//#region src/token/registry.mts
|
|
106
106
|
var Registry = class {
|
|
107
|
+
parent;
|
|
107
108
|
factories = /* @__PURE__ */ new Map();
|
|
108
109
|
constructor(parent) {
|
|
109
110
|
this.parent = parent;
|
|
@@ -132,6 +133,23 @@ var Registry = class {
|
|
|
132
133
|
delete(token) {
|
|
133
134
|
this.factories.delete(token.id);
|
|
134
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Updates the scope of an already registered factory.
|
|
138
|
+
* This is useful when you need to dynamically change a service's scope
|
|
139
|
+
* (e.g., when a singleton controller has request-scoped dependencies).
|
|
140
|
+
*
|
|
141
|
+
* @param token The injection token to update
|
|
142
|
+
* @param scope The new scope to set
|
|
143
|
+
* @returns true if the scope was updated, false if the token was not found
|
|
144
|
+
*/ updateScope(token, scope) {
|
|
145
|
+
const factory = this.factories.get(token.id);
|
|
146
|
+
if (factory) {
|
|
147
|
+
factory.scope = scope;
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (this.parent) return this.parent.updateScope(token, scope);
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
135
153
|
};
|
|
136
154
|
const globalRegistry = new Registry();
|
|
137
155
|
|
|
@@ -491,9 +509,14 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
491
509
|
*/ var BaseHolderManager = class BaseHolderManager {
|
|
492
510
|
logger;
|
|
493
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;
|
|
494
516
|
constructor(logger = null) {
|
|
495
517
|
this.logger = logger;
|
|
496
518
|
this._holders = /* @__PURE__ */ new Map();
|
|
519
|
+
this._dependents = /* @__PURE__ */ new Map();
|
|
497
520
|
}
|
|
498
521
|
/**
|
|
499
522
|
* Protected getter for accessing the holders map from subclasses.
|
|
@@ -501,23 +524,81 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
501
524
|
return this._holders;
|
|
502
525
|
}
|
|
503
526
|
/**
|
|
504
|
-
* Deletes a holder by name.
|
|
527
|
+
* Deletes a holder by name and cleans up the reverse dependency index.
|
|
505
528
|
* @param name The name of the holder to delete
|
|
506
529
|
* @returns true if the holder was deleted, false if it didn't exist
|
|
507
530
|
*/ delete(name) {
|
|
531
|
+
const holder = this._holders.get(name);
|
|
532
|
+
if (holder) this.removeFromDependentsIndex(name, holder.deps);
|
|
508
533
|
return this._holders.delete(name);
|
|
509
534
|
}
|
|
510
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
|
+
/**
|
|
511
573
|
* Filters holders based on a predicate function.
|
|
512
574
|
* @param predicate Function to test each holder
|
|
513
575
|
* @returns A new Map containing only the holders that match the predicate
|
|
576
|
+
* @deprecated Use forEachHolder() for iteration to avoid allocations
|
|
514
577
|
*/ filter(predicate) {
|
|
515
|
-
|
|
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);
|
|
516
588
|
}
|
|
517
589
|
/**
|
|
518
|
-
*
|
|
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;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Clears all holders from this manager and the reverse dependency index.
|
|
519
599
|
*/ clear() {
|
|
520
600
|
this._holders.clear();
|
|
601
|
+
this._dependents.clear();
|
|
521
602
|
}
|
|
522
603
|
/**
|
|
523
604
|
* Gets the number of holders currently managed.
|
|
@@ -601,12 +682,14 @@ let InstanceStatus = /* @__PURE__ */ function(InstanceStatus$1) {
|
|
|
601
682
|
if (waiterHolder && getHolder) {
|
|
602
683
|
const cycle = CircularDetector.detectCycle(waiterHolder.name, holder.name, getHolder);
|
|
603
684
|
if (cycle) return [DIError.circularDependency(cycle)];
|
|
604
|
-
waiterHolder.waitingFor.add(holder.name);
|
|
685
|
+
if (process.env.NODE_ENV !== "production") waiterHolder.waitingFor.add(holder.name);
|
|
605
686
|
}
|
|
606
687
|
try {
|
|
607
688
|
await holder.creationPromise;
|
|
608
689
|
} finally {
|
|
609
|
-
if (
|
|
690
|
+
if (process.env.NODE_ENV !== "production") {
|
|
691
|
+
if (waiterHolder) waiterHolder.waitingFor.delete(holder.name);
|
|
692
|
+
}
|
|
610
693
|
}
|
|
611
694
|
return BaseHolderManager.waitForHolderReady(holder, waiterHolder, getHolder);
|
|
612
695
|
case InstanceStatus.Destroying: return [DIError.instanceDestroying(holder.name)];
|
|
@@ -733,10 +816,11 @@ var RequestStorage = class {
|
|
|
733
816
|
return null;
|
|
734
817
|
}
|
|
735
818
|
findDependents(instanceName) {
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
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];
|
|
740
824
|
}
|
|
741
825
|
};
|
|
742
826
|
|
|
@@ -942,16 +1026,13 @@ var SingletonStorage = class {
|
|
|
942
1026
|
return this.manager.getAllNames();
|
|
943
1027
|
}
|
|
944
1028
|
forEach(callback) {
|
|
945
|
-
|
|
1029
|
+
this.manager.forEachHolder((holder, name) => callback(name, holder));
|
|
946
1030
|
}
|
|
947
1031
|
findByInstance(instance) {
|
|
948
|
-
|
|
949
|
-
return null;
|
|
1032
|
+
return this.manager.findHolder((h) => h.instance === instance) ?? null;
|
|
950
1033
|
}
|
|
951
1034
|
findDependents(instanceName) {
|
|
952
|
-
|
|
953
|
-
for (const [name, holder] of this.manager.filter(() => true)) if (holder.deps.has(instanceName)) dependents.push(name);
|
|
954
|
-
return dependents;
|
|
1035
|
+
return this.manager.getDependents(instanceName);
|
|
955
1036
|
}
|
|
956
1037
|
};
|
|
957
1038
|
|
|
@@ -1179,6 +1260,8 @@ var SingletonStorage = class {
|
|
|
1179
1260
|
*/ async handleInstantiationSuccess(instanceName, holder, ctx, deferred, instance, scopedContainer) {
|
|
1180
1261
|
holder.instance = instance;
|
|
1181
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);
|
|
1182
1265
|
if (ctx.deps.size > 0) ctx.deps.forEach((dependency) => {
|
|
1183
1266
|
holder.destroyListeners.push(this.serviceLocator.getEventBus().on(dependency, "destroy", () => {
|
|
1184
1267
|
this.logger?.log(`[InstanceResolver] Dependency ${dependency} destroyed, invalidating ${instanceName}`);
|
|
@@ -1634,12 +1717,42 @@ var SingletonStorage = class {
|
|
|
1634
1717
|
//#endregion
|
|
1635
1718
|
//#region src/internal/core/token-processor.mts
|
|
1636
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
|
+
/**
|
|
1637
1749
|
* Handles token validation, normalization, and instance name generation.
|
|
1638
1750
|
*
|
|
1639
1751
|
* Provides utilities for resolving tokens to their underlying InjectionToken,
|
|
1640
1752
|
* validating arguments against schemas, and generating unique instance identifiers.
|
|
1641
1753
|
*/ var TokenProcessor = class {
|
|
1642
1754
|
logger;
|
|
1755
|
+
instanceNameCache = new InstanceNameCache();
|
|
1643
1756
|
constructor(logger = null) {
|
|
1644
1757
|
this.logger = logger;
|
|
1645
1758
|
}
|
|
@@ -1698,10 +1811,16 @@ var SingletonStorage = class {
|
|
|
1698
1811
|
}
|
|
1699
1812
|
/**
|
|
1700
1813
|
* Generates a unique instance name based on token and arguments.
|
|
1814
|
+
* Results are cached using an LRU cache for performance.
|
|
1701
1815
|
*/ generateInstanceName(token, args) {
|
|
1702
1816
|
if (!args) return token.toString();
|
|
1703
|
-
const
|
|
1704
|
-
|
|
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;
|
|
1705
1824
|
}
|
|
1706
1825
|
/**
|
|
1707
1826
|
* Formats a single argument value for instance name generation.
|
|
@@ -2497,4 +2616,4 @@ Object.defineProperty(exports, 'wrapSyncInit', {
|
|
|
2497
2616
|
return wrapSyncInit;
|
|
2498
2617
|
}
|
|
2499
2618
|
});
|
|
2500
|
-
//# sourceMappingURL=container-
|
|
2619
|
+
//# sourceMappingURL=container-DENMeJ87.cjs.map
|