di-bag 0.5.0 → 0.5.1
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.d.ts +1 -1
- package/dist/inspection.d.ts +13 -0
- package/dist/module.d.ts +2 -0
- package/dist/module.js +20 -0
- package/dist/runtime.d.ts +5 -1
- package/dist/runtime.js +22 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { ReboundProviders, ReboundSelection } from './types';
|
|
|
18
18
|
export type { CanonicalLifetime, ChildReplacementAdmission, CheckedChildContainerLifetimes, CheckedLifetimes, LifetimeObligation, Reach } from './lifetime-types';
|
|
19
19
|
export type { DiBagPolicy } from './types';
|
|
20
20
|
export type { CheckDependencyCompatibility, CheckDependencyCompleteness, RegistrationEntries, OverrideFactoryContext, RegistrationsFromEntries, OverrideRegistrations, Overrides, ServicesOf, SelectedRegistrations, Selection } from './types';
|
|
21
|
-
export type { Presence, AcquisitionMetadataPresence, AcquisitionSnapshot, RegistrationSnapshot, BindingSnapshot, GraphSnapshot } from './inspection';
|
|
21
|
+
export type { Presence, AcquisitionMetadataPresence, AcquisitionSnapshot, RegistrationSnapshot, BindingSnapshot, ModuleInstallationSnapshot, GraphSnapshot } from './inspection';
|
|
22
22
|
export type { PositionalFactoryArguments, PositionalFactoryFunction } from './composition';
|
|
23
23
|
export type { OptionalDependency, LazyDependency, DependencyReference } from './dependency-references';
|
|
24
24
|
export type { PluginOutputValidator, PluginProvider } from './plugins';
|
package/dist/inspection.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ export interface RegistrationSnapshot<M = Readonly<{}>, A extends readonly unkno
|
|
|
53
53
|
* @see https://dany-fedorov.github.io/di-bag/guides/tutorial.html#attach-metadata-and-inspect-without-resolving
|
|
54
54
|
*/
|
|
55
55
|
export interface BindingSnapshot<M = Readonly<{}>, A extends readonly unknown[] = readonly []> extends RegistrationSnapshot<M, A> {
|
|
56
|
+
/** Innermost module installation that introduced this binding; absent for host declarations and host replacements. */
|
|
57
|
+
readonly moduleInstallationId: symbol | undefined;
|
|
56
58
|
/** Public names or token symbols that select this binding, in service key order; empty for a private module binding. */
|
|
57
59
|
readonly serviceKeys: readonly (string | symbol)[];
|
|
58
60
|
readonly lifetime: Lifetime;
|
|
@@ -65,6 +67,15 @@ export interface BindingSnapshot<M = Readonly<{}>, A extends readonly unknown[]
|
|
|
65
67
|
readonly dependencyKind: 'required' | 'optional' | 'lazy';
|
|
66
68
|
}[];
|
|
67
69
|
}
|
|
70
|
+
/** One occurrence of a sealed module in a container graph. */
|
|
71
|
+
export interface ModuleInstallationSnapshot {
|
|
72
|
+
/** Stable identity for this occurrence in the graph. */
|
|
73
|
+
readonly installationId: symbol;
|
|
74
|
+
/** Exact label supplied when the module was sealed, if any. */
|
|
75
|
+
readonly moduleLabel: string | undefined;
|
|
76
|
+
/** Enclosing installation, if this module was installed inside another module. */
|
|
77
|
+
readonly parentInstallationId: symbol | undefined;
|
|
78
|
+
}
|
|
68
79
|
/**
|
|
69
80
|
* A frozen description of every binding a container can resolve, plus the edges observed so far.
|
|
70
81
|
* Named dependencies read from a factory's object parameter are not knowable until the factory
|
|
@@ -73,6 +84,8 @@ export interface BindingSnapshot<M = Readonly<{}>, A extends readonly unknown[]
|
|
|
73
84
|
*/
|
|
74
85
|
export interface GraphSnapshot {
|
|
75
86
|
readonly containerId: symbol;
|
|
87
|
+
/** Module occurrences in installation order, with each parent preceding its contiguous descendants. */
|
|
88
|
+
readonly moduleInstallations: readonly ModuleInstallationSnapshot[];
|
|
76
89
|
/** Public bindings in service key order, then contributions in group order, then remaining private bindings. */
|
|
77
90
|
readonly bindings: readonly BindingSnapshot<object, readonly unknown[]>[];
|
|
78
91
|
readonly contributions: readonly {
|
package/dist/module.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ declare class Module<ExportedServices extends object, RequiredServices extends o
|
|
|
39
39
|
/** @internal */
|
|
40
40
|
readonly [moduleInvariant]: (value: [ExportedServices, RequiredServices, Constraints, PublicProviders]) => [ExportedServices, RequiredServices, Constraints, PublicProviders];
|
|
41
41
|
constructor(description: ModuleDescription);
|
|
42
|
+
/** The exact label supplied when this module was sealed, if any. Reading it never acquires a service. */
|
|
43
|
+
get moduleLabel(): string | undefined;
|
|
42
44
|
/**
|
|
43
45
|
* Return a module view with one string-named export renamed through an options object.
|
|
44
46
|
* @param options - The current export and its noncolliding new name.
|
package/dist/module.js
CHANGED
|
@@ -27,6 +27,10 @@ class Module {
|
|
|
27
27
|
});
|
|
28
28
|
Object.freeze(this);
|
|
29
29
|
}
|
|
30
|
+
/** The exact label supplied when this module was sealed, if any. Reading it never acquires a service. */
|
|
31
|
+
get moduleLabel() {
|
|
32
|
+
return descriptions.get(this).label;
|
|
33
|
+
}
|
|
30
34
|
/**
|
|
31
35
|
* Return a module view with one string-named export renamed through an options object.
|
|
32
36
|
* @param options - The current export and its noncolliding new name.
|
|
@@ -171,6 +175,19 @@ function moduleGraph(value, index) {
|
|
|
171
175
|
throw (0, errors_1.libraryError)('DI_BAG_INVALID_MODULE', `withInstalledModules requires genuine modules: element ${index} is not one`, { operation: 'withInstalledModules', index });
|
|
172
176
|
}
|
|
173
177
|
const { graph, exports, label, requirementRenames } = description;
|
|
178
|
+
const installationId = Symbol('module installation');
|
|
179
|
+
const remapped = new Map();
|
|
180
|
+
for (const nested of graph.moduleInstallations ?? [])
|
|
181
|
+
remapped.set(nested.installationId, Symbol('module installation'));
|
|
182
|
+
const moduleInstallations = [
|
|
183
|
+
{ installationId, moduleLabel: label, parentInstallationId: undefined },
|
|
184
|
+
...(graph.moduleInstallations ?? []).map(nested => ({
|
|
185
|
+
installationId: remapped.get(nested.installationId),
|
|
186
|
+
moduleLabel: nested.moduleLabel,
|
|
187
|
+
parentInstallationId: nested.parentInstallationId === undefined
|
|
188
|
+
? installationId : remapped.get(nested.parentInstallationId),
|
|
189
|
+
})),
|
|
190
|
+
];
|
|
174
191
|
const exported = new Set();
|
|
175
192
|
for (const localKey of exports.values())
|
|
176
193
|
exported.add(graph.publicSlots.get(localKey));
|
|
@@ -219,6 +236,8 @@ function moduleGraph(value, index) {
|
|
|
219
236
|
bindings.set(fresh, {
|
|
220
237
|
id: fresh, label: labelOf(id, binding), registration: binding.registration,
|
|
221
238
|
localNames: localNamesFor(binding),
|
|
239
|
+
moduleInstallationId: binding.moduleInstallationId === undefined
|
|
240
|
+
? installationId : remapped.get(binding.moduleInstallationId),
|
|
222
241
|
});
|
|
223
242
|
}
|
|
224
243
|
const publicSlots = new Map();
|
|
@@ -232,5 +251,6 @@ function moduleGraph(value, index) {
|
|
|
232
251
|
publicSlots,
|
|
233
252
|
contributions,
|
|
234
253
|
tokenKinds: new Map(graph.tokenKinds ?? []),
|
|
254
|
+
moduleInstallations,
|
|
235
255
|
};
|
|
236
256
|
}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ScopeAcquisitions } from './acquisition';
|
|
2
2
|
import { normalize } from './registration';
|
|
3
3
|
import type { ProviderOrFactory, Registrations } from './registration';
|
|
4
|
-
import type { GraphSnapshot, RegistrationSnapshot } from './inspection';
|
|
4
|
+
import type { GraphSnapshot, ModuleInstallationSnapshot, RegistrationSnapshot } from './inspection';
|
|
5
5
|
import type { RuntimeContext } from './acquisition-mode';
|
|
6
6
|
import { type TokenKind } from './tokens';
|
|
7
7
|
import type { LifetimeKind } from './lifetime';
|
|
@@ -19,12 +19,14 @@ export interface BindingDescription {
|
|
|
19
19
|
readonly label: string;
|
|
20
20
|
readonly registration: ProviderOrFactory;
|
|
21
21
|
readonly localNames: ReadonlyMap<BindingKey, BindingRef>;
|
|
22
|
+
readonly moduleInstallationId?: symbol;
|
|
22
23
|
}
|
|
23
24
|
export interface GraphDescription {
|
|
24
25
|
readonly bindings: ReadonlyMap<BindingId, BindingDescription>;
|
|
25
26
|
readonly publicSlots: ReadonlyMap<BindingKey, BindingId>;
|
|
26
27
|
readonly contributions?: ReadonlyMap<symbol, readonly BindingId[]>;
|
|
27
28
|
readonly tokenKinds?: ReadonlyMap<symbol, TokenKind>;
|
|
29
|
+
readonly moduleInstallations?: readonly ModuleInstallationSnapshot[];
|
|
28
30
|
}
|
|
29
31
|
type Normalized = Readonly<ReturnType<typeof normalize>>;
|
|
30
32
|
/** Immutable descriptions and path-copied lookup storage. Retained maps never escape. */
|
|
@@ -60,6 +62,8 @@ export declare class BindingGraph {
|
|
|
60
62
|
registration(id: BindingId): Normalized;
|
|
61
63
|
private requireRegistration;
|
|
62
64
|
label(id: BindingId): string;
|
|
65
|
+
moduleInstallationId(id: BindingId): symbol | undefined;
|
|
66
|
+
moduleInstallations(): readonly ModuleInstallationSnapshot[];
|
|
63
67
|
withPublicRegistrations(registrations: Registrations, operation?: string): BindingGraph;
|
|
64
68
|
/** Replace ordered slots and prune only unreferenced public replacement history. */
|
|
65
69
|
withPublicBindings(entries: readonly (readonly [BindingKey, ProviderOrFactory])[], operation?: string): BindingGraph;
|
package/dist/runtime.js
CHANGED
|
@@ -12,6 +12,7 @@ const tokens_1 = require("./tokens");
|
|
|
12
12
|
const lifetime_1 = require("./lifetime");
|
|
13
13
|
const emptyContributions = Object.freeze([]);
|
|
14
14
|
const emptyNames = new Map();
|
|
15
|
+
const emptyModuleInstallations = Object.freeze([]);
|
|
15
16
|
/** Immutable descriptions and path-copied lookup storage. Retained maps never escape. */
|
|
16
17
|
class BindingGraph {
|
|
17
18
|
#bindings = new persistent_map_1.PersistentMap();
|
|
@@ -32,12 +33,16 @@ class BindingGraph {
|
|
|
32
33
|
// First public registration order by key, for module snapshots. Keys are
|
|
33
34
|
// never unregistered, so this retains nothing a graph would otherwise drop.
|
|
34
35
|
#publicOrder;
|
|
36
|
+
#moduleInstallations;
|
|
35
37
|
#bindingCache = new Map();
|
|
36
38
|
#registrationCache = new Map();
|
|
37
39
|
#publicCache = new Map();
|
|
38
40
|
#contributionCache = new Map();
|
|
39
41
|
#explicitlyClassified = false;
|
|
40
42
|
constructor(description = { bindings: new Map(), publicSlots: new Map() }) {
|
|
43
|
+
if (description.moduleInstallations?.length) {
|
|
44
|
+
this.#moduleInstallations = { values: Object.freeze(description.moduleInstallations.map(record => Object.freeze({ ...record }))) };
|
|
45
|
+
}
|
|
41
46
|
const declaredKinds = description.tokenKinds ?? new Map();
|
|
42
47
|
const lexicalSnapshots = new Map();
|
|
43
48
|
for (const [id, binding] of description.bindings) {
|
|
@@ -59,7 +64,10 @@ class BindingGraph {
|
|
|
59
64
|
this.#lexicalUsers = this.#lexicalUsers.set(lexical.id, (this.#lexicalUsers.get(lexical.id) ?? 0) + 1);
|
|
60
65
|
const entry = {
|
|
61
66
|
lexical,
|
|
62
|
-
description: Object.freeze({
|
|
67
|
+
description: Object.freeze({
|
|
68
|
+
id: binding.id, label: binding.label, registration: binding.registration, localNames: lexical.names,
|
|
69
|
+
...(binding.moduleInstallationId === undefined ? {} : { moduleInstallationId: binding.moduleInstallationId }),
|
|
70
|
+
}),
|
|
63
71
|
normalized: Object.freeze((0, registration_1.normalize)(binding.registration)),
|
|
64
72
|
};
|
|
65
73
|
this.retainBindingTokenKinds(entry, 'withInstalledModules');
|
|
@@ -98,6 +106,7 @@ class BindingGraph {
|
|
|
98
106
|
graph.#tokenKindOwners = this.#tokenKindOwners;
|
|
99
107
|
graph.#directTokenKinds = this.#directTokenKinds;
|
|
100
108
|
graph.#publicOrder = this.#publicOrder;
|
|
109
|
+
graph.#moduleInstallations = this.#moduleInstallations;
|
|
101
110
|
return graph;
|
|
102
111
|
}
|
|
103
112
|
entry(id) {
|
|
@@ -253,6 +262,12 @@ class BindingGraph {
|
|
|
253
262
|
return registration;
|
|
254
263
|
}
|
|
255
264
|
label(id) { return (this.#bindingCache.get(id) ?? this.entry(id)?.description)?.label ?? String(id); }
|
|
265
|
+
moduleInstallationId(id) {
|
|
266
|
+
return (this.#bindingCache.get(id) ?? this.entry(id)?.description)?.moduleInstallationId;
|
|
267
|
+
}
|
|
268
|
+
moduleInstallations() {
|
|
269
|
+
return this.#moduleInstallations ? (0, persistent_sequence_1.materialize)(this.#moduleInstallations) : emptyModuleInstallations;
|
|
270
|
+
}
|
|
256
271
|
withPublicRegistrations(registrations, operation = 'register') {
|
|
257
272
|
return this.withPublicBindings(Object.keys(registrations).map(key => [key, registrations[key]]), operation);
|
|
258
273
|
}
|
|
@@ -360,7 +375,7 @@ class BindingGraph {
|
|
|
360
375
|
for (const [key, kind] of this.#tokenKinds) {
|
|
361
376
|
tokenKinds.set(key, kind);
|
|
362
377
|
}
|
|
363
|
-
return { bindings, publicSlots, contributions, tokenKinds };
|
|
378
|
+
return { bindings, publicSlots, contributions, tokenKinds, moduleInstallations: this.moduleInstallations() };
|
|
364
379
|
}
|
|
365
380
|
/** Every retained binding in `describe()` order, with the public keys that select it. */
|
|
366
381
|
bindingSummaries() {
|
|
@@ -396,6 +411,9 @@ class BindingGraph {
|
|
|
396
411
|
this.assertTokenKind(key, kind, operation);
|
|
397
412
|
}
|
|
398
413
|
const graph = this.copy();
|
|
414
|
+
if (description.moduleInstallations?.length) {
|
|
415
|
+
graph.#moduleInstallations = (0, persistent_sequence_1.append)(graph.#moduleInstallations, installation.#moduleInstallations);
|
|
416
|
+
}
|
|
399
417
|
const pending = [];
|
|
400
418
|
// Publish all incoming protection before releasing overwritten descriptions.
|
|
401
419
|
for (const [id, count] of installation.#lexicalUsers)
|
|
@@ -485,6 +503,7 @@ class BagRuntime {
|
|
|
485
503
|
const description = this.graph.registration(id);
|
|
486
504
|
return Object.freeze({
|
|
487
505
|
...this.inspectBinding(id),
|
|
506
|
+
moduleInstallationId: this.graph.moduleInstallationId(id),
|
|
488
507
|
serviceKeys: keys,
|
|
489
508
|
lifetime: (0, lifetime_1.publicLifetime)(description.lifetime.kind),
|
|
490
509
|
factoryReturnKind: description.factoryReturnKind,
|
|
@@ -494,6 +513,7 @@ class BagRuntime {
|
|
|
494
513
|
});
|
|
495
514
|
return Object.freeze({
|
|
496
515
|
containerId: this.acquisitions.ownerId,
|
|
516
|
+
moduleInstallations: this.graph.moduleInstallations(),
|
|
497
517
|
bindings: Object.freeze(bindings),
|
|
498
518
|
contributions: this.graph.contributionGroups(),
|
|
499
519
|
observedEdges: this.acquisitions.observedEdges(),
|
package/package.json
CHANGED