react-obsidian 2.11.3 → 2.12.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.
Files changed (75) hide show
  1. package/dist/src/Obsidian.d.ts +4 -3
  2. package/dist/src/Obsidian.d.ts.map +1 -1
  3. package/dist/src/Obsidian.js +7 -4
  4. package/dist/src/Obsidian.js.map +1 -1
  5. package/dist/src/decorators/inject/Injectable.d.ts +1 -1
  6. package/dist/src/decorators/inject/Injectable.d.ts.map +1 -1
  7. package/dist/src/decorators/inject/Injectable.js +2 -2
  8. package/dist/src/decorators/inject/Injectable.js.map +1 -1
  9. package/dist/src/graph/ObjectGraph.d.ts.map +1 -1
  10. package/dist/src/graph/ObjectGraph.js +6 -16
  11. package/dist/src/graph/ObjectGraph.js.map +1 -1
  12. package/dist/src/graph/ServiceLocatorFactory.d.ts +1 -1
  13. package/dist/src/graph/ServiceLocatorFactory.d.ts.map +1 -1
  14. package/dist/src/graph/ServiceLocatorFactory.js +2 -2
  15. package/dist/src/graph/ServiceLocatorFactory.js.map +1 -1
  16. package/dist/src/graph/registry/GraphRegistry.d.ts +7 -2
  17. package/dist/src/graph/registry/GraphRegistry.d.ts.map +1 -1
  18. package/dist/src/graph/registry/GraphRegistry.js +38 -2
  19. package/dist/src/graph/registry/GraphRegistry.js.map +1 -1
  20. package/dist/src/injectors/class/ClassInjector.d.ts +1 -1
  21. package/dist/src/injectors/class/ClassInjector.d.ts.map +1 -1
  22. package/dist/src/injectors/class/ClassInjector.js +4 -4
  23. package/dist/src/injectors/class/ClassInjector.js.map +1 -1
  24. package/dist/src/injectors/class/LateInjector.d.ts +2 -1
  25. package/dist/src/injectors/class/LateInjector.d.ts.map +1 -1
  26. package/dist/src/injectors/class/LateInjector.js +13 -4
  27. package/dist/src/injectors/class/LateInjector.js.map +1 -1
  28. package/dist/src/injectors/components/ComponentInjector.d.ts +1 -1
  29. package/dist/src/injectors/components/ComponentInjector.d.ts.map +1 -1
  30. package/dist/src/injectors/components/ComponentInjector.js +5 -5
  31. package/dist/src/injectors/components/ComponentInjector.js.map +1 -1
  32. package/dist/src/injectors/components/InjectComponent.d.ts +1 -1
  33. package/dist/src/injectors/components/InjectComponent.d.ts.map +1 -1
  34. package/dist/src/injectors/components/InjectComponent.js +6 -5
  35. package/dist/src/injectors/components/InjectComponent.js.map +1 -1
  36. package/dist/src/injectors/components/useGraph.d.ts +1 -1
  37. package/dist/src/injectors/components/useGraph.d.ts.map +1 -1
  38. package/dist/src/injectors/components/useGraph.js +2 -2
  39. package/dist/src/injectors/components/useGraph.js.map +1 -1
  40. package/dist/src/injectors/components/useInjectionToken.d.ts +1 -1
  41. package/dist/src/injectors/components/useInjectionToken.d.ts.map +1 -1
  42. package/dist/src/injectors/components/useInjectionToken.js +6 -2
  43. package/dist/src/injectors/components/useInjectionToken.js.map +1 -1
  44. package/dist/src/injectors/hooks/HookInjector.d.ts +1 -1
  45. package/dist/src/injectors/hooks/HookInjector.d.ts.map +1 -1
  46. package/dist/src/injectors/hooks/HookInjector.js +2 -2
  47. package/dist/src/injectors/hooks/HookInjector.js.map +1 -1
  48. package/dist/src/injectors/hooks/InjectHook.d.ts +2 -2
  49. package/dist/src/injectors/hooks/InjectHook.d.ts.map +1 -1
  50. package/dist/src/injectors/hooks/InjectHook.js +4 -4
  51. package/dist/src/injectors/hooks/InjectHook.js.map +1 -1
  52. package/dist/src/utils/isString.d.ts +2 -0
  53. package/dist/src/utils/isString.d.ts.map +1 -0
  54. package/dist/src/utils/isString.js +8 -0
  55. package/dist/src/utils/isString.js.map +1 -0
  56. package/package.json +2 -2
  57. package/src/Obsidian.ts +10 -6
  58. package/src/decorators/inject/Injectable.ts +2 -2
  59. package/src/graph/ObjectGraph.ts +6 -3
  60. package/src/graph/ServiceLocatorFactory.ts +2 -2
  61. package/src/graph/registry/GraphRegistry.ts +39 -3
  62. package/src/injectors/class/ClassInjector.ts +4 -4
  63. package/src/injectors/class/LateInjector.ts +10 -3
  64. package/src/injectors/components/ComponentInjector.tsx +5 -5
  65. package/src/injectors/components/InjectComponent.ts +6 -5
  66. package/src/injectors/components/useGraph.ts +2 -2
  67. package/src/injectors/components/useInjectionToken.ts +5 -2
  68. package/src/injectors/hooks/HookInjector.ts +2 -2
  69. package/src/injectors/hooks/InjectHook.ts +4 -4
  70. package/src/utils/isString.ts +3 -0
  71. package/dist/src/decorators/Memoize.d.ts +0 -3
  72. package/dist/src/decorators/Memoize.d.ts.map +0 -1
  73. package/dist/src/decorators/Memoize.js +0 -21
  74. package/dist/src/decorators/Memoize.js.map +0 -1
  75. package/src/decorators/Memoize.ts +0 -18
