@fluojs/di 1.0.0-beta.3 → 1.0.0-beta.4
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/container.d.ts +8 -3
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +53 -24
- package/package.json +1 -1
package/dist/container.d.ts
CHANGED
|
@@ -9,16 +9,17 @@ export declare class Container {
|
|
|
9
9
|
private readonly registrations;
|
|
10
10
|
private readonly multiRegistrations;
|
|
11
11
|
private readonly multiOverriddenTokens;
|
|
12
|
-
private
|
|
13
|
-
private
|
|
12
|
+
private requestCache;
|
|
13
|
+
private multiRequestCache;
|
|
14
14
|
private readonly multiSingletonCache;
|
|
15
15
|
private readonly staleDisposalTasks;
|
|
16
16
|
private readonly staleDisposalErrors;
|
|
17
17
|
private readonly singletonCache;
|
|
18
18
|
private readonly forwardRefTokenCache;
|
|
19
|
-
private
|
|
19
|
+
private childScopes;
|
|
20
20
|
private disposePromise;
|
|
21
21
|
private disposed;
|
|
22
|
+
private trackedByRoot;
|
|
22
23
|
constructor(parent?: Container | undefined, requestScopeEnabled?: boolean, singletonCache?: Map<Token, Promise<unknown>>);
|
|
23
24
|
/**
|
|
24
25
|
* Registers providers in the current container scope.
|
|
@@ -79,6 +80,7 @@ export declare class Container {
|
|
|
79
80
|
*/
|
|
80
81
|
dispose(): Promise<void>;
|
|
81
82
|
private disposeAll;
|
|
83
|
+
private isDisposedInHierarchy;
|
|
82
84
|
private hasMulti;
|
|
83
85
|
private assertNoRegistrationConflict;
|
|
84
86
|
private hasAncestorSingleRegistration;
|
|
@@ -101,6 +103,9 @@ export declare class Container {
|
|
|
101
103
|
private resolveDepToken;
|
|
102
104
|
private withTokenInChain;
|
|
103
105
|
private root;
|
|
106
|
+
private ensureTrackedRequestScope;
|
|
107
|
+
private requestCacheForWrite;
|
|
108
|
+
private multiRequestCacheForWrite;
|
|
104
109
|
private lookupProvider;
|
|
105
110
|
/**
|
|
106
111
|
* Resolve the cache map that should hold the instance for `provider`.
|
package/dist/container.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAW3E,OAAO,KAAK,EASV,QAAQ,EAET,MAAM,YAAY,CAAC;AAuIpB;;GAEG;AACH,qBAAa,SAAS;
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
|
package/dist/container.js
CHANGED
|
@@ -119,16 +119,17 @@ export class Container {
|
|
|
119
119
|
registrations = new Map();
|
|
120
120
|
multiRegistrations = new Map();
|
|
121
121
|
multiOverriddenTokens = new Set();
|
|
122
|
-
requestCache
|
|
123
|
-
multiRequestCache
|
|
122
|
+
requestCache;
|
|
123
|
+
multiRequestCache;
|
|
124
124
|
multiSingletonCache = new Map();
|
|
125
125
|
staleDisposalTasks = new Set();
|
|
126
126
|
staleDisposalErrors = [];
|
|
127
127
|
singletonCache;
|
|
128
128
|
forwardRefTokenCache = new WeakMap();
|
|
129
|
-
childScopes
|
|
129
|
+
childScopes;
|
|
130
130
|
disposePromise;
|
|
131
131
|
disposed = false;
|
|
132
|
+
trackedByRoot = false;
|
|
132
133
|
constructor(parent, requestScopeEnabled = false, singletonCache) {
|
|
133
134
|
this.parent = parent;
|
|
134
135
|
this.requestScopeEnabled = requestScopeEnabled;
|
|
@@ -146,7 +147,7 @@ export class Container {
|
|
|
146
147
|
* @throws {InvalidProviderError} When a provider definition is structurally invalid.
|
|
147
148
|
*/
|
|
148
149
|
register(...providers) {
|
|
149
|
-
if (this.
|
|
150
|
+
if (this.isDisposedInHierarchy()) {
|
|
150
151
|
throw new ContainerResolutionError('Container has been disposed and can no longer register providers.', {
|
|
151
152
|
hint: 'Ensure providers are registered before calling container.dispose().'
|
|
152
153
|
});
|
|
@@ -190,7 +191,7 @@ export class Container {
|
|
|
190
191
|
* @throws {InvalidProviderError} When a provider definition is structurally invalid.
|
|
191
192
|
*/
|
|
192
193
|
override(...providers) {
|
|
193
|
-
if (this.
|
|
194
|
+
if (this.isDisposedInHierarchy()) {
|
|
194
195
|
throw new ContainerResolutionError('Container has been disposed and can no longer override providers.', {
|
|
195
196
|
hint: 'Ensure overrides are applied before calling container.dispose().'
|
|
196
197
|
});
|
|
@@ -229,14 +230,12 @@ export class Container {
|
|
|
229
230
|
* @throws {ContainerResolutionError} When called after the container was disposed.
|
|
230
231
|
*/
|
|
231
232
|
createRequestScope() {
|
|
232
|
-
if (this.
|
|
233
|
+
if (this.isDisposedInHierarchy()) {
|
|
233
234
|
throw new ContainerResolutionError('Container has been disposed and can no longer create request scopes.', {
|
|
234
235
|
hint: 'Create request scopes before calling container.dispose().'
|
|
235
236
|
});
|
|
236
237
|
}
|
|
237
|
-
|
|
238
|
-
this.root().childScopes.add(child);
|
|
239
|
-
return child;
|
|
238
|
+
return new Container(this, true, this.root().singletonCache);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
/**
|
|
@@ -250,7 +249,7 @@ export class Container {
|
|
|
250
249
|
* @throws {CircularDependencyError} When provider dependency resolution detects a cycle.
|
|
251
250
|
*/
|
|
252
251
|
async resolve(token) {
|
|
253
|
-
if (this.
|
|
252
|
+
if (this.isDisposedInHierarchy()) {
|
|
254
253
|
throw new ContainerResolutionError('Container has been disposed and can no longer resolve providers.', {
|
|
255
254
|
token,
|
|
256
255
|
hint: 'Ensure all resolves complete before calling container.dispose().'
|
|
@@ -282,17 +281,24 @@ export class Container {
|
|
|
282
281
|
async disposeAll() {
|
|
283
282
|
try {
|
|
284
283
|
// Dispose all live request-scope children first (root only)
|
|
285
|
-
if (!this.parent && this.childScopes.size > 0) {
|
|
284
|
+
if (!this.parent && this.childScopes && this.childScopes.size > 0) {
|
|
286
285
|
await Promise.all(Array.from(this.childScopes).map(child => child.dispose()));
|
|
287
286
|
this.childScopes.clear();
|
|
288
287
|
}
|
|
289
288
|
await this.disposeCache(this.disposalCacheEntries());
|
|
290
289
|
} finally {
|
|
291
|
-
if (this.parent) {
|
|
292
|
-
this.root().childScopes
|
|
290
|
+
if (this.parent && this.trackedByRoot) {
|
|
291
|
+
this.root().childScopes?.delete(this);
|
|
292
|
+
this.trackedByRoot = false;
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
|
+
isDisposedInHierarchy() {
|
|
297
|
+
if (this.disposed) {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return this.parent?.isDisposedInHierarchy() ?? false;
|
|
301
|
+
}
|
|
296
302
|
hasMulti(token) {
|
|
297
303
|
if (this.multiRegistrations.has(token)) return true;
|
|
298
304
|
return this.parent?.hasMulti(token) ?? false;
|
|
@@ -478,6 +484,25 @@ export class Container {
|
|
|
478
484
|
root() {
|
|
479
485
|
return this.parent ? this.parent.root() : this;
|
|
480
486
|
}
|
|
487
|
+
ensureTrackedRequestScope() {
|
|
488
|
+
if (!this.requestScopeEnabled || !this.parent || this.trackedByRoot) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const root = this.root();
|
|
492
|
+
root.childScopes ??= new Set();
|
|
493
|
+
root.childScopes.add(this);
|
|
494
|
+
this.trackedByRoot = true;
|
|
495
|
+
}
|
|
496
|
+
requestCacheForWrite() {
|
|
497
|
+
this.ensureTrackedRequestScope();
|
|
498
|
+
this.requestCache ??= new Map();
|
|
499
|
+
return this.requestCache;
|
|
500
|
+
}
|
|
501
|
+
multiRequestCacheForWrite() {
|
|
502
|
+
this.ensureTrackedRequestScope();
|
|
503
|
+
this.multiRequestCache ??= new Map();
|
|
504
|
+
return this.multiRequestCache;
|
|
505
|
+
}
|
|
481
506
|
lookupProvider(token) {
|
|
482
507
|
const local = this.registrations.get(token);
|
|
483
508
|
if (local) {
|
|
@@ -500,7 +525,7 @@ export class Container {
|
|
|
500
525
|
cacheFor(provider) {
|
|
501
526
|
if (provider.scope === Scope.DEFAULT) {
|
|
502
527
|
if (this.requestScopeEnabled && this.registrations.has(provider.provide)) {
|
|
503
|
-
return this.
|
|
528
|
+
return this.requestCacheForWrite();
|
|
504
529
|
}
|
|
505
530
|
return this.root().singletonCache;
|
|
506
531
|
}
|
|
@@ -511,12 +536,12 @@ export class Container {
|
|
|
511
536
|
hint: 'Wrap the resolve call inside a request-scoped child container created via container.createRequestScope().'
|
|
512
537
|
});
|
|
513
538
|
}
|
|
514
|
-
return this.
|
|
539
|
+
return this.requestCacheForWrite();
|
|
515
540
|
}
|
|
516
541
|
multiCacheFor(provider) {
|
|
517
542
|
if (provider.scope === Scope.DEFAULT) {
|
|
518
543
|
if (this.requestScopeEnabled && this.hasLocalMultiProvider(provider)) {
|
|
519
|
-
return this.
|
|
544
|
+
return this.multiRequestCacheForWrite();
|
|
520
545
|
}
|
|
521
546
|
return this.root().multiSingletonCache;
|
|
522
547
|
}
|
|
@@ -527,15 +552,15 @@ export class Container {
|
|
|
527
552
|
hint: 'Wrap the resolve call inside a request-scoped child container created via container.createRequestScope().'
|
|
528
553
|
});
|
|
529
554
|
}
|
|
530
|
-
return this.
|
|
555
|
+
return this.multiRequestCacheForWrite();
|
|
531
556
|
}
|
|
532
557
|
hasLocalMultiProvider(provider) {
|
|
533
558
|
return this.multiRegistrations.get(provider.provide)?.includes(provider) ?? false;
|
|
534
559
|
}
|
|
535
560
|
disposalCacheEntries() {
|
|
536
561
|
if (this.parent) {
|
|
537
|
-
const entries = Array.from(this.requestCache
|
|
538
|
-
for (const [provider, promise] of this.multiRequestCache
|
|
562
|
+
const entries = Array.from(this.requestCache?.entries() ?? []);
|
|
563
|
+
for (const [provider, promise] of this.multiRequestCache?.entries() ?? []) {
|
|
539
564
|
entries.push([provider, promise]);
|
|
540
565
|
}
|
|
541
566
|
return entries;
|
|
@@ -591,8 +616,8 @@ export class Container {
|
|
|
591
616
|
}
|
|
592
617
|
clearDisposalCaches() {
|
|
593
618
|
if (this.parent) {
|
|
594
|
-
this.requestCache
|
|
595
|
-
this.multiRequestCache
|
|
619
|
+
this.requestCache?.clear();
|
|
620
|
+
this.multiRequestCache?.clear();
|
|
596
621
|
return;
|
|
597
622
|
}
|
|
598
623
|
this.singletonCache.clear();
|
|
@@ -716,7 +741,7 @@ export class Container {
|
|
|
716
741
|
return deps;
|
|
717
742
|
}
|
|
718
743
|
invalidateCachedEntry(token, scope) {
|
|
719
|
-
if (this.requestCache
|
|
744
|
+
if (this.requestCache?.has(token)) {
|
|
720
745
|
const cached = this.requestCache.get(token);
|
|
721
746
|
if (cached) {
|
|
722
747
|
this.scheduleStaleDisposal(cached);
|
|
@@ -742,12 +767,16 @@ export class Container {
|
|
|
742
767
|
this.multiSingletonCache.delete(provider);
|
|
743
768
|
}
|
|
744
769
|
}
|
|
745
|
-
|
|
770
|
+
const multiRequestCache = this.multiRequestCache;
|
|
771
|
+
if (!multiRequestCache) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
for (const [provider, cached] of multiRequestCache.entries()) {
|
|
746
775
|
if (provider.provide !== token) {
|
|
747
776
|
continue;
|
|
748
777
|
}
|
|
749
778
|
this.scheduleStaleDisposal(cached);
|
|
750
|
-
|
|
779
|
+
multiRequestCache.delete(provider);
|
|
751
780
|
}
|
|
752
781
|
}
|
|
753
782
|
}
|