@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/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(100, `Duplicate provider for token "${token.toString()}" detected.`);
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(101, `Tried to re-provide factory for token "${token.toString()}" detected.`);
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(102, `Cannot use constructor for token "${ctor.name}". Please make sure to use @nodeInjectable() decorator`);
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(103, `Cannot use provider as it is neither a NodeToken nor MultiNodeToken nor a valid constructor.:
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(200, `Invalid alias target "${aliasStr}". Alias must be a NodeToken, MultiNodeToken, or a class decorated with @NodeInjectable().`);
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(201, `Token "${alias.toString()}" cannot alias itself in a loop.`);
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(300, "Cannot retrieve providers before the container has been bootstrapped.");
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(301, "Cannot modify providers after the container has been bootstrapped.");
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(302, "Container has already been bootstrapped and cannot be bootstrapped again.");
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(400, `No provider found for "${token.toString()}".`);
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(401, `Circular dependency detected while resolving "${providerStr}":
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(500, `Cannot instantiate ${parentStr} because it depends on untracked injection ${tokenStr}. Please make sure all injections are properly tracked.`);
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(501, `Cannot inject "${tokenStr}" outside of an injection context.`);
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(502, "Cannot call injection utilities outside of an injection context.");
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(503, `Failed to access instance for token "${token.toString()}". It was not properly instantiated.`);
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(504, "Failed to access the requested instance due to an unknown error.");
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 injection;
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
- instantiate() {
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.instantiate();
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,