@fnioc/di 1.0.0 → 2.0.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/README.md +36 -27
- package/dist/index.d.ts +652 -8
- package/dist/index.js +521 -23
- package/package.json +6 -9
- package/dist/builder.d.ts +0 -81
- package/dist/builder.d.ts.map +0 -1
- package/dist/builder.js +0 -85
- package/dist/builder.js.map +0 -1
- package/dist/errors.d.ts +0 -73
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -139
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/scope.d.ts +0 -180
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -466
- package/dist/scope.js.map +0 -1
- package/dist/types.d.ts +0 -57
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -4
- package/dist/types.js.map +0 -1
package/dist/builder.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// The registration builder. Holds the base token → registration map and hands
|
|
2
|
-
// out a root Scope. `.add()` is the surface the transformer lowers to; the
|
|
3
|
-
// override paths (`.register`) are the recommended plugin-less mechanism.
|
|
4
|
-
import { Scope } from "./scope.js";
|
|
5
|
-
/**
|
|
6
|
-
* The registration builder.
|
|
7
|
-
*
|
|
8
|
-
* `Scopes` is the user-supplied scope-name union (e.g.
|
|
9
|
-
* `"singleton" | "request"`). `"transient"` is NOT a member — transient is the
|
|
10
|
-
* absence of a tag, not a scope.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* const services = new DiBuilder<"singleton" | "request">();
|
|
15
|
-
* services.add("pkg:ILogger", ConsoleLogger).as("singleton"); // lowered form
|
|
16
|
-
* const root = services.createScope("singleton");
|
|
17
|
-
* const logger = root.resolve<ILogger>("pkg:ILogger");
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export class DiBuilder {
|
|
21
|
-
registrations = new Map();
|
|
22
|
-
add(tokenOrCtor, maybeCtor) {
|
|
23
|
-
// Only the string-token form reaches the engine at runtime. The type-only
|
|
24
|
-
// overload is never actually invoked post-transform; guard defensively so a
|
|
25
|
-
// hand-written type-form call fails loud rather than registering garbage.
|
|
26
|
-
if (typeof tokenOrCtor !== "string" || maybeCtor === undefined) {
|
|
27
|
-
throw new TypeError('add<I>(ctor) requires the @fnioc/transformer plugin. Without it, ' +
|
|
28
|
-
'register with an explicit token: add("my:token", MyClass).');
|
|
29
|
-
}
|
|
30
|
-
const registration = {
|
|
31
|
-
kind: "class",
|
|
32
|
-
ctor: maybeCtor,
|
|
33
|
-
tag: undefined,
|
|
34
|
-
};
|
|
35
|
-
this.registrations.set(tokenOrCtor, registration);
|
|
36
|
-
// `.as()` rebinds the registration with its tag. The map holds an immutable
|
|
37
|
-
// record, so swap in a fresh one rather than mutating the readonly field.
|
|
38
|
-
const token = tokenOrCtor;
|
|
39
|
-
const registrations = this.registrations;
|
|
40
|
-
return {
|
|
41
|
-
as(scope) {
|
|
42
|
-
// The lowered form always passes a value arg; the authored type-arg-only
|
|
43
|
-
// form never executes (the transformer rewrites it first). A no-arg call
|
|
44
|
-
// at runtime would leave the registration transient — guard so it is a
|
|
45
|
-
// no-op rather than overwriting the tag with `undefined`.
|
|
46
|
-
if (scope === undefined)
|
|
47
|
-
return;
|
|
48
|
-
registrations.set(token, { ...registration, tag: scope });
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* The plugin-less override path. Registers a token against either a
|
|
54
|
-
* `useFactory` closure (which resolves its own deps from the scope passed to
|
|
55
|
-
* it) or a `useValue` instance. The recommended mechanism for test doubles,
|
|
56
|
-
* third-party instances, and plugin-less wiring.
|
|
57
|
-
*
|
|
58
|
-
* A `useFactory` may carry an optional `tag` so the factory's result is
|
|
59
|
-
* cached at a matching ancestor scope (singleton-style); without a tag it
|
|
60
|
-
* runs on every resolve. A `useValue` is the instance itself — always the
|
|
61
|
-
* same value, no lifetime.
|
|
62
|
-
*/
|
|
63
|
-
register(token, spec) {
|
|
64
|
-
if ("useValue" in spec) {
|
|
65
|
-
this.registrations.set(token, { kind: "value", useValue: spec.useValue });
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
this.registrations.set(token, {
|
|
69
|
-
kind: "factory",
|
|
70
|
-
useFactory: spec.useFactory,
|
|
71
|
-
tag: spec.tag,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Mints the root scope. The root must be a real, app-lifetime object — its
|
|
78
|
-
* name is the lifetime tag that singletons (or whatever the app's longest
|
|
79
|
-
* lifetime is) bind to.
|
|
80
|
-
*/
|
|
81
|
-
createScope(rootScopeName) {
|
|
82
|
-
return new Scope(rootScopeName, undefined, this.registrations);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=builder.js.map
|
package/dist/builder.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAI1E,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAsCnC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,SAAS;IACH,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;IAezD,GAAG,CACR,WAAsD,EACtD,SAAgB;QAEhB,0EAA0E;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC/D,MAAM,IAAI,SAAS,CACjB,mEAAmE;gBACjE,4DAA4D,CAC/D,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAsB;YACtC,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,SAAS;SACf,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAElD,4EAA4E;QAC5E,0EAA0E;QAC1E,MAAM,KAAK,GAAG,WAAW,CAAC;QAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,OAAO;YACL,EAAE,CAAmB,KAAS;gBAC5B,yEAAyE;gBACzE,yEAAyE;gBACzE,uEAAuE;gBACvE,0DAA0D;gBAC1D,IAAI,KAAK,KAAK,SAAS;oBAAE,OAAO;gBAChC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACI,QAAQ,CAAI,KAAY,EAAE,IAAqB;QACpD,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE;gBAC5B,IAAI,EAAE,SAAS;gBACf,UAAU,EAAE,IAAI,CAAC,UAA8C;gBAC/D,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,aAAqB;QACtC,OAAO,IAAI,KAAK,CAAS,aAAa,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACzE,CAAC;CACF"}
|
package/dist/errors.d.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type { Token } from "@fnioc/core";
|
|
2
|
-
/** Base class for every error the container raises. */
|
|
3
|
-
export declare class DiError extends Error {
|
|
4
|
-
constructor(message: string);
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* A token was requested but no registration exists for it anywhere in the
|
|
8
|
-
* resolving scope's chain (nor on the builder's base map).
|
|
9
|
-
*/
|
|
10
|
-
export declare class UnregisteredTokenError extends DiError {
|
|
11
|
-
readonly token: Token;
|
|
12
|
-
constructor(token: Token);
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* A registration carries a lifetime tag, but no ancestor scope in the resolving
|
|
16
|
-
* chain has a matching name. This is the captive-dependency / misconfiguration
|
|
17
|
-
* detector — the engine never auto-creates a scope to satisfy the tag.
|
|
18
|
-
*/
|
|
19
|
-
export declare class MissingScopeError extends DiError {
|
|
20
|
-
readonly token: Token;
|
|
21
|
-
readonly tag: string;
|
|
22
|
-
readonly availableScopes: readonly string[];
|
|
23
|
-
constructor(token: Token, tag: string, availableScopes: readonly string[]);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* A constructor with parameters has no DepRecord in the WeakMap — the
|
|
27
|
-
* transformer never saw it and it was never hand-annotated.
|
|
28
|
-
*/
|
|
29
|
-
export declare class MissingMetadataError extends DiError {
|
|
30
|
-
readonly token: Token;
|
|
31
|
-
readonly ctorName: string;
|
|
32
|
-
constructor(token: Token, ctorName: string);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* A constructor has DepRecord signatures, but none of them is directly
|
|
36
|
-
* satisfiable in the owning scope (every signature names at least one token
|
|
37
|
-
* that is not registered, or contains a hole this phase cannot fill).
|
|
38
|
-
*/
|
|
39
|
-
export declare class NoSatisfiableSignatureError extends DiError {
|
|
40
|
-
readonly token: Token;
|
|
41
|
-
readonly ctorName: string;
|
|
42
|
-
readonly unsatisfiable: readonly Token[];
|
|
43
|
-
constructor(token: Token, ctorName: string, unsatisfiable: readonly Token[]);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* A token reappeared on the active resolution stack — the dependency graph has
|
|
47
|
-
* a cycle. The message includes the full path that closed the loop.
|
|
48
|
-
*/
|
|
49
|
-
export declare class CircularDependencyError extends DiError {
|
|
50
|
-
readonly path: readonly Token[];
|
|
51
|
-
constructor(path: readonly Token[]);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* A constructor parameter is typed as a factory of some token (a `FactoryRef`),
|
|
55
|
-
* but that token cannot be turned into a factory: either it is not registered,
|
|
56
|
-
* or it is registered as a `useValue` / `useFactory` override rather than a
|
|
57
|
-
* class. A factory injects a callable that constructs the target class on
|
|
58
|
-
* demand, so the target must be a class registration.
|
|
59
|
-
*/
|
|
60
|
-
export declare class FactoryTargetError extends DiError {
|
|
61
|
-
readonly factoryToken: Token;
|
|
62
|
-
readonly reason: "unregistered" | "not-a-class";
|
|
63
|
-
constructor(factoryToken: Token, reason: "unregistered" | "not-a-class");
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Sync `dispose()` was called on a scope that owns a Promise-valued (thenable)
|
|
67
|
-
* cached instance. A pending Promise cannot be disposed synchronously — the
|
|
68
|
-
* caller must use `disposeAsync()`.
|
|
69
|
-
*/
|
|
70
|
-
export declare class AsyncDisposalRequiredError extends DiError {
|
|
71
|
-
constructor();
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,uDAAuD;AACvD,qBAAa,OAAQ,SAAQ,KAAK;gBACb,OAAO,EAAE,MAAM;CAInC;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,OAAO;aACd,KAAK,EAAE,KAAK;gBAAZ,KAAK,EAAE,KAAK;CAMhD;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,OAAO;aAE1B,KAAK,EAAE,KAAK;aACZ,GAAG,EAAE,MAAM;aACX,eAAe,EAAE,SAAS,MAAM,EAAE;gBAFlC,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,SAAS,MAAM,EAAE;CAerD;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;aAE7B,KAAK,EAAE,KAAK;aACZ,QAAQ,EAAE,MAAM;gBADhB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM;CAUnC;AAED;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,OAAO;aAEpC,KAAK,EAAE,KAAK;aACZ,QAAQ,EAAE,MAAM;aAChB,aAAa,EAAE,SAAS,KAAK,EAAE;gBAF/B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,SAAS,KAAK,EAAE;CAelD;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,OAAO;aACf,IAAI,EAAE,SAAS,KAAK,EAAE;gBAAtB,IAAI,EAAE,SAAS,KAAK,EAAE;CAG1D;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,OAAO;aAE3B,YAAY,EAAE,KAAK;aACnB,MAAM,EAAE,cAAc,GAAG,aAAa;gBADtC,YAAY,EAAE,KAAK,EACnB,MAAM,EAAE,cAAc,GAAG,aAAa;CAezD;AAED;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,OAAO;;CAQtD"}
|
package/dist/errors.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// Typed error classes for the runtime engine.
|
|
2
|
-
//
|
|
3
|
-
// Each failure mode the resolver can hit gets its own class so consumers can
|
|
4
|
-
// branch on `instanceof` rather than string-matching messages. Messages are
|
|
5
|
-
// written for a human reading a stack trace at the moment a graph fails to
|
|
6
|
-
// resolve.
|
|
7
|
-
/** Base class for every error the container raises. */
|
|
8
|
-
export class DiError extends Error {
|
|
9
|
-
constructor(message) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.name = new.target.name;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* A token was requested but no registration exists for it anywhere in the
|
|
16
|
-
* resolving scope's chain (nor on the builder's base map).
|
|
17
|
-
*/
|
|
18
|
-
export class UnregisteredTokenError extends DiError {
|
|
19
|
-
token;
|
|
20
|
-
constructor(token) {
|
|
21
|
-
super(`No registration found for token "${token}". Register it with ` +
|
|
22
|
-
`services.add(...)/.register(...) before resolving.`);
|
|
23
|
-
this.token = token;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* A registration carries a lifetime tag, but no ancestor scope in the resolving
|
|
28
|
-
* chain has a matching name. This is the captive-dependency / misconfiguration
|
|
29
|
-
* detector — the engine never auto-creates a scope to satisfy the tag.
|
|
30
|
-
*/
|
|
31
|
-
export class MissingScopeError extends DiError {
|
|
32
|
-
token;
|
|
33
|
-
tag;
|
|
34
|
-
availableScopes;
|
|
35
|
-
constructor(token, tag, availableScopes) {
|
|
36
|
-
super(`Cannot resolve "${token}": its lifetime is tagged "${tag}", but no ` +
|
|
37
|
-
`ancestor scope with that name exists in the resolving chain ` +
|
|
38
|
-
`(available: ${availableScopes.length > 0
|
|
39
|
-
? availableScopes.map((s) => `"${s}"`).join(" → ")
|
|
40
|
-
: "none"}). ` +
|
|
41
|
-
`This usually means a longer-lived service depends on a ` +
|
|
42
|
-
`shorter-lived one (e.g. a "singleton" needing a "request"). Never ` +
|
|
43
|
-
`auto-created — fix the registration's lifetime or create the scope.`);
|
|
44
|
-
this.token = token;
|
|
45
|
-
this.tag = tag;
|
|
46
|
-
this.availableScopes = availableScopes;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* A constructor with parameters has no DepRecord in the WeakMap — the
|
|
51
|
-
* transformer never saw it and it was never hand-annotated.
|
|
52
|
-
*/
|
|
53
|
-
export class MissingMetadataError extends DiError {
|
|
54
|
-
token;
|
|
55
|
-
ctorName;
|
|
56
|
-
constructor(token, ctorName) {
|
|
57
|
-
super(`No dep metadata found for ${ctorName} (resolving "${token}"). The ` +
|
|
58
|
-
`constructor has parameters but no @signature, forCtor, or ` +
|
|
59
|
-
`transformer-generated defineDeps call was found. Use ` +
|
|
60
|
-
`forCtor(...).signature(...) or register it with useFactory to wire ` +
|
|
61
|
-
`it manually.`);
|
|
62
|
-
this.token = token;
|
|
63
|
-
this.ctorName = ctorName;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* A constructor has DepRecord signatures, but none of them is directly
|
|
68
|
-
* satisfiable in the owning scope (every signature names at least one token
|
|
69
|
-
* that is not registered, or contains a hole this phase cannot fill).
|
|
70
|
-
*/
|
|
71
|
-
export class NoSatisfiableSignatureError extends DiError {
|
|
72
|
-
token;
|
|
73
|
-
ctorName;
|
|
74
|
-
unsatisfiable;
|
|
75
|
-
constructor(token, ctorName, unsatisfiable) {
|
|
76
|
-
super(`No satisfiable constructor signature for ${ctorName} (resolving ` +
|
|
77
|
-
`"${token}"). Every candidate signature names a dependency that is ` +
|
|
78
|
-
`not registered in the owning scope` +
|
|
79
|
-
(unsatisfiable.length > 0
|
|
80
|
-
? `; unsatisfiable tokens: ${unsatisfiable
|
|
81
|
-
.map((t) => `"${t}"`)
|
|
82
|
-
.join(", ")}`
|
|
83
|
-
: "") +
|
|
84
|
-
`. Register the missing dependencies, or provide a useFactory ` +
|
|
85
|
-
`override.`);
|
|
86
|
-
this.token = token;
|
|
87
|
-
this.ctorName = ctorName;
|
|
88
|
-
this.unsatisfiable = unsatisfiable;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* A token reappeared on the active resolution stack — the dependency graph has
|
|
93
|
-
* a cycle. The message includes the full path that closed the loop.
|
|
94
|
-
*/
|
|
95
|
-
export class CircularDependencyError extends DiError {
|
|
96
|
-
path;
|
|
97
|
-
constructor(path) {
|
|
98
|
-
super(`Circular dependency detected:\n ${path.join(" → ")}`);
|
|
99
|
-
this.path = path;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* A constructor parameter is typed as a factory of some token (a `FactoryRef`),
|
|
104
|
-
* but that token cannot be turned into a factory: either it is not registered,
|
|
105
|
-
* or it is registered as a `useValue` / `useFactory` override rather than a
|
|
106
|
-
* class. A factory injects a callable that constructs the target class on
|
|
107
|
-
* demand, so the target must be a class registration.
|
|
108
|
-
*/
|
|
109
|
-
export class FactoryTargetError extends DiError {
|
|
110
|
-
factoryToken;
|
|
111
|
-
reason;
|
|
112
|
-
constructor(factoryToken, reason) {
|
|
113
|
-
super(reason === "unregistered"
|
|
114
|
-
? `Cannot inject a factory for "${factoryToken}": no registration ` +
|
|
115
|
-
`found for it. A factory parameter (typed \`() => IFoo\`) needs ` +
|
|
116
|
-
`the target registered as a class with ` +
|
|
117
|
-
`services.add(...) before it can build instances.`
|
|
118
|
-
: `Cannot inject a factory for "${factoryToken}": it is registered ` +
|
|
119
|
-
`as a useValue/useFactory override, not a class. A factory builds ` +
|
|
120
|
-
`its target with \`new\`, so the target must be a class ` +
|
|
121
|
-
`registration. Resolve it directly instead of as a factory, or ` +
|
|
122
|
-
`register the class with services.add(...).`);
|
|
123
|
-
this.factoryToken = factoryToken;
|
|
124
|
-
this.reason = reason;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Sync `dispose()` was called on a scope that owns a Promise-valued (thenable)
|
|
129
|
-
* cached instance. A pending Promise cannot be disposed synchronously — the
|
|
130
|
-
* caller must use `disposeAsync()`.
|
|
131
|
-
*/
|
|
132
|
-
export class AsyncDisposalRequiredError extends DiError {
|
|
133
|
-
constructor() {
|
|
134
|
-
super(`Cannot dispose synchronously: this scope owns a Promise-valued ` +
|
|
135
|
-
`instance (an async useFactory result). Awaiting it is required ` +
|
|
136
|
-
`before disposal — call disposeAsync() instead of dispose().`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,YAAY,EACV,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,OAAO,EACP,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,8CAA8C;AAC9C,EAAE;AACF,+EAA+E;AAC/E,sEAAsE;AACtE,qEAAqE;AACrE,EAAE;AACF,gFAAgF;AAChF,0EAA0E;AAC1E,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAanC,OAAO,EACL,OAAO,EACP,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/scope.d.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import type { Token } from "@fnioc/core";
|
|
2
|
-
import type { Registration, ResolveScope } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* A node in the scope chain. Created from a `DiBuilder` (the root) or from a
|
|
5
|
-
* parent scope (`.createScope`). Holds the instances it owns and any local
|
|
6
|
-
* override registrations.
|
|
7
|
-
*
|
|
8
|
-
* The generic `Scopes` is the user's scope-name union, threaded so
|
|
9
|
-
* `.createScope` only accepts declared names.
|
|
10
|
-
*/
|
|
11
|
-
export declare class Scope<Scopes extends string = string> implements ResolveScope {
|
|
12
|
-
/** This scope's tag name. The root scope's name is its lifetime. */
|
|
13
|
-
readonly name: Scopes;
|
|
14
|
-
/** The parent scope, or `undefined` for the root. */
|
|
15
|
-
private readonly parent;
|
|
16
|
-
/** The builder's base registration map (shared, walked last). */
|
|
17
|
-
private readonly baseRegistrations;
|
|
18
|
-
/** Local override registrations held at this scope (shadow ancestors). */
|
|
19
|
-
private readonly localRegistrations;
|
|
20
|
-
/** Instances this scope owns and caches, keyed by token. */
|
|
21
|
-
private readonly instances;
|
|
22
|
-
/** Owned instances in construction order — disposed in reverse. */
|
|
23
|
-
private readonly ownedOrder;
|
|
24
|
-
private disposed;
|
|
25
|
-
constructor(
|
|
26
|
-
/** This scope's tag name. The root scope's name is its lifetime. */
|
|
27
|
-
name: Scopes,
|
|
28
|
-
/** The parent scope, or `undefined` for the root. */
|
|
29
|
-
parent: Scope<Scopes> | undefined,
|
|
30
|
-
/** The builder's base registration map (shared, walked last). */
|
|
31
|
-
baseRegistrations: ReadonlyMap<Token, Registration>);
|
|
32
|
-
/** Creates a parent-linked child scope with the given (declared) name. */
|
|
33
|
-
createScope(childName: Scopes): Scope<Scopes>;
|
|
34
|
-
/**
|
|
35
|
-
* Registers a scope-local override. Shadows any ancestor or base registration
|
|
36
|
-
* for the same token, for this scope and its descendants only. The override
|
|
37
|
-
* paths (`useFactory` / `useValue`) are also available here so a single scope
|
|
38
|
-
* (e.g. a test scope) can swap an implementation without rebuilding the
|
|
39
|
-
* builder.
|
|
40
|
-
*/
|
|
41
|
-
registerFactory<T>(token: Token, useFactory: (scope: ResolveScope) => T, tag?: Scopes): this;
|
|
42
|
-
/** Registers a scope-local `useValue` override (see `registerFactory`). */
|
|
43
|
-
registerValue<T>(token: Token, useValue: T): this;
|
|
44
|
-
/**
|
|
45
|
-
* Resolves a token to an instance, walking the parent chain for both the
|
|
46
|
-
* registration and the owning scope. The public entry point starts a fresh
|
|
47
|
-
* cycle-detection stack.
|
|
48
|
-
*/
|
|
49
|
-
resolve<T>(token: Token): T;
|
|
50
|
-
/**
|
|
51
|
-
* Walks UP the chain (this scope's locals → ancestors' locals → base map),
|
|
52
|
-
* returning the nearest registration for `token`. Child shadows parent.
|
|
53
|
-
*/
|
|
54
|
-
private lookup;
|
|
55
|
-
/**
|
|
56
|
-
* Finds the nearest ancestor scope (inclusive of this one) whose name matches
|
|
57
|
-
* `tag`, walking UP the chain. Returns `undefined` when none matches.
|
|
58
|
-
*/
|
|
59
|
-
private findOwner;
|
|
60
|
-
/** The chain of scope names from this scope up to the root, for diagnostics. */
|
|
61
|
-
private chainNames;
|
|
62
|
-
/**
|
|
63
|
-
* The internal resolver. `stack` is the active resolution path (for cycle
|
|
64
|
-
* detection); it is shared across the whole `resolve()` call but never across
|
|
65
|
-
* separate calls.
|
|
66
|
-
*/
|
|
67
|
-
private resolveWith;
|
|
68
|
-
/**
|
|
69
|
-
* Builds an instance for `registration`. `owningScope` is the scope whose
|
|
70
|
-
* chain the dependencies are resolved against — THE critical rule. For a
|
|
71
|
-
* factory override that is the scope passed to the closure; for a class it is
|
|
72
|
-
* the scope its ctor deps resolve relative to.
|
|
73
|
-
*/
|
|
74
|
-
private instantiate;
|
|
75
|
-
/**
|
|
76
|
-
* Constructs a class instance on a DIRECT resolve, resolving its constructor
|
|
77
|
-
* dependencies relative to THIS scope (the owning scope). Performs greedy
|
|
78
|
-
* signature selection over the ctor's DepRecord, then fills each slot:
|
|
79
|
-
*
|
|
80
|
-
* - a string token → resolved through this scope's chain (selection
|
|
81
|
-
* guarantees every string-token slot here is resolvable);
|
|
82
|
-
* - a `FactoryRef` → injected as a callable (see `makeFactory`);
|
|
83
|
-
* - a `null` hole → there is no caller on a direct resolve, so it lands as
|
|
84
|
-
* `undefined`. Holes are meaningfully filled only when the class is a
|
|
85
|
-
* factory target — see `constructPartitioned`.
|
|
86
|
-
*/
|
|
87
|
-
private construct;
|
|
88
|
-
/**
|
|
89
|
-
* Builds the callable injected for a `FactoryRef` parameter.
|
|
90
|
-
*
|
|
91
|
-
* The target ctor's signature is partitioned at CALL time against the live
|
|
92
|
-
* registration map: each slot that is a registered token is resolved; each
|
|
93
|
-
* slot that is an unregistered token or a `null` hole takes the next
|
|
94
|
-
* caller-supplied argument, positionally. The injected callable therefore
|
|
95
|
-
* exposes only the target's unregistered parameters, in their relative order
|
|
96
|
-
* — no Ramda-style placeholders, no leaked constructor arity.
|
|
97
|
-
*
|
|
98
|
-
* Lifetime semantics:
|
|
99
|
-
* - A ZERO-ARG factory (the target ctor has no holes / unregistered params)
|
|
100
|
-
* routes the build through the normal `resolve` path, so it RESPECTS the
|
|
101
|
-
* target's registered lifetime: a singleton target yields the same
|
|
102
|
-
* instance on every call; a transient target yields a fresh one.
|
|
103
|
-
* - A PARAMETERIZED factory (the target has holes / unregistered params
|
|
104
|
-
* filled per call) constructs a FRESH instance on every call and BYPASSES
|
|
105
|
-
* the instance cache. Caller args differ per call, so caching would be
|
|
106
|
-
* wrong — two calls with different arguments must not collapse to one
|
|
107
|
-
* cached instance.
|
|
108
|
-
*
|
|
109
|
-
* The closure captures `this` as the owning scope. §5.4 holds at call time:
|
|
110
|
-
* the target's deps resolve relative to the scope that owns the
|
|
111
|
-
* factory-holding instance, exactly as a direct resolve would — so a factory
|
|
112
|
-
* captured by a singleton that tries to build a request-scoped target still
|
|
113
|
-
* throws `MissingScopeError` when invoked.
|
|
114
|
-
*/
|
|
115
|
-
private makeFactory;
|
|
116
|
-
/**
|
|
117
|
-
* Constructs a factory target, partitioning its already-selected signature
|
|
118
|
-
* against the live registration map: a registered token is resolved; an
|
|
119
|
-
* unregistered token or a `null` hole takes the next caller-supplied argument
|
|
120
|
-
* positionally. Always a fresh instance — a parameterized factory bypasses
|
|
121
|
-
* the instance cache (caller args differ per call). Runs on a fresh cycle
|
|
122
|
-
* stack since the factory is invoked outside the original resolve.
|
|
123
|
-
*/
|
|
124
|
-
private constructPartitioned;
|
|
125
|
-
/**
|
|
126
|
-
* Greedy signature selection. Scans signatures longest → shortest and returns
|
|
127
|
-
* the first SATISFIABLE one. A slot is satisfiable when it is:
|
|
128
|
-
*
|
|
129
|
-
* - a `null` hole — always satisfiable; filled by a caller arg (a direct
|
|
130
|
-
* resolve supplies nothing, so it lands as `undefined`);
|
|
131
|
-
* - a `FactoryRef` — always satisfiable; injected as a callable. The
|
|
132
|
-
* factory's target need not be resolvable for the slot to count (an
|
|
133
|
-
* unregistered target surfaces a `FactoryTargetError` when the factory is
|
|
134
|
-
* built / called, not here); or
|
|
135
|
-
* - a string token whose registration is resolvable in this (the owning)
|
|
136
|
-
* scope's chain.
|
|
137
|
-
*
|
|
138
|
-
* Only string tokens can be UNsatisfiable. A signature is satisfiable iff
|
|
139
|
-
* every string-token slot is resolvable.
|
|
140
|
-
*
|
|
141
|
-
* - Equal-arity ties break by registration order (the order signatures appear
|
|
142
|
-
* in the DepRecord), which `sort`'s stability preserves.
|
|
143
|
-
* - None satisfiable ⇒ throw naming the unsatisfiable tokens.
|
|
144
|
-
*/
|
|
145
|
-
private selectSignature;
|
|
146
|
-
/**
|
|
147
|
-
* Greedy signature selection for a FACTORY TARGET. Unlike `selectSignature`,
|
|
148
|
-
* there is no resolvability gate: a target's unregistered tokens are not
|
|
149
|
-
* unsatisfiable — they are the factory's caller-supplied parameters. So the
|
|
150
|
-
* choice is purely the longest signature, equal-arity ties broken by
|
|
151
|
-
* registration order (`sort` stability). Always returns a signature (the
|
|
152
|
-
* caller has already checked `signatures.length > 0`).
|
|
153
|
-
*/
|
|
154
|
-
private selectTargetSignature;
|
|
155
|
-
/** True when `token` has a registration somewhere in this scope's chain. */
|
|
156
|
-
private isResolvable;
|
|
157
|
-
/**
|
|
158
|
-
* Closes this scope synchronously, disposing the instances it owns in REVERSE
|
|
159
|
-
* construction order. Only native `Disposable` instances are disposed.
|
|
160
|
-
*
|
|
161
|
-
* Throws `AsyncDisposalRequiredError` if any owned instance is a Promise
|
|
162
|
-
* (thenable) — a pending Promise cannot be disposed synchronously; the caller
|
|
163
|
-
* must use `disposeAsync()`. Idempotent: a second call is a no-op.
|
|
164
|
-
*/
|
|
165
|
-
dispose(): void;
|
|
166
|
-
/**
|
|
167
|
-
* Closes this scope asynchronously. Awaits each owned Promise-valued instance
|
|
168
|
-
* first (so an async factory's result settles before teardown), then disposes
|
|
169
|
-
* owned instances in REVERSE construction order — honoring both
|
|
170
|
-
* `Symbol.asyncDispose` and `Symbol.dispose`. Idempotent.
|
|
171
|
-
*/
|
|
172
|
-
disposeAsync(): Promise<void>;
|
|
173
|
-
/** Drops owned references after disposal so they can be collected. */
|
|
174
|
-
private clear;
|
|
175
|
-
/** Native `using` support — delegates to `dispose()`. */
|
|
176
|
-
[Symbol.dispose](): void;
|
|
177
|
-
/** Native `await using` support — delegates to `disposeAsync()`. */
|
|
178
|
-
[Symbol.asyncDispose](): Promise<void>;
|
|
179
|
-
}
|
|
180
|
-
//# sourceMappingURL=scope.d.ts.map
|
package/dist/scope.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAuB,KAAK,EAAE,MAAM,aAAa,CAAC;AAW9D,OAAO,KAAK,EAGV,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AA4CpB;;;;;;;GAOG;AACH,qBAAa,KAAK,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,CAAE,YAAW,YAAY;IAatE,oEAAoE;aACpD,IAAI,EAAE,MAAM;IAC5B,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAjBpC,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAkC;IAErE,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAEvD,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAE5C,OAAO,CAAC,QAAQ,CAAS;;IAGvB,oEAAoE;IACpD,IAAI,EAAE,MAAM;IAC5B,qDAAqD;IACpC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS;IAClD,iEAAiE;IAChD,iBAAiB,EAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC;IAGtE,0EAA0E;IACnE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAIpD;;;;;;OAMG;IACI,eAAe,CAAC,CAAC,EACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,CAAC,EACtC,GAAG,CAAC,EAAE,MAAM,GACX,IAAI;IASP,2EAA2E;IACpE,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAKxD;;;;OAIG;IACI,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;IAMlC;;;OAGG;IACH,OAAO,CAAC,MAAM;IAWd;;;OAGG;IACH,OAAO,CAAC,SAAS;IAUjB,gFAAgF;IAChF,OAAO,CAAC,UAAU;IAalB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAsDnB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAmBnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,SAAS;IAgCjB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,CAAC,WAAW;IAgDnB;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,eAAe;IAiCvB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAY7B,4EAA4E;IAC5E,OAAO,CAAC,YAAY;IAMpB;;;;;;;OAOG;IACI,OAAO,IAAI,IAAI;IAmBtB;;;;;OAKG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB1C,sEAAsE;IACtE,OAAO,CAAC,KAAK;IAKb,yDAAyD;IAClD,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAI/B,oEAAoE;IAC7D,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAG9C"}
|