@@ -4,9 +4,13 @@ exports.useInjectionToken = void 0;
4
4
  const react_1 = require("react");
5
5
  const graphContext_1 = require("./graphContext");
6
6
  const uniqueId_1 = require("../../utils/uniqueId");
7
- const useInjectionToken = (Graph) => {
7
+ const isString_1 = require("../../utils/isString");
8
+ const useInjectionToken = (keyOrGraph) => {
8
9
  const ctx = (0, react_1.useContext)(graphContext_1.GraphContext);
9
- const [injectionToken] = (0, react_1.useState)(() => { var _a; return (_a = ctx === null || ctx === void 0 ? void 0 : ctx.injectionToken) !== null && _a !== void 0 ? _a : (0, uniqueId_1.uniqueId)(Graph.name); });
10
+ const [injectionToken] = (0, react_1.useState)(() => {
11
+ var _a;
12
+ return (_a = ctx === null || ctx === void 0 ? void 0 : ctx.injectionToken) !== null && _a !== void 0 ? _a : (0, uniqueId_1.uniqueId)((0, isString_1.isString)(keyOrGraph) ? keyOrGraph : keyOrGraph.name);
13
+ });
10
14
  return injectionToken;
11
15
  };
12
16
  exports.useInjectionToken = useInjectionToken;
@@ -1 +1 @@
1
- {"version":3,"file":"useInjectionToken.js","sourceRoot":"","sources":["../../../../src/injectors/components/useInjectionToken.ts"],"names":[],"mappings":";;;AAAA,iCAA6C;AAC7C,iDAA8C;AAE9C,mDAAgD;AAEzC,MAAM,iBAAiB,GAAG,CAAC,KAAiC,EAAE,EAAE;IACrE,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,2BAAY,CAAC,CAAC;IACrC,MAAM,CAAC,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE,WAAC,OAAA,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,cAAc,mCAAI,IAAA,mBAAQ,EAAC,KAAK,CAAC,IAAI,CAAC,CAAA,EAAA,CAAC,CAAC;IACrF,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAJW,QAAA,iBAAiB,qBAI5B"}
1
+ {"version":3,"file":"useInjectionToken.js","sourceRoot":"","sources":["../../../../src/injectors/components/useInjectionToken.ts"],"names":[],"mappings":";;;AAAA,iCAA6C;AAC7C,iDAA8C;AAE9C,mDAAgD;AAChD,mDAAgD;AAEzC,MAAM,iBAAiB,GAAG,CAAC,UAA+C,EAAE,EAAE;IACnF,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,2BAAY,CAAC,CAAC;IACrC,MAAM,CAAC,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE;;QACrC,OAAO,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,cAAc,mCAAI,IAAA,mBAAQ,EAAC,IAAA,mBAAQ,EAAC,UAAU,CAAC,CAAA,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IACH,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AANW,QAAA,iBAAiB,qBAM5B"}
@@ -1,6 +1,6 @@
1
1
  import { ObjectGraph } from '../../graph/ObjectGraph';
2
2
  import { Constructable } from '../../types';
3
3
  export default class HookInjector {
4
- inject<Args, Result>(hook: (args: Args) => Result, Graph: Constructable<ObjectGraph>): (args?: Partial<Args>) => Result;
4
+ inject<Args, Result>(hook: (args: Args) => Result, keyOrGraph: string | Constructable<ObjectGraph>): (args?: Partial<Args>) => Result;
5
5
  }
6
6
  //# sourceMappingURL=HookInjector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HookInjector.d.ts","sourceRoot":"","sources":["../../../../src/injectors/hooks/HookInjector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,MAAM,CAAC,IAAI,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,EAC5B,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM;CAMpC"}
1
+ {"version":3,"file":"HookInjector.d.ts","sourceRoot":"","sources":["../../../../src/injectors/hooks/HookInjector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,MAAM,CAAC,IAAI,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,EAC5B,UAAU,EAAE,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,GAC9C,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM;CAMpC"}
@@ -5,9 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const useGraph_1 = __importDefault(require("../components/useGraph"));
7
7
  class HookInjector {
8
- inject(hook, Graph) {
8
+ inject(hook, keyOrGraph) {
9
9
  return (args) => {
10
- const graph = (0, useGraph_1.default)(Graph, hook, args);
10
+ const graph = (0, useGraph_1.default)(keyOrGraph, hook, args);
11
11
  return hook(new Proxy(args !== null && args !== void 0 ? args : {}, new Injector(graph)));
12
12
  };
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HookInjector.js","sourceRoot":"","sources":["../../../../src/injectors/hooks/HookInjector.ts"],"names":[],"mappings":";;;;;AAEA,sEAA8C;AAG9C,MAAqB,YAAY;IAC/B,MAAM,CACJ,IAA4B,EAC5B,KAAiC;QAEjC,OAAO,CAAC,IAAoB,EAAU,EAAE;YACtC,MAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC;CACF;AAVD,+BAUC;AAED,MAAM,QAAQ;IACZ,YAAoB,KAAY;QAAZ,UAAK,GAAL,KAAK,CAAO;IAAG,CAAC;IAEpC,GAAG,CAAC,GAAQ,EAAE,QAAgB,EAAE,QAAa;QAC3C,OAAO,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnF,CAAC;CACF"}
1
+ {"version":3,"file":"HookInjector.js","sourceRoot":"","sources":["../../../../src/injectors/hooks/HookInjector.ts"],"names":[],"mappings":";;;;;AAEA,sEAA8C;AAG9C,MAAqB,YAAY;IAC/B,MAAM,CACJ,IAA4B,EAC5B,UAA+C;QAE/C,OAAO,CAAC,IAAoB,EAAU,EAAE;YACtC,MAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC;CACF;AAVD,+BAUC;AAED,MAAM,QAAQ;IACZ,YAAoB,KAAY;QAAZ,UAAK,GAAL,KAAK,CAAO;IAAG,CAAC;IAEpC,GAAG,CAAC,GAAQ,EAAE,QAAgB,EAAE,QAAa;QAC3C,OAAO,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnF,CAAC;CACF"}
@@ -1,5 +1,5 @@
1
1
  import { ObjectGraph } from '../../graph/ObjectGraph';
2
2
  import { Constructable } from '../../types';
3
- export declare function injectHookWithArguments<Injected, Own, Result = {}>(hook: (args: Injected & Own) => Result, Graph: Constructable<ObjectGraph>): (props: Own & Partial<Injected>) => Result;
4
- export declare function injectHook<Injected, Result = {}>(hook: (args: Injected) => Result, Graph: Constructable<ObjectGraph>): (props?: Partial<Injected>) => Result;
3
+ export declare function injectHookWithArguments<Injected, Own, Result = {}>(hook: (args: Injected & Own) => Result, keyOrGraph: string | Constructable<ObjectGraph>): (props: Own & Partial<Injected>) => Result;
4
+ export declare function injectHook<Injected, Result = {}>(hook: (args: Injected) => Result, keyOrGraph: string | Constructable<ObjectGraph>): (props?: Partial<Injected>) => Result;
5
5
  //# sourceMappingURL=InjectHook.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InjectHook.d.ts","sourceRoot":"","sources":["../../../../src/injectors/hooks/InjectHook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU5C,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,EAChE,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,KAAK,MAAM,EACtC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM,CAE5C;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,EAC9C,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,EAChC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM,CAEvC"}
1
+ {"version":3,"file":"InjectHook.d.ts","sourceRoot":"","sources":["../../../../src/injectors/hooks/InjectHook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU5C,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,EAChE,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,KAAK,MAAM,EACtC,UAAU,EAAE,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,GAC9C,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM,CAE5C;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,EAC9C,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,EAChC,UAAU,EAAE,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,GAC9C,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM,CAEvC"}
@@ -10,12 +10,12 @@ const hookInjector = new HookInjector_1.default();
10
10
  // As a workaround, we provide two injection functions with an almost identical signature.
11
11
  // 1. injectHookWithArguments: Should be used when a hook requires parameters in addition to the injected dependencies.
12
12
  // 2. injectHook: Should be used when a hook does not require parameters.
13
- function injectHookWithArguments(hook, Graph) {
14
- return hookInjector.inject(hook, Graph);
13
+ function injectHookWithArguments(hook, keyOrGraph) {
14
+ return hookInjector.inject(hook, keyOrGraph);
15
15
  }
16
16
  exports.injectHookWithArguments = injectHookWithArguments;
17
- function injectHook(hook, Graph) {
18
- return hookInjector.inject(hook, Graph);
17
+ function injectHook(hook, keyOrGraph) {
18
+ return hookInjector.inject(hook, keyOrGraph);
19
19
  }
20
20
  exports.injectHook = injectHook;
21
21
  //# sourceMappingURL=InjectHook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InjectHook.js","sourceRoot":"","sources":["../../../../src/injectors/hooks/InjectHook.ts"],"names":[],"mappings":";;;;;;AAGA,kEAA0C;AAE1C,MAAM,YAAY,GAAG,IAAI,sBAAY,EAAE,CAAC;AAExC,6HAA6H;AAC7H,0FAA0F;AAC1F,uHAAuH;AACvH,yEAAyE;AAEzE,SAAgB,uBAAuB,CACrC,IAAsC,EACtC,KAAiC;IAEjC,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAA+C,CAAC;AACxF,CAAC;AALD,0DAKC;AAED,SAAgB,UAAU,CACxB,IAAgC,EAChC,KAAiC;IAEjC,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AALD,gCAKC"}
1
+ {"version":3,"file":"InjectHook.js","sourceRoot":"","sources":["../../../../src/injectors/hooks/InjectHook.ts"],"names":[],"mappings":";;;;;;AAGA,kEAA0C;AAE1C,MAAM,YAAY,GAAG,IAAI,sBAAY,EAAE,CAAC;AAExC,6HAA6H;AAC7H,0FAA0F;AAC1F,uHAAuH;AACvH,yEAAyE;AAEzE,SAAgB,uBAAuB,CACrC,IAAsC,EACtC,UAA+C;IAE/C,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAA+C,CAAC;AAC7F,CAAC;AALD,0DAKC;AAED,SAAgB,UAAU,CACxB,IAAgC,EAChC,UAA+C;IAE/C,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC/C,CAAC;AALD,gCAKC"}
@@ -0,0 +1,2 @@
1
+ export declare function isString(value: any): value is string;
2
+ //# sourceMappingURL=isString.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isString.d.ts","sourceRoot":"","sources":["../../../src/utils/isString.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,MAAM,CAEpD"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isString = void 0;
4
+ function isString(value) {
5
+ return typeof value === 'string';
6
+ }
7
+ exports.isString = isString;
8
+ //# sourceMappingURL=isString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isString.js","sourceRoot":"","sources":["../../../src/utils/isString.ts"],"names":[],"mappings":";;;AAAA,SAAgB,QAAQ,CAAC,KAAU;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACnC,CAAC;AAFD,4BAEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-obsidian",
3
- "version": "2.11.3",
3
+ "version": "2.12.0",
4
4
  "description": "Dependency injection framework for React and React Native applications",
5
5
  "scripts": {
6
6
  "prepack": "npm run lint && tsc --project tsconfig.prod.json",
@@ -47,7 +47,7 @@
47
47
  "eslint-plugin-import": "^2.25.2",
48
48
  "eslint-plugin-import-newlines": "^1.1.5",
49
49
  "eslint-plugin-jest-formatting": "^3.1.0",
50
- "eslint-plugin-obsidian": "2.11.3",
50
+ "eslint-plugin-obsidian": "2.12.0",
51
51
  "eslint-plugin-react": "^7.26.1",
52
52
  "eslint-plugin-react-hooks": "^4.2.0",
53
53
  "eslint-plugin-unused-imports": "3.1.x",
package/src/Obsidian.ts CHANGED
@@ -1,20 +1,24 @@
1
1
  import graphRegistry from './graph/registry/GraphRegistry';
2
2
  import { ObjectGraph } from './graph/ObjectGraph';
3
- import { GraphInternals, ServiceLocator } from './types';
3
+ import { GraphInternals, ServiceLocator, type Constructable } from './types';
4
4
  import { GraphMiddleware } from './graph/registry/GraphMiddleware';
5
5
  import lateInjector from './injectors/class/LateInjector';
6
6
  import serviceLocatorFactory from './graph/ServiceLocatorFactory';
7
7
 
8
8
  export default class Obsidian {
9
- obtain<T extends ObjectGraph<P>, P>(
10
- Graph: new(...args: P[]) => T,
9
+ registerGraph(key: string, generator: () => Constructable<ObjectGraph>) {
10
+ graphRegistry.registerGraphGenerator(key, generator);
11
+ }
12
+
13
+ obtain<T extends ObjectGraph<P>, P = unknown>(
14
+ keyOrGraph: string | (new(...args: P[]) => T),
11
15
  props?: P,
12
16
  ): ServiceLocator<Omit<T, GraphInternals>> {
13
- return serviceLocatorFactory.fromGraph(Graph, props);
17
+ return serviceLocatorFactory.fromGraph(keyOrGraph, props);
14
18
  }
15
19
 
16
- inject<T extends object>(target: T, graph?: ObjectGraph) {
17
- return lateInjector.inject(target, graph);
20
+ inject<T extends object>(target: T, keyOrGraph?: string | ObjectGraph) {
21
+ return lateInjector.inject(target, keyOrGraph);
18
22
  }
19
23
 
20
24
  addGraphMiddleware(middleware: GraphMiddleware) {
@@ -3,6 +3,6 @@ import { Graph } from '../../graph/Graph';
3
3
  import graphRegistry from '../../graph/registry/GraphRegistry';
4
4
  import ClassInjector from '../../injectors/class/ClassInjector';
5
5
 
6
- export function Injectable(Graph: Constructable<Graph>): any {
7
- return new ClassInjector(graphRegistry).inject(Graph);
6
+ export function Injectable(keyOrGraph: string | Constructable<Graph>): any {
7
+ return new ClassInjector(graphRegistry).inject(keyOrGraph);
8
8
  }
@@ -1,5 +1,4 @@
1
1
  import { uniqueId } from '../utils/uniqueId';
2
- import Memoize from '../decorators/Memoize';
3
2
  import { bindProviders } from './ProviderBinder';
4
3
  import { Graph } from './Graph';
5
4
  import PropertyRetriever from './PropertyRetriever';
@@ -9,9 +8,13 @@ import { CircularDependenciesDetector } from './CircularDependenciesDetector';
9
8
  export abstract class ObjectGraph<T = unknown> implements Graph {
10
9
  private propertyRetriever = new PropertyRetriever(this);
11
10
 
12
- @Memoize()
13
11
  get name(): string {
14
- return uniqueId(this.constructor.name);
12
+ if (Reflect.hasMetadata('memoizedName', this)) {
13
+ return Reflect.getMetadata('memoizedName', this);
14
+ }
15
+ const name = uniqueId(this.constructor.name);
16
+ Reflect.defineMetadata('memoizedName', name, this);
17
+ return name;
15
18
  }
16
19
 
17
20
  constructor(protected _props?: T) {
@@ -3,8 +3,8 @@ import { Constructable, ServiceLocator as ServiceLocatorType } from '../types';
3
3
  import graphRegistry from './registry/GraphRegistry';
4
4
 
5
5
  export default class ServiceLocatorFactory {
6
- static fromGraph<T extends ObjectGraph<P>, P = any>(Graph: Constructable<T>, props?: P) {
7
- const resolved = graphRegistry.resolve(Graph, 'serviceLocator', props);
6
+ static fromGraph<T extends ObjectGraph<P>, P = any>(keyOrGraph: string | Constructable<T>, props?: P) {
7
+ const resolved = graphRegistry.resolve(keyOrGraph, 'serviceLocator', props);
8
8
  const wrapped = new Proxy(resolved, {
9
9
  get(_target: any, property: string, receiver: any) {
10
10
  return () => resolved.retrieve(property, receiver);
@@ -4,6 +4,7 @@ import { Middleware } from './Middleware';
4
4
  import GraphMiddlewareChain from './GraphMiddlewareChain';
5
5
  import { ObtainLifecycleBoundGraphException } from './ObtainLifecycleBoundGraphException';
6
6
  import { getGlobal } from '../../utils/getGlobal';
7
+ import { isString } from '../../utils/isString';
7
8
 
8
9
  export class GraphRegistry {
9
10
  private readonly constructorToInstance = new Map<Constructable<Graph>, Set<Graph>>();
@@ -13,12 +14,21 @@ export class GraphRegistry {
13
14
  private readonly nameToInstance = new Map<string, Graph>();
14
15
  private readonly graphToSubgraphs = new Map<Constructable<Graph>, Set<Constructable<Graph>>>();
15
16
  private readonly graphMiddlewares = new GraphMiddlewareChain();
17
+ private readonly keyToGenerator = new Map<string,() => Constructable<Graph>>();
18
+ private readonly keyToGraph = new Map<string, Constructable<Graph>>();
16
19
 
17
20
  register(constructor: Constructable<Graph>, subgraphs: Constructable<Graph>[] = []) {
18
21
  this.graphToSubgraphs.set(constructor, new Set(subgraphs));
19
22
  }
20
23
 
21
- ensureRegistered(graph: Graph) {
24
+ registerGraphGenerator(key: string, generator: () => Constructable<Graph>) {
25
+ if (this.keyToGenerator.has(key)) throw new Error(`Attempted to register a graph generator for key "${key}" that is already registered.`);
26
+ this.keyToGenerator.set(key, generator);
27
+ }
28
+
29
+ ensureRegistered(keyOrGraph: string | Graph) {
30
+ if (isString(keyOrGraph)) return;
31
+ const graph = keyOrGraph;
22
32
  if (this.instanceToConstructor.get(graph)) return;
23
33
  this.set(graph.constructor as any, graph);
24
34
  }
@@ -34,12 +44,15 @@ export class GraphRegistry {
34
44
  }
35
45
 
36
46
  resolve<T extends Graph>(
37
- Graph: Constructable<T>,
47
+ keyOrGraph: String | Constructable<T>,
38
48
  source: 'lifecycleOwner' | 'classInjection' | 'serviceLocator' = 'lifecycleOwner',
39
49
  props: any = undefined,
40
50
  injectionToken?: string,
41
51
  ): T {
42
- if ((this.isSingleton(Graph) || this.isBoundToReactLifecycle(Graph)) && this.has(Graph, injectionToken)) {
52
+ const Graph = isString(keyOrGraph) ?
53
+ this.getGraphConstructorByKey<T>(keyOrGraph) :
54
+ keyOrGraph as Constructable<T>;
55
+ if (( this.isSingleton(Graph) || this.isBoundToReactLifecycle(Graph)) && this.has(Graph, injectionToken)) {
43
56
  return this.isComponentScopedLifecycleBound(Graph) ?
44
57
  this.getByInjectionToken(Graph, injectionToken) :
45
58
  this.getFirst(Graph);
@@ -52,6 +65,15 @@ export class GraphRegistry {
52
65
  return graph as T;
53
66
  }
54
67
 
68
+ private getGraphConstructorByKey<T extends Graph>(key: string): Constructable<T> {
69
+ if (this.keyToGraph.has(key)) return this.keyToGraph.get(key) as Constructable<T>;
70
+ const generator = this.keyToGenerator.get(key);
71
+ if (!generator) throw new Error(`Attempted to resolve a graph by key "${key}" that is not registered. Did you forget to call Obsidian.registerGraph?`);
72
+ const constructor = generator();
73
+ this.keyToGraph.set(key, constructor);
74
+ return constructor as Constructable<T>;
75
+ }
76
+
55
77
  private has(Graph: Constructable<Graph>, injectionToken?: string): boolean {
56
78
  const instances = this.constructorToInstance.get(Graph);
57
79
  if (!instances) return false;
@@ -133,6 +155,18 @@ export class GraphRegistry {
133
155
  this.injectionTokenToInstance.delete(token);
134
156
  this.instanceToInjectionToken.delete(graph);
135
157
  }
158
+
159
+ this.clearGraphsRegisteredByKey(Graph);
160
+ }
161
+
162
+ private clearGraphsRegisteredByKey(Graph: Constructable<Graph>) {
163
+ [...this.keyToGraph.keys()]
164
+ .map((key) => [key, this.keyToGraph.get(key)!] as [string, Constructable<Graph>])
165
+ .filter(([_, $Graph]) => $Graph === Graph)
166
+ .forEach(([key, _]) => {
167
+ this.keyToGraph.delete(key);
168
+ this.keyToGenerator.delete(key);
169
+ });
136
170
  }
137
171
 
138
172
  addGraphMiddleware(middleware: Middleware<Graph>) {
@@ -149,6 +183,8 @@ export class GraphRegistry {
149
183
  this.nameToInstance.clear();
150
184
  this.injectionTokenToInstance.clear();
151
185
  this.instanceToInjectionToken.clear();
186
+ this.keyToGenerator.clear();
187
+ this.keyToGraph.clear();
152
188
  }
153
189
  }
154
190
 
@@ -11,14 +11,14 @@ export default class ClassInjector {
11
11
  private injectionMetadata: InjectionMetadata = new InjectionMetadata(),
12
12
  ) {}
13
13
 
14
- inject(Graph: Constructable<Graph>) {
14
+ inject(keyOrGraph: string | Constructable<Graph>) {
15
15
  return (Target: Constructable<any>) => {
16
- return new Proxy(Target, this.createProxyHandler(Graph, this.graphRegistry, this.injectionMetadata));
16
+ return new Proxy(Target, this.createProxyHandler(keyOrGraph, this.graphRegistry, this.injectionMetadata));
17
17
  };
18
18
  }
19
19
 
20
20
  private createProxyHandler(
21
- Graph: Constructable<Graph>,
21
+ keyOrGraph: string | Constructable<Graph>,
22
22
  graphRegistry: GraphRegistry,
23
23
  injectionMetadata: InjectionMetadata,
24
24
  ): ProxyHandler<any> {
@@ -26,7 +26,7 @@ export default class ClassInjector {
26
26
  construct(target: any, args: any[], newTarget: Function): any {
27
27
  const isReactClassComponent = target.prototype?.isReactComponent;
28
28
  const source = isReactClassComponent ? 'lifecycleOwner' : 'classInjection';
29
- const graph = graphRegistry.resolve(Graph, source, args.length > 0 ? args[0] : undefined);
29
+ const graph = graphRegistry.resolve(keyOrGraph, source, args.length > 0 ? args[0] : undefined);
30
30
  if (isReactClassComponent) {
31
31
  referenceCounter.retain(graph);
32
32
  }
@@ -1,3 +1,4 @@
1
+ import { isString } from 'lodash';
1
2
  import { ObjectGraph } from '../../graph/ObjectGraph';
2
3
  import graphRegistry from '../../graph/registry/GraphRegistry';
3
4
  import InjectionMetadata from './InjectionMetadata';
@@ -5,16 +6,22 @@ import InjectionMetadata from './InjectionMetadata';
5
6
  export const GRAPH_INSTANCE_NAME_KEY = 'GRAPH_INSTANCE_NAME';
6
7
 
7
8
  class LateInjector<T extends object> {
8
- inject(target: T, sourceGraph?: ObjectGraph): T {
9
- if (sourceGraph) graphRegistry.ensureRegistered(sourceGraph);
9
+ inject(target: T, keyOrGraph?: string | ObjectGraph): T {
10
+ if (keyOrGraph) graphRegistry.ensureRegistered(keyOrGraph);
10
11
  const injectionMetadata = new InjectionMetadata();
11
- const graph = sourceGraph ?? this.getGraphInstance(target);
12
+ const graph = this.getGraph(target, keyOrGraph);
12
13
  injectionMetadata.getLatePropertiesToInject(target.constructor).forEach((key) => {
13
14
  Reflect.set(target, key, graph.retrieve(key));
14
15
  });
15
16
  return target;
16
17
  }
17
18
 
19
+ private getGraph(target: T, keyOrGraph?: string | ObjectGraph) {
20
+ if (keyOrGraph instanceof ObjectGraph) return keyOrGraph;
21
+ if (isString(keyOrGraph)) return graphRegistry.resolve(keyOrGraph, 'classInjection');
22
+ return this.getGraphInstance(target);
23
+ }
24
+
18
25
  private getGraphInstance(target: T) {
19
26
  const graphInstanceName = Reflect.getMetadata(GRAPH_INSTANCE_NAME_KEY, target.constructor);
20
27
  return graphRegistry.getGraphInstance(graphInstanceName);
@@ -11,24 +11,24 @@ import { useInjectionToken } from './useInjectionToken';
11
11
  export default class ComponentInjector {
12
12
  inject<P>(
13
13
  Target: React.FunctionComponent<P>,
14
- Graph: Constructable<ObjectGraph>,
14
+ keyOrGraph: string | Constructable<ObjectGraph>,
15
15
  ): React.FunctionComponent<Partial<P>> {
16
- const Wrapped = this.wrapComponent(Target, Graph);
16
+ const Wrapped = this.wrapComponent(Target, keyOrGraph);
17
17
  hoistNonReactStatics(Wrapped, Target);
18
18
  return Wrapped;
19
19
  }
20
20
 
21
21
  private wrapComponent<P>(
22
22
  InjectionCandidate: React.FunctionComponent<P>,
23
- Graph: Constructable<ObjectGraph>,
23
+ keyOrGraph: string | Constructable<ObjectGraph>,
24
24
  ): React.FunctionComponent<Partial<P>> {
25
25
  const isMemoized = isMemoizedComponent(InjectionCandidate);
26
26
  const Target = isMemoized ? InjectionCandidate.type : InjectionCandidate;
27
27
  const compare = isMemoized ? InjectionCandidate.compare : undefined;
28
28
 
29
29
  return genericMemo((passedProps: P) => {
30
- const injectionToken = useInjectionToken(Graph);
31
- const graph = useGraph<P>(Graph, Target, passedProps, injectionToken);
30
+ const injectionToken = useInjectionToken(keyOrGraph);
31
+ const graph = useGraph<P>(keyOrGraph, Target, passedProps, injectionToken);
32
32
  const proxiedProps = new PropsInjector(graph).inject(passedProps);
33
33
 
34
34
  return (
@@ -1,5 +1,6 @@
1
1
  import { ObjectGraph } from '../../graph/ObjectGraph';
2
2
  import { Constructable } from '../../types';
3
+ import { isString } from '../../utils/isString';
3
4
  import ComponentInjector from './ComponentInjector';
4
5
 
5
6
  interface Discriminator {
@@ -13,18 +14,18 @@ export const injectComponent = <OwnProps = Discriminator, InjectedProps = Discri
13
14
  (OwnProps extends infer P ? OwnProps extends Discriminator ? P : OwnProps : never) &
14
15
  (InjectedProps extends Discriminator ? any : InjectedProps)
15
16
  >,
16
- Graph: Constructable<ObjectGraph>,
17
+ keyOrGraph: string | Constructable<ObjectGraph>,
17
18
  ) => {
18
- assertGraph(Graph, Target);
19
+ assertGraph(keyOrGraph, Target);
19
20
 
20
- return componentInjector.inject(Target, Graph) as React.FunctionComponent<
21
+ return componentInjector.inject(Target, keyOrGraph) as React.FunctionComponent<
21
22
  InjectedProps extends Discriminator ?
22
23
  OwnProps extends Discriminator ? Partial<OwnProps> : OwnProps :
23
24
  OwnProps extends InjectedProps ? Partial<OwnProps> : OwnProps & Partial<InjectedProps>
24
25
  >;
25
26
  };
26
- function assertGraph(Graph: Constructable<ObjectGraph<unknown>>, Target: any) {
27
- if (!Graph) {
27
+ function assertGraph(keyOrGraph: string | Constructable<ObjectGraph>, Target: any) {
28
+ if (!isString(keyOrGraph) && !keyOrGraph) {
28
29
  throw new Error(
29
30
  `injectComponent was called with an undefined Graph.`
30
31
  + `This is probably not an issue with Obsidian.`
@@ -5,14 +5,14 @@ import graphRegistry from '../../graph/registry/GraphRegistry';
5
5
  import referenceCounter from '../../ReferenceCounter';
6
6
 
7
7
  export default <P>(
8
- Graph: Constructable<ObjectGraph>,
8
+ keyOrGraph: string | Constructable<ObjectGraph>,
9
9
  target: any,
10
10
  props?: Partial<P>,
11
11
  injectionToken?: string,
12
12
  ) => {
13
13
 
14
14
  const [graph] = useState(() => {
15
- const resolvedGraph = graphRegistry.resolve(Graph, 'lifecycleOwner', props, injectionToken);
15
+ const resolvedGraph = graphRegistry.resolve(keyOrGraph, 'lifecycleOwner', props, injectionToken);
16
16
  resolvedGraph.onBind(target);
17
17
  return resolvedGraph;
18
18
  });
@@ -2,9 +2,12 @@ import { useContext, useState } from 'react';
2
2
  import { GraphContext } from './graphContext';
3
3
  import type { Constructable, ObjectGraph } from '../..';
4
4
  import { uniqueId } from '../../utils/uniqueId';
5
+ import { isString } from '../../utils/isString';
5
6
 
6
- export const useInjectionToken = (Graph: Constructable<ObjectGraph>) => {
7
+ export const useInjectionToken = (keyOrGraph: string | Constructable<ObjectGraph>) => {
7
8
  const ctx = useContext(GraphContext);
8
- const [injectionToken] = useState(() => ctx?.injectionToken ?? uniqueId(Graph.name));
9
+ const [injectionToken] = useState(() => {
10
+ return ctx?.injectionToken ?? uniqueId(isString(keyOrGraph)? keyOrGraph : keyOrGraph.name);
11
+ });
9
12
  return injectionToken;
10
13
  };
@@ -6,10 +6,10 @@ import { Constructable } from '../../types';
6
6
  export default class HookInjector {
7
7
  inject<Args, Result>(
8
8
  hook: (args: Args) => Result,
9
- Graph: Constructable<ObjectGraph>,
9
+ keyOrGraph: string | Constructable<ObjectGraph>,
10
10
  ): (args?: Partial<Args>) => Result {
11
11
  return (args?: Partial<Args>): Result => {
12
- const graph = useGraph(Graph, hook, args);
12
+ const graph = useGraph(keyOrGraph, hook, args);
13
13
  return hook(new Proxy(args ?? {}, new Injector(graph)));
14
14
  };
15
15
  }
@@ -12,14 +12,14 @@ const hookInjector = new HookInjector();
12
12
 
13
13
  export function injectHookWithArguments<Injected, Own, Result = {}>(
14
14
  hook: (args: Injected & Own) => Result,
15
- Graph: Constructable<ObjectGraph>,
15
+ keyOrGraph: string | Constructable<ObjectGraph>,
16
16
  ): (props: Own & Partial<Injected>) => Result {
17
- return hookInjector.inject(hook, Graph) as (props: Own & Partial<Injected>) => Result;
17
+ return hookInjector.inject(hook, keyOrGraph) as (props: Own & Partial<Injected>) => Result;
18
18
  }
19
19
 
20
20
  export function injectHook<Injected, Result = {}>(
21
21
  hook: (args: Injected) => Result,
22
- Graph: Constructable<ObjectGraph>,
22
+ keyOrGraph: string | Constructable<ObjectGraph>,
23
23
  ): (props?: Partial<Injected>) => Result {
24
- return hookInjector.inject(hook, Graph);
24
+ return hookInjector.inject(hook, keyOrGraph);
25
25
  }
@@ -0,0 +1,3 @@
1
+ export function isString(value: any): value is string {
2
+ return typeof value === 'string';
3
+ }
@@ -1,3 +0,0 @@
1
- import 'reflect-metadata';
2
- export default function Memoize(): (_Clazz: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
3
- //# sourceMappingURL=Memoize.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Memoize.d.ts","sourceRoot":"","sources":["../../../src/decorators/Memoize.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,CAAC;AAE1B,MAAM,CAAC,OAAO,UAAU,OAAO,aACG,GAAG,eAAe,MAAM,cAAc,kBAAkB,wBAazF"}
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- /* eslint-disable no-param-reassign */
4
- require("reflect-metadata");
5
- function Memoize() {
6
- return function provide(_Clazz, propertyKey, descriptor) {
7
- const originalGet = descriptor.get;
8
- descriptor.get = function get() {
9
- const key = `memoized${propertyKey}`;
10
- if (Reflect.hasMetadata(key, this)) {
11
- return Reflect.getMetadata(key, this);
12
- }
13
- const value = originalGet.call(this);
14
- Reflect.defineMetadata(key, value, this);
15
- return value;
16
- };
17
- return descriptor;
18
- };
19
- }
20
- exports.default = Memoize;
21
- //# sourceMappingURL=Memoize.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Memoize.js","sourceRoot":"","sources":["../../../src/decorators/Memoize.ts"],"names":[],"mappings":";;AAAA,sCAAsC;AACtC,4BAA0B;AAE1B,SAAwB,OAAO;IAC7B,OAAO,SAAS,OAAO,CAAC,MAAW,EAAE,WAAmB,EAAE,UAA8B;QACtF,MAAM,WAAW,GAAG,UAAU,CAAC,GAAI,CAAC;QACpC,UAAU,CAAC,GAAG,GAAG,SAAS,GAAG;YAC3B,MAAM,GAAG,GAAG,WAAW,WAAW,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;gBAClC,OAAO,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;aACvC;YACD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAdD,0BAcC"}
@@ -1,18 +0,0 @@
1
- /* eslint-disable no-param-reassign */
2
- import 'reflect-metadata';
3
-
4
- export default function Memoize() {
5
- return function provide(_Clazz: any, propertyKey: string, descriptor: PropertyDescriptor) {
6
- const originalGet = descriptor.get!;
7
- descriptor.get = function get() {
8
- const key = `memoized${propertyKey}`;
9
- if (Reflect.hasMetadata(key, this)) {
10
- return Reflect.getMetadata(key, this);
11
- }
12
- const value = originalGet.call(this);
13
- Reflect.defineMetadata(key, value, this);
14
- return value;
15
- };
16
- return descriptor;
17
- };
18
- }