@illuma/core 1.1.0 → 1.2.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/CHANGELOG.md +14 -0
- package/README.md +170 -170
- package/dist/index.cjs +101 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -76
- package/dist/index.d.ts +120 -76
- package/dist/index.js +99 -20
- package/dist/index.js.map +1 -1
- package/dist/{injection-Y_bVmBSk.d.ts → injection-CJGqGWJ6.d.cts} +1 -1
- package/dist/{injection-CSxu56ds.d.cts → injection-D22uAh1O.d.ts} +1 -1
- package/dist/{plugin-container-CwkVlVS4.d.ts → plugin-container-CUw26ZhP.d.ts} +21 -18
- package/dist/{plugin-container-D8Zwpigq.d.cts → plugin-container-n0FIqLbh.d.cts} +21 -18
- package/dist/plugins.d.cts +3 -3
- package/dist/plugins.d.ts +3 -3
- package/dist/testkit.cjs +62 -20
- package/dist/testkit.cjs.map +1 -1
- package/dist/testkit.d.cts +2 -2
- package/dist/testkit.d.ts +2 -2
- package/dist/testkit.js +62 -20
- package/dist/testkit.js.map +1 -1
- package/dist/{providers-D9YA8L_g.d.cts → token-BvQrvm-Q.d.cts} +73 -73
- package/dist/{providers-D9YA8L_g.d.ts → token-BvQrvm-Q.d.ts} +73 -73
- package/package.json +74 -74
package/dist/index.js
CHANGED
|
@@ -2,6 +2,29 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/lib/errors.ts
|
|
5
|
+
var ERR_CODES = {
|
|
6
|
+
// Provider errors
|
|
7
|
+
DUPLICATE_PROVIDER: 100,
|
|
8
|
+
DUPLICATE_FACTORY: 101,
|
|
9
|
+
INVALID_CTOR: 102,
|
|
10
|
+
INVALID_PROVIDER: 103,
|
|
11
|
+
// Alias errors
|
|
12
|
+
INVALID_ALIAS: 200,
|
|
13
|
+
LOOP_ALIAS: 201,
|
|
14
|
+
// Bootstrap errors
|
|
15
|
+
NOT_BOOTSTRAPPED: 300,
|
|
16
|
+
BOOTSTRAPPED: 301,
|
|
17
|
+
DOUBLE_BOOTSTRAP: 302,
|
|
18
|
+
// Retrieval errors
|
|
19
|
+
NOT_FOUND: 400,
|
|
20
|
+
CIRCULAR_DEPENDENCY: 401,
|
|
21
|
+
// Instantiation errors
|
|
22
|
+
UNTRACKED: 500,
|
|
23
|
+
OUTSIDE_CONTEXT: 501,
|
|
24
|
+
CALLED_UTILS_OUTSIDE_CONTEXT: 502,
|
|
25
|
+
INSTANCE_ACCESS_FAILED: 503,
|
|
26
|
+
ACCESS_FAILED: 504
|
|
27
|
+
};
|
|
5
28
|
var InjectionError = class _InjectionError extends Error {
|
|
6
29
|
static {
|
|
7
30
|
__name(this, "InjectionError");
|
|
@@ -13,66 +36,70 @@ var InjectionError = class _InjectionError extends Error {
|
|
|
13
36
|
}
|
|
14
37
|
// Provider errors
|
|
15
38
|
static duplicate(token) {
|
|
16
|
-
return new _InjectionError(
|
|
39
|
+
return new _InjectionError(ERR_CODES.DUPLICATE_PROVIDER, `Duplicate provider for token "${token.toString()}" detected.`);
|
|
17
40
|
}
|
|
18
41
|
static duplicateFactory(token) {
|
|
19
|
-
return new _InjectionError(
|
|
42
|
+
return new _InjectionError(ERR_CODES.DUPLICATE_FACTORY, `Tried to re-provide factory for token "${token.toString()}" detected.`);
|
|
20
43
|
}
|
|
21
44
|
static invalidCtor(ctor) {
|
|
22
|
-
return new _InjectionError(
|
|
45
|
+
return new _InjectionError(ERR_CODES.INVALID_CTOR, `Cannot use constructor for token "${ctor.name}". Please make sure to use @nodeInjectable() decorator`);
|
|
23
46
|
}
|
|
24
47
|
static invalidProvider(provider) {
|
|
25
|
-
return new _InjectionError(
|
|
48
|
+
return new _InjectionError(ERR_CODES.INVALID_PROVIDER, `Cannot use provider as it is neither a NodeToken nor MultiNodeToken nor a valid constructor.:
|
|
26
49
|
${provider}`);
|
|
27
50
|
}
|
|
28
51
|
// Alias errors
|
|
29
52
|
static invalidAlias(alias) {
|
|
30
53
|
const aliasStr = typeof alias === "function" ? alias.name || "Unknown" : String(alias);
|
|
31
|
-
return new _InjectionError(
|
|
54
|
+
return new _InjectionError(ERR_CODES.INVALID_ALIAS, `Invalid alias target "${aliasStr}". Alias must be a NodeToken, MultiNodeToken, or a class decorated with @NodeInjectable().`);
|
|
32
55
|
}
|
|
33
56
|
static loopAlias(alias) {
|
|
34
|
-
return new _InjectionError(
|
|
57
|
+
return new _InjectionError(ERR_CODES.LOOP_ALIAS, `Token "${alias.toString()}" cannot alias itself in a loop.`);
|
|
35
58
|
}
|
|
36
59
|
// Bootstrap errors
|
|
37
60
|
static notBootstrapped() {
|
|
38
|
-
return new _InjectionError(
|
|
61
|
+
return new _InjectionError(ERR_CODES.NOT_BOOTSTRAPPED, "Cannot retrieve providers before the container has been bootstrapped.");
|
|
39
62
|
}
|
|
40
63
|
static bootstrapped() {
|
|
41
|
-
return new _InjectionError(
|
|
64
|
+
return new _InjectionError(ERR_CODES.BOOTSTRAPPED, "Cannot modify providers after the container has been bootstrapped.");
|
|
42
65
|
}
|
|
43
66
|
static doubleBootstrap() {
|
|
44
|
-
return new _InjectionError(
|
|
67
|
+
return new _InjectionError(ERR_CODES.DOUBLE_BOOTSTRAP, "Container has already been bootstrapped and cannot be bootstrapped again.");
|
|
45
68
|
}
|
|
46
69
|
// Retrieval errors
|
|
47
70
|
static notFound(token) {
|
|
48
|
-
return new _InjectionError(
|
|
71
|
+
return new _InjectionError(ERR_CODES.NOT_FOUND, `No provider found for "${token.toString()}".`);
|
|
49
72
|
}
|
|
50
73
|
static circularDependency(provider, path) {
|
|
51
74
|
const providerStr = provider instanceof NodeBase ? provider.toString() : provider.name;
|
|
52
75
|
const pathStr = path.map((p) => p instanceof NodeBase ? p.toString() : p.name).join(" -> ");
|
|
53
|
-
return new _InjectionError(
|
|
76
|
+
return new _InjectionError(ERR_CODES.CIRCULAR_DEPENDENCY, `Circular dependency detected while resolving "${providerStr}":
|
|
54
77
|
${pathStr}`);
|
|
55
78
|
}
|
|
56
79
|
// Instantiation errors
|
|
57
80
|
static untracked(token, parent) {
|
|
58
81
|
const tokenStr = token instanceof NodeBase ? token.toString() : token.name;
|
|
59
82
|
const parentStr = parent instanceof NodeBase ? parent.toString() : parent.name;
|
|
60
|
-
return new _InjectionError(
|
|
83
|
+
return new _InjectionError(ERR_CODES.UNTRACKED, `Cannot instantiate ${parentStr} because it depends on untracked injection ${tokenStr}. Please make sure all injections are properly tracked.`);
|
|
61
84
|
}
|
|
62
85
|
static outsideContext(token) {
|
|
63
86
|
const tokenStr = token instanceof NodeBase ? token.toString() : token.name;
|
|
64
|
-
return new _InjectionError(
|
|
87
|
+
return new _InjectionError(ERR_CODES.OUTSIDE_CONTEXT, `Cannot inject "${tokenStr}" outside of an injection context.`);
|
|
65
88
|
}
|
|
66
89
|
static calledUtilsOutsideContext() {
|
|
67
|
-
return new _InjectionError(
|
|
90
|
+
return new _InjectionError(ERR_CODES.CALLED_UTILS_OUTSIDE_CONTEXT, "Cannot call injection utilities outside of an injection context.");
|
|
68
91
|
}
|
|
69
92
|
static instanceAccessFailed(token) {
|
|
70
|
-
return new _InjectionError(
|
|
93
|
+
return new _InjectionError(ERR_CODES.INSTANCE_ACCESS_FAILED, `Failed to access instance for token "${token.toString()}". It was not properly instantiated.`);
|
|
71
94
|
}
|
|
72
95
|
static accessFailed() {
|
|
73
|
-
return new _InjectionError(
|
|
96
|
+
return new _InjectionError(ERR_CODES.ACCESS_FAILED, "Failed to access the requested instance due to an unknown error.");
|
|
74
97
|
}
|
|
75
98
|
};
|
|
99
|
+
function isNotFoundError(error) {
|
|
100
|
+
return error instanceof InjectionError && error.code === ERR_CODES.NOT_FOUND;
|
|
101
|
+
}
|
|
102
|
+
__name(isNotFoundError, "isNotFoundError");
|
|
76
103
|
|
|
77
104
|
// src/lib/api/token.ts
|
|
78
105
|
var NodeBase = class {
|
|
@@ -435,23 +462,29 @@ var TreeRootNode = class {
|
|
|
435
462
|
static {
|
|
436
463
|
__name(this, "TreeRootNode");
|
|
437
464
|
}
|
|
465
|
+
instant;
|
|
438
466
|
_deps = /* @__PURE__ */ new Set();
|
|
439
467
|
_treePool = /* @__PURE__ */ new Map();
|
|
468
|
+
constructor(instant = true) {
|
|
469
|
+
this.instant = instant;
|
|
470
|
+
}
|
|
440
471
|
get dependencies() {
|
|
441
472
|
return this._deps;
|
|
442
473
|
}
|
|
443
474
|
addDependency(node) {
|
|
444
475
|
this._deps.add(node);
|
|
445
476
|
}
|
|
446
|
-
|
|
477
|
+
build() {
|
|
447
478
|
for (const dep of this._deps) {
|
|
448
|
-
dep.instantiate(this._treePool);
|
|
449
479
|
if ("token" in dep.proto) this._treePool.set(dep.proto.token, dep);
|
|
480
|
+
if (this.instant) dep.instantiate(this._treePool);
|
|
481
|
+
else dep.collectPool(this._treePool);
|
|
450
482
|
}
|
|
451
483
|
}
|
|
452
484
|
find(token) {
|
|
453
485
|
const node = this._treePool.get(token);
|
|
454
486
|
if (!node) return null;
|
|
487
|
+
if (!this.instant) node.instantiate(this._treePool);
|
|
455
488
|
return node;
|
|
456
489
|
}
|
|
457
490
|
toString() {
|
|
@@ -482,6 +515,11 @@ var TreeNodeSingle = class {
|
|
|
482
515
|
else this._deps.set(node.proto.token, node);
|
|
483
516
|
node.allocations++;
|
|
484
517
|
}
|
|
518
|
+
collectPool(pool) {
|
|
519
|
+
for (const node of this._deps.values()) node.collectPool(pool);
|
|
520
|
+
for (const dep of this._transparent) dep.collectPool(pool);
|
|
521
|
+
pool.set(this.proto.token, this);
|
|
522
|
+
}
|
|
485
523
|
instantiate(pool) {
|
|
486
524
|
if (this._resolved) return;
|
|
487
525
|
for (const node of this._deps.values()) node.instantiate(pool);
|
|
@@ -519,6 +557,10 @@ var TreeNodeTransparent = class _TreeNodeTransparent {
|
|
|
519
557
|
else this._deps.set(node.proto.token, node);
|
|
520
558
|
node.allocations++;
|
|
521
559
|
}
|
|
560
|
+
collectPool(pool) {
|
|
561
|
+
for (const node of this._deps.values()) node.collectPool(pool);
|
|
562
|
+
for (const dep of this._transparent) dep.collectPool(pool);
|
|
563
|
+
}
|
|
522
564
|
instantiate(pool) {
|
|
523
565
|
if (this._resolved) return;
|
|
524
566
|
for (const dep of this._transparent) dep.instantiate(pool);
|
|
@@ -543,6 +585,10 @@ var TreeNodeMulti = class _TreeNodeMulti {
|
|
|
543
585
|
constructor(proto) {
|
|
544
586
|
this.proto = proto;
|
|
545
587
|
}
|
|
588
|
+
collectPool(pool) {
|
|
589
|
+
for (const dep of this._deps) dep.collectPool(pool);
|
|
590
|
+
pool.set(this.proto.token, this);
|
|
591
|
+
}
|
|
546
592
|
instantiate(pool) {
|
|
547
593
|
if (this._resolved) return;
|
|
548
594
|
for (const dep of this._deps) {
|
|
@@ -719,6 +765,37 @@ var InjectorImpl = class {
|
|
|
719
765
|
};
|
|
720
766
|
var Injector = new NodeToken("Injector");
|
|
721
767
|
|
|
768
|
+
// src/lib/utils/defer.ts
|
|
769
|
+
function injectDefer(provider, options) {
|
|
770
|
+
const injector = nodeInject(Injector);
|
|
771
|
+
let token = provider;
|
|
772
|
+
if (isInjectable(provider)) token = getInjectableToken(provider);
|
|
773
|
+
if (!isNodeBase(token)) throw InjectionError.invalidProvider(String(token));
|
|
774
|
+
let resolved = false;
|
|
775
|
+
let instance = SHAPE_SHIFTER;
|
|
776
|
+
return () => {
|
|
777
|
+
if (resolved) return instance;
|
|
778
|
+
if (options?.optional) {
|
|
779
|
+
try {
|
|
780
|
+
instance = injector.get(token);
|
|
781
|
+
resolved = true;
|
|
782
|
+
return instance;
|
|
783
|
+
} catch (e) {
|
|
784
|
+
if (isNotFoundError(e)) {
|
|
785
|
+
resolved = true;
|
|
786
|
+
instance = null;
|
|
787
|
+
return instance;
|
|
788
|
+
}
|
|
789
|
+
throw e;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
instance = injector.get(token);
|
|
793
|
+
resolved = true;
|
|
794
|
+
return instance;
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
__name(injectDefer, "injectDefer");
|
|
798
|
+
|
|
722
799
|
// src/lib/utils/inheritance.ts
|
|
723
800
|
function injectGroupAsync(fn, opts) {
|
|
724
801
|
const { container: parent } = nodeInject(Injector);
|
|
@@ -913,7 +990,7 @@ var NodeContainer = class extends Illuma {
|
|
|
913
990
|
return parentNode.findNode(token);
|
|
914
991
|
}
|
|
915
992
|
_buildInjectionTree() {
|
|
916
|
-
const root = new TreeRootNode();
|
|
993
|
+
const root = new TreeRootNode(this._opts?.instant);
|
|
917
994
|
const cache = /* @__PURE__ */ new Map();
|
|
918
995
|
const nodes = [
|
|
919
996
|
...this._protoNodes.values(),
|
|
@@ -958,7 +1035,7 @@ var NodeContainer = class extends Illuma {
|
|
|
958
1035
|
value: new InjectorImpl(this)
|
|
959
1036
|
});
|
|
960
1037
|
this._rootNode = this._buildInjectionTree();
|
|
961
|
-
this._rootNode.
|
|
1038
|
+
this._rootNode.build();
|
|
962
1039
|
this._bootstrapped = true;
|
|
963
1040
|
const end = performance.now();
|
|
964
1041
|
const duration = end - start;
|
|
@@ -1028,6 +1105,7 @@ var NodeContainer = class extends Illuma {
|
|
|
1028
1105
|
}
|
|
1029
1106
|
};
|
|
1030
1107
|
export {
|
|
1108
|
+
ERR_CODES as ILLUMA_ERR_CODES,
|
|
1031
1109
|
INJECTION_SYMBOL,
|
|
1032
1110
|
InjectionContext,
|
|
1033
1111
|
InjectionError,
|
|
@@ -1041,6 +1119,7 @@ export {
|
|
|
1041
1119
|
extractToken,
|
|
1042
1120
|
getInjectableToken,
|
|
1043
1121
|
injectAsync,
|
|
1122
|
+
injectDefer,
|
|
1044
1123
|
injectEntryAsync,
|
|
1045
1124
|
injectGroupAsync,
|
|
1046
1125
|
isConstructor,
|