react-obsidian 0.0.24 → 0.0.27
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 +1 -2
- package/dist/src/injectors/components/ComponentInjector.d.ts.map +1 -1
- package/dist/src/injectors/components/ComponentInjector.js +14 -2
- package/dist/src/injectors/components/ComponentInjector.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/React.d.ts +7 -0
- package/dist/src/utils/React.d.ts.map +1 -0
- package/dist/src/utils/React.js +8 -0
- package/dist/src/utils/React.js.map +1 -0
- package/package.json +1 -1
- package/src/injectors/components/ComponentInjector.tsx +16 -3
- package/src/types/index.ts +1 -1
- package/src/utils/React.ts +8 -0
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
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
|
-
|
|
15
14
|
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
15
|
|
|
17
16
|
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.
|
|
@@ -115,7 +114,7 @@ const useButtonClick = ({ biLogger }: UseButtonPressProps): UseButtonPress => {
|
|
|
115
114
|
};
|
|
116
115
|
|
|
117
116
|
// Dependencies are injected from ApplicationGraph
|
|
118
|
-
export default injectHook(
|
|
117
|
+
export default injectHook(useButtonClick, ApplicationGraph);
|
|
119
118
|
|
|
120
119
|
// Now that we exported the injected hook, we can use it in a component without the needed so provide its dependencies manually
|
|
121
120
|
const Component = () => (
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentInjector.d.ts","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
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;CAsBtB"}
|
|
@@ -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,21 @@ 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 (
|
|
42
|
+
ComponentInjector.prototype.wrapComponent = function (InjectionCandidate, Graph) {
|
|
42
43
|
return function (passedProps) {
|
|
43
44
|
var graph = (0, useGraph_1.default)(Graph, passedProps);
|
|
44
|
-
var
|
|
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
|
+
if ((0, React_1.isMemoizedComponent)(InjectionCandidate) && InjectionCandidate.compare) {
|
|
48
|
+
if (!InjectionCandidate.compare(proxiedProps, passedProps)) {
|
|
49
|
+
setProxiedProps(new PropsInjector_1.default(graph).inject(passedProps));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
setProxiedProps(new PropsInjector_1.default(graph).inject(passedProps));
|
|
54
|
+
}
|
|
55
|
+
}, [passedProps]);
|
|
56
|
+
var Target = (0, React_1.isMemoizedComponent)(InjectionCandidate) ? InjectionCandidate.type : InjectionCandidate;
|
|
45
57
|
return react_1.default.createElement(react_1.default.Fragment, null, Target(proxiedProps));
|
|
46
58
|
};
|
|
47
59
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentInjector.js","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
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;IAgCA,CAAC;IA/BC,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,IAAI,IAAA,2BAAmB,EAAC,kBAAkB,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE;oBACzE,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE;wBAC1D,eAAe,CAAC,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;qBAC/D;iBACF;qBAAM;oBACL,eAAe,CAAC,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;iBAC/D;YACH,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,AAhCD,IAgCC"}
|
|
@@ -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]:
|
|
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,
|
|
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,7 @@
|
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
2
|
+
declare type MemoizedComponent = React.MemoExoticComponent<FunctionComponent<any>> & {
|
|
3
|
+
compare?: (prevProps: any, nextProps: any) => boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare function isMemoizedComponent(component: FunctionComponent<any>): component is MemoizedComponent;
|
|
6
|
+
export {};
|
|
7
|
+
//# 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,GAAG;IAC3E,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC;CACvD,CAAC;AACF,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":";;;AAKA,SAAgB,mBAAmB,CAAC,SAAiC;IACnE,OAAQ,SAA+B,CAAC,IAAI,KAAK,SAAS,CAAC;AAC7D,CAAC;AAFD,kDAEC"}
|
package/package.json
CHANGED
|
@@ -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,24 @@ export default class ComponentInjector {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
private wrapComponent<P>(
|
|
19
|
-
|
|
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
|
+
if (isMemoizedComponent(InjectionCandidate) && InjectionCandidate.compare) {
|
|
29
|
+
if (!InjectionCandidate.compare(proxiedProps, passedProps)) {
|
|
30
|
+
setProxiedProps(new PropsInjector(graph).inject(passedProps));
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
setProxiedProps(new PropsInjector(graph).inject(passedProps));
|
|
34
|
+
}
|
|
35
|
+
}, [passedProps]);
|
|
36
|
+
|
|
37
|
+
const Target = isMemoizedComponent(InjectionCandidate) ? InjectionCandidate.type : InjectionCandidate;
|
|
25
38
|
return <>{Target(proxiedProps as unknown as P)}</>;
|
|
26
39
|
};
|
|
27
40
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -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]:
|
|
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,8 @@
|
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
2
|
+
|
|
3
|
+
type MemoizedComponent = React.MemoExoticComponent<FunctionComponent<any>> & {
|
|
4
|
+
compare?: (prevProps: any, nextProps: any) => boolean;
|
|
5
|
+
};
|
|
6
|
+
export function isMemoizedComponent(component: FunctionComponent<any>): component is MemoizedComponent {
|
|
7
|
+
return (component as MemoizedComponent).type !== undefined;
|
|
8
|
+
}
|