react-obsidian 0.0.23 → 0.0.26

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 CHANGED
@@ -11,7 +11,7 @@
11
11
  <br>⚠️ <b>Until we hit v1, Obsidian is not semver-compliant and all APIs are subject to change.</b></h5>
12
12
 
13
13
  ## Introduction
14
-
14
+ useButtonClick
15
15
  React Obsidian is a dependency injection framework for React and React Native applications. It allows you to inject dependencies effortlessly into hooks, components or classes. Separating the construction and consumption of dependencies is crucial to maintaining a readable and testable codebase.
16
16
 
17
17
  React Obsidian is guided by the principles of the Dependency Injection pattern, but does not strictly follow them. We allowed ourselves a degree of freedom when designing the library in order to reduce boilerplate code and library footprint.
@@ -32,8 +32,10 @@ React Obsidian is guided by the principles of the Dependency Injection pattern,
32
32
  * [Advance usage](https://github.com/wix-incubator/react-obsidian#advance-usage)
33
33
  * [Accessing props in graphs](https://github.com/wix-incubator/react-obsidian#accessing-props-in-graphs)
34
34
  * [Singleton graphs and providers](https://github.com/wix-incubator/react-obsidian#singleton-graphs-and-providers)
35
+ * [Lazy property injection](https://github.com/wix-incubator/react-obsidian#lazy-property-injection)
36
+ * [Typing graphs](https://github.com/wix-incubator/react-obsidian#typing-graphs)
35
37
  * [Graph middleware](https://github.com/wix-incubator/react-obsidian#graph-middleware)
36
- * [Clear graphs](https://github.com/wix-incubator/react-obsidian#clear-graphs)
38
+ * [Clearing graphs](https://github.com/wix-incubator/react-obsidian#clearing-graphs)
37
39
 
38
40
 
39
41
 
@@ -113,7 +115,7 @@ const useButtonClick = ({ biLogger }: UseButtonPressProps): UseButtonPress => {
113
115
  };
114
116
 
115
117
  // Dependencies are injected from ApplicationGraph
116
- export default injectHook(usePress, ApplicationGraph);
118
+ export default injectHook(useButtonClick, ApplicationGraph);
117
119
 
118
120
  // Now that we exported the injected hook, we can use it in a component without the needed so provide its dependencies manually
119
121
  const Component = () => (
@@ -222,6 +224,63 @@ class ApplicationGraph {
222
224
  }
223
225
  ```
224
226
 
227
+ ### Lazy property injection
228
+ Class properties can be injected lazily by using the `@LazyInject()` decorator. This is useful when the injection should be done in a lifecycle method instead of in the class constructor.
229
+
230
+ ```ts
231
+ @Injectable(ApplicationGraph)
232
+ class Foo {
233
+ @LazyInject() private bar!: Bar;
234
+
235
+ constructor() {
236
+ console.log(bar) // undefined
237
+ Obsidian.inject(this);
238
+ console.log(bar) // Bar {}
239
+ }
240
+ }
241
+ ```
242
+
243
+ In the example above, the dependencies are resolved from the graph declared in the `@Injectable()` decorator. Declaring the graph in advance isn't always desirable. When using the `@LazyInject()` decorator, we can omit the `@Injectable()` decorator and specify the graph to inject from in the call to ``Obsidian.inject()`.
244
+
245
+ ```ts
246
+ class Foo {
247
+ @LazyInject() private bar!: Bar;
248
+
249
+ constructor() {
250
+ console.log(bar) // undefined
251
+ Obsidian.inject(this, () => new ApplicationGraph());
252
+ console.log(bar) // Bar {}
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### Typing graphs
258
+ Obsidian exposes a utility `type` that represents the dependencies provided by a graph. This type is useful when typing props passed to components or hooks. It's especially useful when you need to differentiate between "own" props and injected props.
259
+
260
+ ```ts
261
+ type InjectedDependencies = DependenciesOf<ApplicationGraph> // { biLogger: BiLogger, httpClient: HttpClient }
262
+
263
+ // These are props our hook requires from the calling scope
264
+ interface OwnProps {
265
+ someArgs: string
266
+ }
267
+
268
+ // This interface represents the object returned from the hook
269
+ interface Result {
270
+ //
271
+ }
272
+
273
+ // Our hook requires two dependencies:
274
+ // 1. someArg - passed down from the calling scope
275
+ // 2. biLogger - injected from the ApplicationGraph
276
+ const hook = ({someArg, biLogger}: OwnProps & InjectedDependencies): Result => {
277
+ // ...
278
+ }
279
+
280
+ // When invoking the hook, it must be provided with `someArg` since OwnProps aren't optional
281
+ const injectedHook: (props: OwnProps & Partial<InjectedDependencies>) => Result = injectHookWithArguments<InjectedDependencies, OwnProps, Result>(hook, MainApplication);
282
+ ```
283
+
225
284
  ### Graph middleware
226
285
  When working on large scale applications, we often need to to hook into various low level operations. Obsidian lets you hook into the graph creation process by adding middleware(s).
227
286
 
@@ -249,7 +308,7 @@ const loggingMiddleware = new class extends GraphMiddleware {
249
308
  Obsidian.addGraphMiddleware(loggingMiddleware);
250
309
  ```
251
310
 
252
- ### Clear graphs
311
+ ### Clearing graphs
253
312
  Graphs can be cleared by invoking `Obsidian.clearGraphs()`. This is useful in tests or when you need to reset the system to it's original state, for example when a user logs out.
254
313
 
255
314
  #### Clearing graphs automatically during execution of Jest tests
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentInjector.d.ts","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,CAAC,CAAC,EACN,MAAM,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAClC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAMtC,OAAO,CAAC,aAAa;CAUtB"}
1
+ {"version":3,"file":"ComponentInjector.d.ts","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,CAAC,CAAC,EACN,MAAM,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAClC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAMtC,OAAO,CAAC,aAAa;CAgBtB"}
@@ -30,6 +30,7 @@ var react_1 = __importStar(require("react"));
30
30
  var hoist_non_react_statics_1 = __importDefault(require("hoist-non-react-statics"));
31
31
  var PropsInjector_1 = __importDefault(require("./PropsInjector"));
32
32
  var useGraph_1 = __importDefault(require("./useGraph"));
33
+ var React_1 = require("../../utils/React");
33
34
  var ComponentInjector = /** @class */ (function () {
34
35
  function ComponentInjector() {
35
36
  }
@@ -38,10 +39,14 @@ var ComponentInjector = /** @class */ (function () {
38
39
  (0, hoist_non_react_statics_1.default)(Wrapped, Target);
39
40
  return Wrapped;
40
41
  };
41
- ComponentInjector.prototype.wrapComponent = function (Target, Graph) {
42
+ ComponentInjector.prototype.wrapComponent = function (InjectionCandidate, Graph) {
42
43
  return function (passedProps) {
43
44
  var graph = (0, useGraph_1.default)(Graph, passedProps);
44
- var proxiedProps = (0, react_1.useState)(new PropsInjector_1.default(graph).inject(passedProps))[0];
45
+ var _a = (0, react_1.useState)(new PropsInjector_1.default(graph).inject(passedProps)), proxiedProps = _a[0], setProxiedProps = _a[1];
46
+ (0, react_1.useEffect)(function () {
47
+ setProxiedProps(new PropsInjector_1.default(graph).inject(passedProps));
48
+ }, [passedProps]);
49
+ var Target = (0, React_1.isMemoizedComponent)(InjectionCandidate) ? InjectionCandidate.type : InjectionCandidate;
45
50
  return react_1.default.createElement(react_1.default.Fragment, null, Target(proxiedProps));
46
51
  };
47
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentInjector.js","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwC;AACxC,oFAA2D;AAE3D,kEAA4C;AAC5C,wDAAkC;AAGlC;IAAA;IAoBA,CAAC;IAnBC,kCAAM,GAAN,UACE,MAAkC,EAClC,KAAiC;QAEjC,IAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAClD,IAAA,iCAAoB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,yCAAa,GAArB,UACE,MAAkC,EAClC,KAAiC;QAEjC,OAAO,UAAC,WAAuB;YAC7B,IAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACpC,IAAA,YAAY,GAAI,IAAA,gBAAQ,EAAC,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAA1D,CAA2D;YAC9E,OAAO,8DAAG,MAAM,CAAC,YAA4B,CAAC,CAAI,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IACH,wBAAC;AAAD,CAAC,AApBD,IAoBC"}
1
+ {"version":3,"file":"ComponentInjector.js","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAmD;AACnD,oFAA2D;AAE3D,kEAA4C;AAC5C,wDAAkC;AAElC,2CAAwD;AAExD;IAAA;IA0BA,CAAC;IAzBC,kCAAM,GAAN,UACE,MAAkC,EAClC,KAAiC;QAEjC,IAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAClD,IAAA,iCAAoB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,yCAAa,GAArB,UACE,kBAA8C,EAC9C,KAAiC;QAEjC,OAAO,UAAC,WAAuB;YAC7B,IAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACrC,IAAA,KAAkC,IAAA,gBAAQ,EAAC,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAvF,YAAY,QAAA,EAAE,eAAe,QAA0D,CAAC;YAE/F,IAAA,iBAAS,EAAC;gBACR,eAAe,CAAC,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;YAChE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;YAElB,IAAM,MAAM,GAAG,IAAA,2BAAmB,EAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;YACtG,OAAO,8DAAG,MAAM,CAAC,YAA4B,CAAC,CAAI,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IACH,wBAAC;AAAD,CAAC,AA1BD,IA0BC"}
@@ -1,5 +1,5 @@
1
1
  import { ObjectGraph } from '../../graph/ObjectGraph';
2
2
  import { Constructable } from '../../types';
3
- export declare function injectHookWithArguments<Result, Injected, Args>(hook: (args: Injected & Args) => Result, Graph: Constructable<ObjectGraph>): (props: Args & Partial<Injected>) => Result;
4
- export declare function injectHook<Result, Injected>(hook: (args: Injected) => Result, Graph: Constructable<ObjectGraph>): (props?: Partial<Injected>) => Result;
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;
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,MAAM,EAAE,QAAQ,EAAE,IAAI,EAC5D,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAK,MAAM,EACvC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,MAAM,CAE7C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,EACzC,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,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 +1 @@
1
- {"version":3,"file":"InjectHook.js","sourceRoot":"","sources":["../../../../src/injectors/hooks/InjectHook.ts"],"names":[],"mappings":";;;;;;AAGA,gEAA0C;AAE1C,IAAM,YAAY,GAAG,IAAI,sBAAY,EAAE,CAAC;AAExC,6HAA6H;AAC7H,0FAA0F;AAC1F,uHAAuH;AACvH,yEAAyE;AAEzE,SAAgB,uBAAuB,CACrC,IAAuC,EACvC,KAAiC;IAEjC,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,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,gEAA0C;AAE1C,IAAM,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,CAAC,CAAC;AAC1C,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"}
@@ -6,7 +6,7 @@ export declare type Constructor = {
6
6
  new (...args: any[]): any;
7
7
  };
8
8
  export declare type ServiceLocator<Clazz> = {
9
- [Key in keyof Clazz]: Function;
9
+ [Key in keyof Clazz]: () => Clazz[Key] extends (...args: any[]) => infer R ? R : never;
10
10
  };
11
11
  export declare type GraphInternals = 'retrieve' | 'name' | 'scope';
12
12
  export declare type DependenciesOf<G> = G extends Graph ? DependenciesOf1<G> : G extends any[] ? DependenciesOfN<G> : never;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,oBAAY,aAAa,CAAC,CAAC,IAAI;IAC7B,KAAI,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC;CACtB,CAAC;AAEF,oBAAY,WAAW,GAAG;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;CAAE,CAAC;AAEvD,oBAAY,cAAc,CAAC,KAAK,IAAI;KACjC,GAAG,IAAI,MAAM,KAAK,GAAG,QAAQ;CAC/B,CAAC;AAEF,oBAAY,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,oBAAY,cAAc,CAAC,CAAC,IAC1B,CAAC,SAAS,KAAK,GACb,eAAe,CAAC,CAAC,CAAC,GAClB,CAAC,SAAS,GAAG,EAAE,GACb,eAAe,CAAC,CAAC,CAAC,GAClB,KAAK,CAAC;AAEZ,aAAK,eAAe,CAAC,MAAM,SAAS,GAAG,EAAE,IACvC,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAClC,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC;AAEZ,aAAK,eAAe,CAAC,KAAK,IAAI;KAC3B,GAAG,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;CACvG,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,oBAAY,aAAa,CAAC,CAAC,IAAI;IAC7B,KAAI,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC;CACtB,CAAC;AAEF,oBAAY,WAAW,GAAG;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;CAAE,CAAC;AAEvD,oBAAY,cAAc,CAAC,KAAK,IAAI;KACjC,GAAG,IAAI,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;CACvF,CAAC;AAEF,oBAAY,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,oBAAY,cAAc,CAAC,CAAC,IAC1B,CAAC,SAAS,KAAK,GACb,eAAe,CAAC,CAAC,CAAC,GAClB,CAAC,SAAS,GAAG,EAAE,GACb,eAAe,CAAC,CAAC,CAAC,GAClB,KAAK,CAAC;AAEZ,aAAK,eAAe,CAAC,MAAM,SAAS,GAAG,EAAE,IACvC,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAClC,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC;AAEZ,aAAK,eAAe,CAAC,KAAK,IAAI;KAC3B,GAAG,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;CACvG,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { FunctionComponent } from 'react';
2
+ declare type MemoizedComponent = React.MemoExoticComponent<FunctionComponent<any>>;
3
+ export declare function isMemoizedComponent(component: FunctionComponent<any>): component is MemoizedComponent;
4
+ export {};
5
+ //# sourceMappingURL=React.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"React.d.ts","sourceRoot":"","sources":["../../../src/utils/React.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE1C,aAAK,iBAAiB,GAAG,KAAK,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3E,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,iBAAiB,CAErG"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMemoizedComponent = void 0;
4
+ function isMemoizedComponent(component) {
5
+ return component.type !== undefined;
6
+ }
7
+ exports.isMemoizedComponent = isMemoizedComponent;
8
+ //# sourceMappingURL=React.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"React.js","sourceRoot":"","sources":["../../../src/utils/React.ts"],"names":[],"mappings":";;;AAGA,SAAgB,mBAAmB,CAAC,SAAiC;IACnE,OAAQ,SAA+B,CAAC,IAAI,KAAK,SAAS,CAAC;AAC7D,CAAC;AAFD,kDAEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-obsidian",
3
- "version": "0.0.23",
3
+ "version": "0.0.26",
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",
@@ -1,9 +1,10 @@
1
- import React, { useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import hoistNonReactStatics from 'hoist-non-react-statics';
3
3
  import { ObjectGraph } from '../../graph/ObjectGraph';
4
4
  import PropsInjector from './PropsInjector';
5
5
  import useGraph from './useGraph';
6
6
  import { Constructable } from '../../types';
7
+ import { isMemoizedComponent } from '../../utils/React';
7
8
 
8
9
  export default class ComponentInjector {
9
10
  inject<P>(
@@ -16,12 +17,18 @@ export default class ComponentInjector {
16
17
  }
17
18
 
18
19
  private wrapComponent<P>(
19
- Target: React.FunctionComponent<P>,
20
+ InjectionCandidate: React.FunctionComponent<P>,
20
21
  Graph: Constructable<ObjectGraph>,
21
22
  ): React.FunctionComponent<Partial<P>> {
22
23
  return (passedProps: Partial<P>) => {
23
24
  const graph = useGraph(Graph, passedProps);
24
- const [proxiedProps] = useState(new PropsInjector(graph).inject(passedProps));
25
+ const [proxiedProps, setProxiedProps] = useState(new PropsInjector(graph).inject(passedProps));
26
+
27
+ useEffect(() => {
28
+ setProxiedProps(new PropsInjector(graph).inject(passedProps));
29
+ }, [passedProps]);
30
+
31
+ const Target = isMemoizedComponent(InjectionCandidate) ? InjectionCandidate.type : InjectionCandidate;
25
32
  return <>{Target(proxiedProps as unknown as P)}</>;
26
33
  };
27
34
  }
@@ -10,14 +10,14 @@ const hookInjector = new HookInjector();
10
10
  // 1. injectHookWithArguments: Should be used when a hook requires parameters in addition to the injected dependencies.
11
11
  // 2. injectHook: Should be used when a hook does not require parameters.
12
12
 
13
- export function injectHookWithArguments<Result, Injected, Args>(
14
- hook: (args: Injected & Args) => Result,
13
+ export function injectHookWithArguments<Injected, Own, Result = {}>(
14
+ hook: (args: Injected & Own) => Result,
15
15
  Graph: Constructable<ObjectGraph>,
16
- ): (props: Args & Partial<Injected>) => Result {
16
+ ): (props: Own & Partial<Injected>) => Result {
17
17
  return hookInjector.inject(hook, Graph);
18
18
  }
19
19
 
20
- export function injectHook<Result, Injected>(
20
+ export function injectHook<Injected, Result = {}>(
21
21
  hook: (args: Injected) => Result,
22
22
  Graph: Constructable<ObjectGraph>,
23
23
  ): (props?: Partial<Injected>) => Result {
@@ -7,7 +7,7 @@ export type Constructable<T> = {
7
7
  export type Constructor = { new(...args: any[]): any };
8
8
 
9
9
  export type ServiceLocator<Clazz> = {
10
- [Key in keyof Clazz]: Function
10
+ [Key in keyof Clazz]: () => Clazz[Key] extends (...args: any[]) => infer R ? R : never;
11
11
  };
12
12
 
13
13
  export type GraphInternals = 'retrieve' | 'name' | 'scope';
@@ -0,0 +1,6 @@
1
+ import { FunctionComponent } from 'react';
2
+
3
+ type MemoizedComponent = React.MemoExoticComponent<FunctionComponent<any>>;
4
+ export function isMemoizedComponent(component: FunctionComponent<any>): component is MemoizedComponent {
5
+ return (component as MemoizedComponent).type !== undefined;
6
+ }