react-obsidian 0.0.25 → 0.0.28
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 +9 -28
- package/dist/src/injectors/components/ComponentInjector.js.map +1 -1
- package/dist/src/utils/React.d.ts +8 -0
- package/dist/src/utils/React.d.ts.map +1 -0
- package/dist/src/utils/React.js +16 -0
- package/dist/src/utils/React.js.map +1 -0
- package/package.json +1 -1
- package/src/injectors/components/ComponentInjector.tsx +11 -5
- package/src/utils/React.ts +15 -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,KAAK,MAAM,OAAO,CAAC;AAE1B,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;CAetB"}
|
|
@@ -1,35 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
var react_1 =
|
|
6
|
+
var react_1 = __importDefault(require("react"));
|
|
30
7
|
var hoist_non_react_statics_1 = __importDefault(require("hoist-non-react-statics"));
|
|
31
8
|
var PropsInjector_1 = __importDefault(require("./PropsInjector"));
|
|
32
9
|
var useGraph_1 = __importDefault(require("./useGraph"));
|
|
10
|
+
var React_1 = require("../../utils/React");
|
|
33
11
|
var ComponentInjector = /** @class */ (function () {
|
|
34
12
|
function ComponentInjector() {
|
|
35
13
|
}
|
|
@@ -38,12 +16,15 @@ var ComponentInjector = /** @class */ (function () {
|
|
|
38
16
|
(0, hoist_non_react_statics_1.default)(Wrapped, Target);
|
|
39
17
|
return Wrapped;
|
|
40
18
|
};
|
|
41
|
-
ComponentInjector.prototype.wrapComponent = function (
|
|
42
|
-
|
|
19
|
+
ComponentInjector.prototype.wrapComponent = function (InjectionCandidate, Graph) {
|
|
20
|
+
var isMemoized = (0, React_1.isMemoizedComponent)(InjectionCandidate);
|
|
21
|
+
var Target = isMemoized ? InjectionCandidate.type : InjectionCandidate;
|
|
22
|
+
var compare = isMemoized ? InjectionCandidate.compare : undefined;
|
|
23
|
+
return (0, React_1.genericMemo)(function (passedProps) {
|
|
43
24
|
var graph = (0, useGraph_1.default)(Graph, passedProps);
|
|
44
|
-
var proxiedProps =
|
|
25
|
+
var proxiedProps = new PropsInjector_1.default(graph).inject(passedProps);
|
|
45
26
|
return react_1.default.createElement(react_1.default.Fragment, null, Target(proxiedProps));
|
|
46
|
-
};
|
|
27
|
+
}, compare);
|
|
47
28
|
};
|
|
48
29
|
return ComponentInjector;
|
|
49
30
|
}());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentInjector.js","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ComponentInjector.js","sourceRoot":"","sources":["../../../../src/injectors/components/ComponentInjector.tsx"],"names":[],"mappings":";;;;;AAAA,gDAA0B;AAC1B,oFAA2D;AAE3D,kEAA4C;AAC5C,wDAAkC;AAElC,2CAAqE;AAErE;IAAA;IAyBA,CAAC;IAxBC,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,IAAM,UAAU,GAAG,IAAA,2BAAmB,EAAC,kBAAkB,CAAC,CAAC;QAC3D,IAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;QACzE,IAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpE,OAAO,IAAA,mBAAW,EAAC,UAAC,WAAc;YAChC,IAAM,KAAK,GAAG,IAAA,kBAAQ,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC3C,IAAM,YAAY,GAAG,IAAI,uBAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAElE,OAAO,8DAAG,MAAM,CAAC,YAA4B,CAAC,CAAI,CAAC;QACrD,CAAC,EAAE,OAAO,CAAC,CAAC;IACd,CAAC;IACH,wBAAC;AAAD,CAAC,AAzBD,IAyBC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { 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 declare function genericMemo<C extends React.ComponentType<any>>(Component: Parameters<typeof React.memo>[0], propsAreEqual?: Parameters<typeof React.memo>[1]): C;
|
|
7
|
+
export {};
|
|
8
|
+
//# 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,KAAK,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEjD,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;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,EAC5D,SAAS,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAC3C,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAGjD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.genericMemo = exports.isMemoizedComponent = void 0;
|
|
7
|
+
var react_1 = __importDefault(require("react"));
|
|
8
|
+
function isMemoizedComponent(component) {
|
|
9
|
+
return component.type !== undefined;
|
|
10
|
+
}
|
|
11
|
+
exports.isMemoizedComponent = isMemoizedComponent;
|
|
12
|
+
function genericMemo(Component, propsAreEqual) {
|
|
13
|
+
return react_1.default.memo(Component, propsAreEqual);
|
|
14
|
+
}
|
|
15
|
+
exports.genericMemo = genericMemo;
|
|
16
|
+
//# sourceMappingURL=React.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"React.js","sourceRoot":"","sources":["../../../src/utils/React.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAiD;AAKjD,SAAgB,mBAAmB,CAAC,SAAiC;IACnE,OAAQ,SAA+B,CAAC,IAAI,KAAK,SAAS,CAAC;AAC7D,CAAC;AAFD,kDAEC;AAED,SAAgB,WAAW,CACzB,SAA2C,EAC3C,aAAgD;IAEhD,OAAO,eAAK,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAiB,CAAC;AAC9D,CAAC;AALD,kCAKC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React 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 { genericMemo, isMemoizedComponent } from '../../utils/React';
|
|
7
8
|
|
|
8
9
|
export default class ComponentInjector {
|
|
9
10
|
inject<P>(
|
|
@@ -16,13 +17,18 @@ 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
|
+
const isMemoized = isMemoizedComponent(InjectionCandidate);
|
|
24
|
+
const Target = isMemoized ? InjectionCandidate.type : InjectionCandidate;
|
|
25
|
+
const compare = isMemoized ? InjectionCandidate.compare : undefined;
|
|
26
|
+
|
|
27
|
+
return genericMemo((passedProps: P) => {
|
|
23
28
|
const graph = useGraph(Graph, passedProps);
|
|
24
|
-
const
|
|
29
|
+
const proxiedProps = new PropsInjector(graph).inject(passedProps);
|
|
30
|
+
|
|
25
31
|
return <>{Target(proxiedProps as unknown as P)}</>;
|
|
26
|
-
};
|
|
32
|
+
}, compare);
|
|
27
33
|
}
|
|
28
34
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { 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
|
+
}
|
|
9
|
+
|
|
10
|
+
export function genericMemo<C extends React.ComponentType<any>>(
|
|
11
|
+
Component: Parameters<typeof React.memo>[0],
|
|
12
|
+
propsAreEqual?: Parameters<typeof React.memo>[1],
|
|
13
|
+
) {
|
|
14
|
+
return React.memo(Component, propsAreEqual) as unknown as C;
|
|
15
|
+
}
|