@illuma/core 1.0.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 +3 -35
- package/README.md +6 -0
- package/dist/index.cjs +109 -21
- 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 +107 -21
- 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 +70 -21
- 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 +70 -21
- 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 +1 -1
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 {
|
|
@@ -292,6 +319,13 @@ var InjectionContext = class _InjectionContext {
|
|
|
292
319
|
}
|
|
293
320
|
};
|
|
294
321
|
|
|
322
|
+
// src/lib/api/proxy.ts
|
|
323
|
+
var SHAPE_SHIFTER = new Proxy(() => {
|
|
324
|
+
}, {
|
|
325
|
+
get: /* @__PURE__ */ __name(() => SHAPE_SHIFTER, "get"),
|
|
326
|
+
apply: /* @__PURE__ */ __name(() => SHAPE_SHIFTER, "apply")
|
|
327
|
+
});
|
|
328
|
+
|
|
295
329
|
// src/lib/api/injection.ts
|
|
296
330
|
function nodeInject(provider, options) {
|
|
297
331
|
let token = provider;
|
|
@@ -308,7 +342,7 @@ function nodeInject(provider, options) {
|
|
|
308
342
|
if (InjectionContext.injector) {
|
|
309
343
|
return InjectionContext.injector(token, options?.optional);
|
|
310
344
|
}
|
|
311
|
-
return
|
|
345
|
+
return SHAPE_SHIFTER;
|
|
312
346
|
}
|
|
313
347
|
__name(nodeInject, "nodeInject");
|
|
314
348
|
|
|
@@ -428,23 +462,29 @@ var TreeRootNode = class {
|
|
|
428
462
|
static {
|
|
429
463
|
__name(this, "TreeRootNode");
|
|
430
464
|
}
|
|
465
|
+
instant;
|
|
431
466
|
_deps = /* @__PURE__ */ new Set();
|
|
432
467
|
_treePool = /* @__PURE__ */ new Map();
|
|
468
|
+
constructor(instant = true) {
|
|
469
|
+
this.instant = instant;
|
|
470
|
+
}
|
|
433
471
|
get dependencies() {
|
|
434
472
|
return this._deps;
|
|
435
473
|
}
|
|
436
474
|
addDependency(node) {
|
|
437
475
|
this._deps.add(node);
|
|
438
476
|
}
|
|
439
|
-
|
|
477
|
+
build() {
|
|
440
478
|
for (const dep of this._deps) {
|
|
441
|
-
dep.instantiate(this._treePool);
|
|
442
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);
|
|
443
482
|
}
|
|
444
483
|
}
|
|
445
484
|
find(token) {
|
|
446
485
|
const node = this._treePool.get(token);
|
|
447
486
|
if (!node) return null;
|
|
487
|
+
if (!this.instant) node.instantiate(this._treePool);
|
|
448
488
|
return node;
|
|
449
489
|
}
|
|
450
490
|
toString() {
|
|
@@ -475,6 +515,11 @@ var TreeNodeSingle = class {
|
|
|
475
515
|
else this._deps.set(node.proto.token, node);
|
|
476
516
|
node.allocations++;
|
|
477
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
|
+
}
|
|
478
523
|
instantiate(pool) {
|
|
479
524
|
if (this._resolved) return;
|
|
480
525
|
for (const node of this._deps.values()) node.instantiate(pool);
|
|
@@ -512,6 +557,10 @@ var TreeNodeTransparent = class _TreeNodeTransparent {
|
|
|
512
557
|
else this._deps.set(node.proto.token, node);
|
|
513
558
|
node.allocations++;
|
|
514
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
|
+
}
|
|
515
564
|
instantiate(pool) {
|
|
516
565
|
if (this._resolved) return;
|
|
517
566
|
for (const dep of this._transparent) dep.instantiate(pool);
|
|
@@ -536,6 +585,10 @@ var TreeNodeMulti = class _TreeNodeMulti {
|
|
|
536
585
|
constructor(proto) {
|
|
537
586
|
this.proto = proto;
|
|
538
587
|
}
|
|
588
|
+
collectPool(pool) {
|
|
589
|
+
for (const dep of this._deps) dep.collectPool(pool);
|
|
590
|
+
pool.set(this.proto.token, this);
|
|
591
|
+
}
|
|
539
592
|
instantiate(pool) {
|
|
540
593
|
if (this._resolved) return;
|
|
541
594
|
for (const dep of this._deps) {
|
|
@@ -712,6 +765,37 @@ var InjectorImpl = class {
|
|
|
712
765
|
};
|
|
713
766
|
var Injector = new NodeToken("Injector");
|
|
714
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
|
+
|
|
715
799
|
// src/lib/utils/inheritance.ts
|
|
716
800
|
function injectGroupAsync(fn, opts) {
|
|
717
801
|
const { container: parent } = nodeInject(Injector);
|
|
@@ -906,7 +990,7 @@ var NodeContainer = class extends Illuma {
|
|
|
906
990
|
return parentNode.findNode(token);
|
|
907
991
|
}
|
|
908
992
|
_buildInjectionTree() {
|
|
909
|
-
const root = new TreeRootNode();
|
|
993
|
+
const root = new TreeRootNode(this._opts?.instant);
|
|
910
994
|
const cache = /* @__PURE__ */ new Map();
|
|
911
995
|
const nodes = [
|
|
912
996
|
...this._protoNodes.values(),
|
|
@@ -951,7 +1035,7 @@ var NodeContainer = class extends Illuma {
|
|
|
951
1035
|
value: new InjectorImpl(this)
|
|
952
1036
|
});
|
|
953
1037
|
this._rootNode = this._buildInjectionTree();
|
|
954
|
-
this._rootNode.
|
|
1038
|
+
this._rootNode.build();
|
|
955
1039
|
this._bootstrapped = true;
|
|
956
1040
|
const end = performance.now();
|
|
957
1041
|
const duration = end - start;
|
|
@@ -1021,6 +1105,7 @@ var NodeContainer = class extends Illuma {
|
|
|
1021
1105
|
}
|
|
1022
1106
|
};
|
|
1023
1107
|
export {
|
|
1108
|
+
ERR_CODES as ILLUMA_ERR_CODES,
|
|
1024
1109
|
INJECTION_SYMBOL,
|
|
1025
1110
|
InjectionContext,
|
|
1026
1111
|
InjectionError,
|
|
@@ -1034,6 +1119,7 @@ export {
|
|
|
1034
1119
|
extractToken,
|
|
1035
1120
|
getInjectableToken,
|
|
1036
1121
|
injectAsync,
|
|
1122
|
+
injectDefer,
|
|
1037
1123
|
injectEntryAsync,
|
|
1038
1124
|
injectGroupAsync,
|
|
1039
1125
|
isConstructor,
|