├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── index.ts
├── package-lock.json
├── package.json
├── resources
├── convert-flying-ducks-to-this.png
├── example-of-flying-ducks.png
├── real-example-with-render.png
├── real-example.png
└── usage-example.png
├── tsconfig.json
├── yarn-error.log
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | resources
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2019 Edvinas Pranka(@epranka, https:///www.kodmina.lt)
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | react-combine-providers
2 | ========================
3 |
4 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 | In React.js, libraries such as ReactRouter, StyledComponents SSR, ReactHelmet and many other has providers. If you has a more than four providers in the root of the application, your entry file usually looks like as flying ducks in the sky
15 |
16 | 
17 |
18 | This module lets avoid it, and makes flying ducks more readable
19 |
20 | 
21 |
22 | ### Install
23 |
24 | ```
25 | npm install --save react-combine-providers
26 | ```
27 |
28 | or
29 |
30 | ```
31 | yarn install react-combine-providers
32 | ```
33 |
34 | ### Import module
35 |
36 | ```js
37 | import { combineProviders } from "react-combine-providers";
38 | ```
39 |
40 | ### Usage
41 |
42 | 
43 |
44 | ### Real example
45 |
46 | 
47 |
48 | ### Real example with render
49 |
50 | If you have problems with state loose, use render method instead
51 |
52 | 
53 |
54 |
55 | ### Author
56 |
57 | Edvinas pranka
58 |
59 | [@epranka](https://twitter.com/epranka)
60 |
61 | https://www.kodmina.lt
62 |
63 | # License
64 |
65 | ISC License
66 |
67 | Copyright (c) 2019 Edvinas Pranka(@epranka, https:///www.kodmina.lt)
68 |
69 | Permission to use, copy, modify, and/or distribute this software for any
70 | purpose with or without fee is hereby granted, provided that the above
71 | copyright notice and this permission notice appear in all copies.
72 |
73 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
74 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
75 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
76 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
77 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
78 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
79 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
80 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | export declare class CombineProviders {
3 | private stack;
4 | constructor();
5 | private getNode;
6 | push
(Component: React.ComponentType
, props?: P): void; 7 | private createProvidersTree; 8 | render(children: any): any; 9 | master(): ({ children }: { 10 | children: any; 11 | }) => any; 12 | } 13 | export declare const combineProviders: () => CombineProviders; 14 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __assign = (this && this.__assign) || function () { 3 | __assign = Object.assign || function(t) { 4 | for (var s, i = 1, n = arguments.length; i < n; i++) { 5 | s = arguments[i]; 6 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) 7 | t[p] = s[p]; 8 | } 9 | return t; 10 | }; 11 | return __assign.apply(this, arguments); 12 | }; 13 | var __importStar = (this && this.__importStar) || function (mod) { 14 | if (mod && mod.__esModule) return mod; 15 | var result = {}; 16 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 17 | result["default"] = mod; 18 | return result; 19 | }; 20 | Object.defineProperty(exports, "__esModule", { value: true }); 21 | var React = __importStar(require("react")); 22 | var CombineProviders = /** @class */ (function () { 23 | function CombineProviders() { 24 | this.stack = []; 25 | this.stack = []; 26 | } 27 | CombineProviders.prototype.getNode = function (Component) { 28 | // @ts-ignore 29 | return this.stack.find(function (node) { 30 | return node.Component === Component; 31 | }); 32 | }; 33 | CombineProviders.prototype.push = function (Component, props) { 34 | // @ts-ignore 35 | var node = this.getNode(Component); 36 | if (node) { 37 | node.props = props; 38 | } 39 | else { 40 | // @ts-ignore 41 | this.stack.push({ Component: Component, props: props }); 42 | } 43 | }; 44 | CombineProviders.prototype.createProvidersTree = function (stack, index, children) { 45 | if (index === void 0) { index = 0; } 46 | var isLastNode = index === stack.length - 1; 47 | var providerNode = stack[index]; 48 | var component = providerNode.Component; 49 | var props = providerNode.props; 50 | if (isLastNode) { 51 | return React.createElement(component, __assign({}, (props || {}), { children: children })); 52 | } 53 | else { 54 | return React.createElement(component, props, this.createProvidersTree(stack, ++index, children)); 55 | } 56 | }; 57 | CombineProviders.prototype.render = function (children) { 58 | return this.createProvidersTree(this.stack, 0, children); 59 | }; 60 | CombineProviders.prototype.master = function () { 61 | var _this = this; 62 | return function (_a) { 63 | var children = _a.children; 64 | return _this.createProvidersTree(_this.stack, 0, children); 65 | }; 66 | }; 67 | return CombineProviders; 68 | }()); 69 | exports.CombineProviders = CombineProviders; 70 | exports.combineProviders = function () { 71 | return new CombineProviders(); 72 | }; 73 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | interface ProviderNode { 3 | Component: React.ComponentType; 4 | props?: any; 5 | } 6 | export class CombineProviders { 7 | private stack: ProviderNode[] = []; 8 | constructor() { 9 | this.stack = []; 10 | } 11 | 12 | private getNode(Component: React.ComponentType) { 13 | // @ts-ignore 14 | return this.stack.find(node => { 15 | return node.Component === Component; 16 | }); 17 | } 18 | 19 | public push
(Component: React.ComponentType
, props?: P) {
20 | // @ts-ignore
21 | const node = this.getNode(Component);
22 | if (node) {
23 | node.props = props;
24 | } else {
25 | // @ts-ignore
26 | this.stack.push({ Component, props });
27 | }
28 | }
29 |
30 | private createProvidersTree(
31 | stack: ProviderNode[],
32 | index: number = 0,
33 | children
34 | ) {
35 | const isLastNode = index === stack.length - 1;
36 | const providerNode = stack[index];
37 | const component = providerNode.Component;
38 | const props = providerNode.props;
39 | if (isLastNode) {
40 | return React.createElement(component, {
41 | ...(props || {}),
42 | children: children
43 | });
44 | } else {
45 | return React.createElement(
46 | component,
47 | props,
48 | this.createProvidersTree(stack, ++index, children)
49 | );
50 | }
51 | }
52 |
53 | public render(children) {
54 | return this.createProvidersTree(this.stack, 0, children);
55 | }
56 |
57 | public master() {
58 | return ({ children }) => {
59 | return this.createProvidersTree(this.stack, 0, children);
60 | };
61 | }
62 | }
63 |
64 | export const combineProviders = () => {
65 | return new CombineProviders();
66 | };
67 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-combine-providers",
3 | "version": "0.9.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/prop-types": {
8 | "version": "15.5.9",
9 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.9.tgz",
10 | "integrity": "sha512-Nha5b+jmBI271jdTMwrHiNXM+DvThjHOfyZtMX9kj/c/LUj2xiLHsG/1L3tJ8DjAoQN48cHwUwtqBotjyXaSdQ==",
11 | "dev": true
12 | },
13 | "@types/react": {
14 | "version": "16.8.3",
15 | "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.3.tgz",
16 | "integrity": "sha512-PjPocAxL9SNLjYMP4dfOShW/rj9FDBJGu3JFRt0zEYf77xfihB6fq8zfDpMrV6s82KnAi7F1OEe5OsQX25Ybdw==",
17 | "dev": true,
18 | "requires": {
19 | "@types/prop-types": "15.5.9",
20 | "csstype": "2.6.2"
21 | }
22 | },
23 | "csstype": {
24 | "version": "2.6.2",
25 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.2.tgz",
26 | "integrity": "sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow==",
27 | "dev": true
28 | },
29 | "js-tokens": {
30 | "version": "4.0.0",
31 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
32 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
33 | },
34 | "loose-envify": {
35 | "version": "1.4.0",
36 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
37 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
38 | "requires": {
39 | "js-tokens": "4.0.0"
40 | }
41 | },
42 | "object-assign": {
43 | "version": "4.1.1",
44 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
45 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
46 | },
47 | "prop-types": {
48 | "version": "15.7.2",
49 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
50 | "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
51 | "requires": {
52 | "loose-envify": "1.4.0",
53 | "object-assign": "4.1.1",
54 | "react-is": "16.8.2"
55 | }
56 | },
57 | "react": {
58 | "version": "16.8.2",
59 | "resolved": "https://registry.npmjs.org/react/-/react-16.8.2.tgz",
60 | "integrity": "sha512-aB2ctx9uQ9vo09HVknqv3DGRpI7OIGJhCx3Bt0QqoRluEjHSaObJl+nG12GDdYH6sTgE7YiPJ6ZUyMx9kICdXw==",
61 | "requires": {
62 | "loose-envify": "1.4.0",
63 | "object-assign": "4.1.1",
64 | "prop-types": "15.7.2",
65 | "scheduler": "0.13.2"
66 | }
67 | },
68 | "react-is": {
69 | "version": "16.8.2",
70 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.2.tgz",
71 | "integrity": "sha512-D+NxhSR2HUCjYky1q1DwpNUD44cDpUXzSmmFyC3ug1bClcU/iDNy0YNn1iwme28fn+NFhpA13IndOd42CrFb+Q=="
72 | },
73 | "scheduler": {
74 | "version": "0.13.2",
75 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.2.tgz",
76 | "integrity": "sha512-qK5P8tHS7vdEMCW5IPyt8v9MJOHqTrOUgPXib7tqm9vh834ibBX5BNhwkplX/0iOzHW5sXyluehYfS9yrkz9+w==",
77 | "requires": {
78 | "loose-envify": "1.4.0",
79 | "object-assign": "4.1.1"
80 | }
81 | },
82 | "typescript": {
83 | "version": "3.3.3",
84 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz",
85 | "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==",
86 | "dev": true
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-combine-providers",
3 | "version": "0.9.6",
4 | "description": "Avoid flying ducks in react providers tree",
5 | "main": "index.js",
6 | "types": "index.d.ts",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1",
9 | "build": "tsc --declaration"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/epranka/react-combine-providers.git"
14 | },
15 | "keywords": [
16 | "react",
17 | "reactjs",
18 | "combine",
19 | "providers",
20 | "javascript",
21 | "es6",
22 | "typescript"
23 | ],
24 | "author": "Edvinas Pranka (@epranka, https://www.kodmina.lt)",
25 | "license": "ISC",
26 | "bugs": {
27 | "url": "https://github.com/epranka/react-combine-providers/issues"
28 | },
29 | "homepage": "https://github.com/epranka/react-combine-providers#readme",
30 | "peerDependencies": {
31 | "react": ">=16"
32 | },
33 | "devDependencies": {
34 | "@types/react": "^16.8.3",
35 | "typescript": "3.2.0-dev.20181006"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/resources/convert-flying-ducks-to-this.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epranka/react-combine-providers/c925232f2dc6ba7e42acbdb654d5540eb7df4ff0/resources/convert-flying-ducks-to-this.png
--------------------------------------------------------------------------------
/resources/example-of-flying-ducks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epranka/react-combine-providers/c925232f2dc6ba7e42acbdb654d5540eb7df4ff0/resources/example-of-flying-ducks.png
--------------------------------------------------------------------------------
/resources/real-example-with-render.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epranka/react-combine-providers/c925232f2dc6ba7e42acbdb654d5540eb7df4ff0/resources/real-example-with-render.png
--------------------------------------------------------------------------------
/resources/real-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epranka/react-combine-providers/c925232f2dc6ba7e42acbdb654d5540eb7df4ff0/resources/real-example.png
--------------------------------------------------------------------------------
/resources/usage-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/epranka/react-combine-providers/c925232f2dc6ba7e42acbdb654d5540eb7df4ff0/resources/usage-example.png
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "esModuleInterop": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/yarn-error.log:
--------------------------------------------------------------------------------
1 | Arguments:
2 | /home/epranka/.nvm/versions/node/v12.3.1/bin/node /usr/share/yarn/bin/yarn.js add 3.2.0-dev.20181006 -D
3 |
4 | PATH:
5 | /home/epranka/.nvm/versions/node/v12.3.1/bin:/home/epranka/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
6 |
7 | Yarn version:
8 | 1.16.0
9 |
10 | Node version:
11 | 12.3.1
12 |
13 | Platform:
14 | linux x64
15 |
16 | Trace:
17 | Error: https://registry.yarnpkg.com/3.2.0-dev.20181006: Not found
18 | at Request.params.callback [as _callback] (/usr/share/yarn/lib/cli.js:66091:18)
19 | at Request.self.callback (/usr/share/yarn/lib/cli.js:129590:22)
20 | at Request.emit (events.js:200:13)
21 | at Request.