ditox-react 3.2.0 → 3.3.1
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/dist/index.cjs +175 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{browser/index.d.ts → index.d.cts} +43 -39
- package/dist/{umd/index.d.ts → index.d.ts} +43 -39
- package/dist/index.js +141 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +179 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +23 -23
- package/src/DependencyContainer.test.tsx +32 -35
- package/src/DependencyContainer.tsx +5 -5
- package/src/DependencyModule.test.tsx +10 -9
- package/src/DependencyModule.tsx +6 -6
- package/src/hooks.test.tsx +18 -17
- package/src/hooks.ts +3 -3
- package/src/index.ts +2 -4
- package/dist/browser/index.js +0 -2
- package/dist/browser/index.js.map +0 -1
- package/dist/cjs/DependencyContainer.d.ts +0 -74
- package/dist/cjs/DependencyContainer.js +0 -101
- package/dist/cjs/DependencyContainer.js.map +0 -1
- package/dist/cjs/DependencyModule.d.ts +0 -29
- package/dist/cjs/DependencyModule.js +0 -58
- package/dist/cjs/DependencyModule.js.map +0 -1
- package/dist/cjs/hooks.d.ts +0 -25
- package/dist/cjs/hooks.js +0 -39
- package/dist/cjs/hooks.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -4
- package/dist/cjs/index.js +0 -13
- package/dist/cjs/index.js.map +0 -1
- package/dist/esm/DependencyContainer.d.ts +0 -74
- package/dist/esm/DependencyContainer.js +0 -73
- package/dist/esm/DependencyContainer.js.map +0 -1
- package/dist/esm/DependencyModule.d.ts +0 -29
- package/dist/esm/DependencyModule.js +0 -31
- package/dist/esm/DependencyModule.js.map +0 -1
- package/dist/esm/hooks.d.ts +0 -25
- package/dist/esm/hooks.js +0 -33
- package/dist/esm/hooks.js.map +0 -1
- package/dist/esm/index.d.ts +0 -4
- package/dist/esm/index.js +0 -4
- package/dist/esm/index.js.map +0 -1
- package/dist/umd/index.js +0 -2
- package/dist/umd/index.js.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('ditox'), require('react')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'ditox', 'react'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.DitoxReact = {}), global.Ditox,global.React));
|
|
5
|
+
})(this, function(exports, ditox, react) {
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
7
|
+
//#region \0rolldown/runtime.js
|
|
8
|
+
var __create = Object.create;
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
17
|
+
key = keys[i];
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
19
|
+
__defProp(to, key, {
|
|
20
|
+
get: ((k) => from[k]).bind(null, key),
|
|
21
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
29
|
+
value: mod,
|
|
30
|
+
enumerable: true
|
|
31
|
+
}) : target, mod));
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
react = __toESM(react);
|
|
35
|
+
|
|
36
|
+
//#region src/DependencyContainer.tsx
|
|
37
|
+
const DependencyContainerContext = (0, react.createContext)(void 0);
|
|
38
|
+
/**
|
|
39
|
+
* Provides a new dependency container to React app
|
|
40
|
+
*
|
|
41
|
+
* This component creates a new container and provides it to React children.
|
|
42
|
+
*
|
|
43
|
+
* If a `binder` callback is specified, it will be called for the new container
|
|
44
|
+
* to bind it with dependencies.
|
|
45
|
+
*
|
|
46
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
47
|
+
* To create a root container specify `root` parameter as `true`,
|
|
48
|
+
* and the container will not depend on any parent container.
|
|
49
|
+
*
|
|
50
|
+
* @param params.binder - A callback which sets up bindings for the container.
|
|
51
|
+
* @param params.root - If `true` then a new container does not depend on any parent containers
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
*
|
|
55
|
+
* ```tsx
|
|
56
|
+
* const TOKEN = token();
|
|
57
|
+
*
|
|
58
|
+
* function appDependencyBinder(container: Container) {
|
|
59
|
+
* container.bindValue(TOKEN, 'value');
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* function App() {
|
|
63
|
+
* return (
|
|
64
|
+
* <DependencyContainer root binder={appDependencyBinder}>
|
|
65
|
+
* <NestedComponent />
|
|
66
|
+
* </DependencyContainer>
|
|
67
|
+
* );
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
*/
|
|
72
|
+
function DependencyContainer(params) {
|
|
73
|
+
const { children, root, binder } = params;
|
|
74
|
+
const parentContainer = (0, react.useContext)(DependencyContainerContext);
|
|
75
|
+
const container = (0, react.useMemo)(() => {
|
|
76
|
+
const container = (0, ditox.createContainer)(root ? void 0 : parentContainer);
|
|
77
|
+
binder === null || binder === void 0 || binder(container);
|
|
78
|
+
return container;
|
|
79
|
+
}, [
|
|
80
|
+
binder,
|
|
81
|
+
parentContainer,
|
|
82
|
+
root
|
|
83
|
+
]);
|
|
84
|
+
(0, react.useEffect)(() => {
|
|
85
|
+
return () => container.removeAll();
|
|
86
|
+
}, [container]);
|
|
87
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainerContext.Provider, { value: container }, children);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Provides a custom dependency container to React app
|
|
91
|
+
*
|
|
92
|
+
* @param params.container - a custom container
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```tsx
|
|
96
|
+
* const container = useMemo(() => {
|
|
97
|
+
* return createContainer();
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* return (
|
|
101
|
+
* <CustomDependencyContainer container={container}>
|
|
102
|
+
* {children}
|
|
103
|
+
* </CustomDependencyContainer>
|
|
104
|
+
* );
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
function CustomDependencyContainer(params) {
|
|
108
|
+
const { children, container } = params;
|
|
109
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainerContext.Provider, { value: container }, children);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/DependencyModule.tsx
|
|
114
|
+
/**
|
|
115
|
+
* Binds the module to a new dependency container.
|
|
116
|
+
*
|
|
117
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
118
|
+
*
|
|
119
|
+
* @param params.module - Module declaration for binding
|
|
120
|
+
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
*
|
|
124
|
+
* ```tsx
|
|
125
|
+
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};
|
|
126
|
+
*
|
|
127
|
+
* function App() {
|
|
128
|
+
* return (
|
|
129
|
+
* <DependencyModule module={LOGGER_MODULE}>
|
|
130
|
+
* <NestedComponent />
|
|
131
|
+
* </DependencyModule>
|
|
132
|
+
* );
|
|
133
|
+
* }
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
function DependencyModule(params) {
|
|
137
|
+
const { children, module, scope } = params;
|
|
138
|
+
const binder = (0, react.useCallback)((container) => (0, ditox.bindModule)(container, module, { scope }), [module, scope]);
|
|
139
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainer, { binder }, children);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/hooks.ts
|
|
144
|
+
/**
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
147
|
+
function useDependencyContainer(mode) {
|
|
148
|
+
const container = (0, react.useContext)(DependencyContainerContext);
|
|
149
|
+
if (!container && mode === "strict") throw new Error("Container is not provided by DependencyContainer component");
|
|
150
|
+
return container;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* @category Hook
|
|
154
|
+
*
|
|
155
|
+
* Returns a dependency by token, or fails with an error.
|
|
156
|
+
*/
|
|
157
|
+
function useDependency(token) {
|
|
158
|
+
const container = useDependencyContainer("strict");
|
|
159
|
+
return (0, react.useMemo)(() => container.resolve(token), [container, token]);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @category Hook
|
|
163
|
+
*
|
|
164
|
+
* Returns a dependency by token, or `undefined` in case the dependency is not provided.
|
|
165
|
+
*/
|
|
166
|
+
function useOptionalDependency(token) {
|
|
167
|
+
const container = useDependencyContainer();
|
|
168
|
+
return (0, react.useMemo)(() => container === null || container === void 0 ? void 0 : container.get(token), [container, token]);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
exports.CustomDependencyContainer = CustomDependencyContainer;
|
|
173
|
+
exports.DependencyContainer = DependencyContainer;
|
|
174
|
+
exports.DependencyModule = DependencyModule;
|
|
175
|
+
exports.useDependency = useDependency;
|
|
176
|
+
exports.useDependencyContainer = useDependencyContainer;
|
|
177
|
+
exports.useOptionalDependency = useOptionalDependency;
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","names":[],"sources":["../src/DependencyContainer.tsx","../src/DependencyModule.tsx","../src/hooks.ts"],"sourcesContent":["import type { Container } from 'ditox';\nimport { createContainer } from 'ditox';\nimport React, {\n createContext,\n ReactElement,\n ReactNode,\n useContext,\n useEffect,\n useMemo,\n} from 'react';\n\nexport const DependencyContainerContext = createContext<Container | undefined>(\n undefined,\n);\n\n/**\n * A callback for binding dependencies to a container\n */\nexport type DependencyContainerBinder = (container: Container) => unknown;\n\n/**\n * Specifies options for a new container:\n * @property binder - A callback which sets up bindings for the container.\n * @property root - If `true` then a new container does not depend on any parent containers\n */\nexport type DependencyContainerParams = {\n children: ReactNode;\n root?: boolean;\n binder?: DependencyContainerBinder;\n};\n\n/**\n * Provides a new dependency container to React app\n *\n * This component creates a new container and provides it to React children.\n *\n * If a `binder` callback is specified, it will be called for the new container\n * to bind it with dependencies.\n *\n * If a parent container exists, it is connected to the current one by default.\n * To create a root container specify `root` parameter as `true`,\n * and the container will not depend on any parent container.\n *\n * @param params.binder - A callback which sets up bindings for the container.\n * @param params.root - If `true` then a new container does not depend on any parent containers\n *\n * @example\n *\n * ```tsx\n * const TOKEN = token();\n *\n * function appDependencyBinder(container: Container) {\n * container.bindValue(TOKEN, 'value');\n * }\n *\n * function App() {\n * return (\n * <DependencyContainer root binder={appDependencyBinder}>\n * <NestedComponent />\n * </DependencyContainer>\n * );\n * }\n * ```\n *\n */\nexport function DependencyContainer(\n params: DependencyContainerParams,\n): ReactElement {\n const { children, root, binder } = params;\n const parentContainer = useContext(DependencyContainerContext);\n\n const container = useMemo(() => {\n const container = createContainer(root ? undefined : parentContainer);\n binder?.(container);\n\n return container;\n }, [binder, parentContainer, root]);\n\n useEffect(() => {\n return () => container.removeAll();\n }, [container]);\n\n return (\n <DependencyContainerContext.Provider value={container}>\n {children}\n </DependencyContainerContext.Provider>\n );\n}\n\n/**\n * Provides a custom dependency container to React app\n *\n * @param params.container - a custom container\n *\n * @example\n * ```tsx\n * const container = useMemo(() => {\n * return createContainer();\n * });\n *\n * return (\n * <CustomDependencyContainer container={container}>\n * {children}\n * </CustomDependencyContainer>\n * );\n * ```\n */\nexport function CustomDependencyContainer(params: {\n children: ReactNode;\n container: Container;\n}): ReactElement {\n const { children, container } = params;\n\n return (\n <DependencyContainerContext.Provider value={container}>\n {children}\n </DependencyContainerContext.Provider>\n );\n}\n","import type { Module, ModuleDeclaration } from 'ditox';\nimport { bindModule } from 'ditox';\nimport React, { ReactElement, ReactNode, useCallback } from 'react';\nimport {\n DependencyContainer,\n DependencyContainerBinder,\n} from './DependencyContainer';\n\n/**\n * Binds the module to a new dependency container.\n *\n * If a parent container exists, it is connected to the current one by default.\n *\n * @param params.module - Module declaration for binding\n * @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.\n *\n * @example\n *\n * ```tsx\n * const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};\n *\n * function App() {\n * return (\n * <DependencyModule module={LOGGER_MODULE}>\n * <NestedComponent />\n * </DependencyModule>\n * );\n * }\n * ```\n */\nexport function DependencyModule(params: {\n children: ReactNode;\n module: ModuleDeclaration<Module<Record<string, unknown>>>;\n scope?: 'scoped' | 'singleton';\n}): ReactElement {\n const { children, module, scope } = params;\n\n const binder: DependencyContainerBinder = useCallback(\n (container) => bindModule(container, module, { scope }),\n [module, scope],\n );\n\n return <DependencyContainer binder={binder}>{children}</DependencyContainer>;\n}\n","import { Container, Token } from 'ditox';\nimport { useContext, useMemo } from 'react';\nimport { DependencyContainerContext } from './DependencyContainer';\n\n/**\n * @category Hook\n *\n * Returns a dependency container. Throws an error in case the container is not provided.\n */\nexport function useDependencyContainer(mode: 'strict'): Container;\n/**\n * @category Hook\n *\n * Returns a dependency container, or `undefined` in case the container is not provided.\n */\nexport function useDependencyContainer(\n mode?: 'optional',\n): Container | undefined;\n/**\n * @internal\n */\nexport function useDependencyContainer(\n mode?: 'strict' | 'optional',\n): Container | undefined {\n const container = useContext(DependencyContainerContext);\n\n if (!container && mode === 'strict') {\n throw new Error(\n 'Container is not provided by DependencyContainer component',\n );\n }\n\n return container;\n}\n\n/**\n * @category Hook\n *\n * Returns a dependency by token, or fails with an error.\n */\nexport function useDependency<T>(token: Token<T>): T {\n const container = useDependencyContainer('strict');\n const value = useMemo(() => container.resolve(token), [container, token]);\n return value;\n}\n\n/**\n * @category Hook\n *\n * Returns a dependency by token, or `undefined` in case the dependency is not provided.\n */\nexport function useOptionalDependency<T>(token: Token<T>): T | undefined {\n const container = useDependencyContainer();\n const value = useMemo(() => container?.get(token), [container, token]);\n return value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWA,MAAa,sDACX,OACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDD,SAAgB,oBACd,QACc;EACd,MAAM,EAAE,UAAU,MAAM,WAAW;EACnC,MAAM,wCAA6B,2BAA2B;EAE9D,MAAM,qCAA0B;GAC9B,MAAM,uCAA4B,OAAO,SAAY,gBAAgB;AACrE,kDAAS,UAAU;AAEnB,UAAO;KACN;GAAC;GAAQ;GAAiB;GAAK,CAAC;AAEnC,6BAAgB;AACd,gBAAa,UAAU,WAAW;KACjC,CAAC,UAAU,CAAC;AAEf,SACE,4CAAC,2BAA2B,YAAS,OAAO,aACzC,SACmC;;;;;;;;;;;;;;;;;;;;CAsB1C,SAAgB,0BAA0B,QAGzB;EACf,MAAM,EAAE,UAAU,cAAc;AAEhC,SACE,4CAAC,2BAA2B,YAAS,OAAO,aACzC,SACmC;;;;;;;;;;;;;;;;;;;;;;;;;;;CCtF1C,SAAgB,iBAAiB,QAIhB;EACf,MAAM,EAAE,UAAU,QAAQ,UAAU;EAEpC,MAAM,iCACH,oCAAyB,WAAW,QAAQ,EAAE,OAAO,CAAC,EACvD,CAAC,QAAQ,MAAM,CAChB;AAED,SAAO,4CAAC,uBAA4B,UAAS,SAA+B;;;;;;;;CCrB9E,SAAgB,uBACd,MACuB;EACvB,MAAM,kCAAuB,2BAA2B;AAExD,MAAI,CAAC,aAAa,SAAS,SACzB,OAAM,IAAI,MACR,6DACD;AAGH,SAAO;;;;;;;CAQT,SAAgB,cAAiB,OAAoB;EACnD,MAAM,YAAY,uBAAuB,SAAS;AAElD,kCAD4B,UAAU,QAAQ,MAAM,EAAE,CAAC,WAAW,MAAM,CAAC;;;;;;;CAS3E,SAAgB,sBAAyB,OAAgC;EACvE,MAAM,YAAY,wBAAwB;AAE1C,wFAD4B,UAAW,IAAI,MAAM,EAAE,CAAC,WAAW,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ditox-react",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Dependency injection
|
|
3
|
+
"version": "3.3.1",
|
|
4
|
+
"description": "Dependency injection for web applications: adapters for React.js",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": "https://github.com/mnasyrov/ditox/issues",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/mnasyrov/ditox.git"
|
|
14
|
+
"url": "git+https://github.com/mnasyrov/ditox.git"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
17
17
|
"react",
|
|
@@ -31,16 +31,6 @@
|
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=12"
|
|
33
33
|
},
|
|
34
|
-
"main": "dist/cjs/index.js",
|
|
35
|
-
"module": "dist/esm/index.js",
|
|
36
|
-
"jsnext:main": "dist/esm/index.js",
|
|
37
|
-
"unpkg": "dist/umd/index.js",
|
|
38
|
-
"umd:main": "dist/umd/index.js",
|
|
39
|
-
"browser": "dist/browser/index.js",
|
|
40
|
-
"react-native": "dist/browser/index.js",
|
|
41
|
-
"types": "dist/esm/index.d.ts",
|
|
42
|
-
"source": "src/index.ts",
|
|
43
|
-
"sideEffects": false,
|
|
44
34
|
"files": [
|
|
45
35
|
"dist",
|
|
46
36
|
"docs",
|
|
@@ -48,18 +38,29 @@
|
|
|
48
38
|
"LICENSE",
|
|
49
39
|
"README.md"
|
|
50
40
|
],
|
|
41
|
+
"type": "module",
|
|
42
|
+
"main": "./dist/index.cjs",
|
|
43
|
+
"module": "./dist/index.js",
|
|
44
|
+
"unpkg": "dist/index.umd.js",
|
|
45
|
+
"umd:main": "dist/index.umd.js",
|
|
46
|
+
"browser": "dist/index.js",
|
|
47
|
+
"react-native": "dist/index.js",
|
|
48
|
+
"types": "./dist/index.d.cts",
|
|
49
|
+
"source": "src/index.ts",
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"import": "./dist/index.js",
|
|
53
|
+
"require": "./dist/index.cjs"
|
|
54
|
+
},
|
|
55
|
+
"./package.json": "./package.json"
|
|
56
|
+
},
|
|
51
57
|
"scripts": {
|
|
52
|
-
"clean": "
|
|
53
|
-
"build": "
|
|
54
|
-
"build:cjs": "tsc -p tsconfig.build.json --outDir dist/cjs --module commonjs",
|
|
55
|
-
"build:esm": "tsc -p tsconfig.build.json --outDir dist/esm --module es2015",
|
|
56
|
-
"build:rollup": "rollup -c",
|
|
58
|
+
"clean": "rm -rf dist lib",
|
|
59
|
+
"build": "tsdown",
|
|
57
60
|
"typedoc": "typedoc"
|
|
58
61
|
},
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"ditox": "3.2.0"
|
|
61
|
-
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
+
"ditox": "^3.2.0",
|
|
63
64
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
64
65
|
},
|
|
65
66
|
"devDependencies": {
|
|
@@ -68,6 +69,5 @@
|
|
|
68
69
|
"react": "19.0.0",
|
|
69
70
|
"react-dom": "19.0.0",
|
|
70
71
|
"react-test-renderer": "19.0.0"
|
|
71
|
-
}
|
|
72
|
-
"gitHead": "493e9ba9fcb36feea88e3948a23a4249a119d03e"
|
|
72
|
+
}
|
|
73
73
|
}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {render, renderHook} from '@testing-library/react';
|
|
6
|
-
import {Container, createContainer, Token, token} from 'ditox';
|
|
7
|
-
import React, {useEffect} from 'react';
|
|
1
|
+
import { render, renderHook } from '@testing-library/react';
|
|
2
|
+
import { Container, createContainer, Token, token } from 'ditox';
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
|
+
import { describe, expect, it, Mock, vi } from 'vitest';
|
|
8
5
|
import {
|
|
9
6
|
CustomDependencyContainer,
|
|
10
7
|
DependencyContainer,
|
|
11
8
|
} from './DependencyContainer';
|
|
12
|
-
import {useDependencyContainer} from './hooks';
|
|
9
|
+
import { useDependencyContainer } from './hooks';
|
|
13
10
|
|
|
14
11
|
describe('DependencyContainer', () => {
|
|
15
12
|
it('should provide a new container', () => {
|
|
16
|
-
const {result} = renderHook(useDependencyContainer, {
|
|
17
|
-
wrapper: ({children}) => (
|
|
13
|
+
const { result } = renderHook(useDependencyContainer, {
|
|
14
|
+
wrapper: ({ children }) => (
|
|
18
15
|
<DependencyContainer>{children}</DependencyContainer>
|
|
19
16
|
),
|
|
20
17
|
});
|
|
@@ -33,8 +30,8 @@ describe('DependencyContainer', () => {
|
|
|
33
30
|
container.bindValue(BAR, 'bar');
|
|
34
31
|
};
|
|
35
32
|
|
|
36
|
-
const {result} = renderHook(() => useDependencyContainer('strict'), {
|
|
37
|
-
wrapper: ({children}) => (
|
|
33
|
+
const { result } = renderHook(() => useDependencyContainer('strict'), {
|
|
34
|
+
wrapper: ({ children }) => (
|
|
38
35
|
<CustomDependencyContainer container={parentContainer}>
|
|
39
36
|
<DependencyContainer binder={binder}>{children}</DependencyContainer>
|
|
40
37
|
</CustomDependencyContainer>
|
|
@@ -56,8 +53,8 @@ describe('DependencyContainer', () => {
|
|
|
56
53
|
container.bindValue(BAR, 'bar');
|
|
57
54
|
};
|
|
58
55
|
|
|
59
|
-
const {result} = renderHook(() => useDependencyContainer('strict'), {
|
|
60
|
-
wrapper: ({children}) => (
|
|
56
|
+
const { result } = renderHook(() => useDependencyContainer('strict'), {
|
|
57
|
+
wrapper: ({ children }) => (
|
|
61
58
|
<CustomDependencyContainer container={parentContainer}>
|
|
62
59
|
<DependencyContainer root binder={binder}>
|
|
63
60
|
{children}
|
|
@@ -82,7 +79,7 @@ describe('DependencyContainer', () => {
|
|
|
82
79
|
const [FooMonitor, fooCallback] = createMonitor(FOO);
|
|
83
80
|
const [BarMonitor, barCallback] = createMonitor(BAR);
|
|
84
81
|
|
|
85
|
-
const {rerender} = render(
|
|
82
|
+
const { rerender } = render(
|
|
86
83
|
<CustomDependencyContainer container={parentContainer}>
|
|
87
84
|
<DependencyContainer root={false} binder={binder}>
|
|
88
85
|
<FooMonitor />
|
|
@@ -126,7 +123,7 @@ describe('DependencyContainer', () => {
|
|
|
126
123
|
const [FooMonitor, fooCallback] = createMonitor(FOO);
|
|
127
124
|
const [BarMonitor, barCallback] = createMonitor(BAR);
|
|
128
125
|
|
|
129
|
-
const {rerender} = render(
|
|
126
|
+
const { rerender } = render(
|
|
130
127
|
<CustomDependencyContainer container={parentContainer}>
|
|
131
128
|
<DependencyContainer root={true} binder={binder}>
|
|
132
129
|
<FooMonitor />
|
|
@@ -163,8 +160,8 @@ describe('DependencyContainer', () => {
|
|
|
163
160
|
|
|
164
161
|
const binder = (container: Container) => container.bindValue(FOO, 'foo');
|
|
165
162
|
|
|
166
|
-
const {result} = renderHook(() => useDependencyContainer('strict'), {
|
|
167
|
-
wrapper: ({children}) => (
|
|
163
|
+
const { result } = renderHook(() => useDependencyContainer('strict'), {
|
|
164
|
+
wrapper: ({ children }) => (
|
|
168
165
|
<DependencyContainer binder={binder}>{children}</DependencyContainer>
|
|
169
166
|
),
|
|
170
167
|
});
|
|
@@ -175,17 +172,17 @@ describe('DependencyContainer', () => {
|
|
|
175
172
|
it('should remove all bindings from a previous container in case "binder" is changed', () => {
|
|
176
173
|
const FOO = token('FOO');
|
|
177
174
|
|
|
178
|
-
const removeHandler1 =
|
|
175
|
+
const removeHandler1 = vi.fn();
|
|
179
176
|
const binder1 = (container: Container) =>
|
|
180
|
-
container.bindFactory(FOO, () => 'foo1', {onRemoved: removeHandler1});
|
|
177
|
+
container.bindFactory(FOO, () => 'foo1', { onRemoved: removeHandler1 });
|
|
181
178
|
|
|
182
|
-
const removeHandler2 =
|
|
179
|
+
const removeHandler2 = vi.fn();
|
|
183
180
|
const binder2 = (container: Container) =>
|
|
184
|
-
container.bindFactory(FOO, () => 'foo2', {onRemoved: removeHandler2});
|
|
181
|
+
container.bindFactory(FOO, () => 'foo2', { onRemoved: removeHandler2 });
|
|
185
182
|
|
|
186
183
|
const [Monitor, monitorCallback] = createMonitor(FOO);
|
|
187
184
|
|
|
188
|
-
const {rerender} = render(
|
|
185
|
+
const { rerender } = render(
|
|
189
186
|
<DependencyContainer binder={binder1}>
|
|
190
187
|
<Monitor />
|
|
191
188
|
</DependencyContainer>,
|
|
@@ -220,13 +217,13 @@ describe('DependencyContainer', () => {
|
|
|
220
217
|
it('should remove all bindings from a previous container in case "root" is changed', () => {
|
|
221
218
|
const FOO = token('FOO');
|
|
222
219
|
|
|
223
|
-
const removeHandler1 =
|
|
220
|
+
const removeHandler1 = vi.fn();
|
|
224
221
|
const binder1 = (container: Container) =>
|
|
225
|
-
container.bindFactory(FOO, () => 'foo1', {onRemoved: removeHandler1});
|
|
222
|
+
container.bindFactory(FOO, () => 'foo1', { onRemoved: removeHandler1 });
|
|
226
223
|
|
|
227
224
|
const [Monitor, monitorCallback] = createMonitor(FOO);
|
|
228
225
|
|
|
229
|
-
const {rerender} = render(
|
|
226
|
+
const { rerender } = render(
|
|
230
227
|
<DependencyContainer binder={binder1} root={false}>
|
|
231
228
|
<Monitor />
|
|
232
229
|
</DependencyContainer>,
|
|
@@ -261,8 +258,8 @@ describe('CustomDependencyContainer', () => {
|
|
|
261
258
|
const container = createContainer();
|
|
262
259
|
container.bindValue(FOO, 'foo');
|
|
263
260
|
|
|
264
|
-
const {result} = renderHook(useDependencyContainer, {
|
|
265
|
-
wrapper: ({children}) => (
|
|
261
|
+
const { result } = renderHook(useDependencyContainer, {
|
|
262
|
+
wrapper: ({ children }) => (
|
|
266
263
|
<CustomDependencyContainer container={container}>
|
|
267
264
|
{children}
|
|
268
265
|
</CustomDependencyContainer>
|
|
@@ -275,17 +272,17 @@ describe('CustomDependencyContainer', () => {
|
|
|
275
272
|
it('should not clean a custom container on rerender or unmount', () => {
|
|
276
273
|
const FOO = token('FOO');
|
|
277
274
|
|
|
278
|
-
const removeHandler1 =
|
|
275
|
+
const removeHandler1 = vi.fn();
|
|
279
276
|
const container1 = createContainer();
|
|
280
|
-
container1.bindFactory(FOO, () => 'foo1', {onRemoved: removeHandler1});
|
|
277
|
+
container1.bindFactory(FOO, () => 'foo1', { onRemoved: removeHandler1 });
|
|
281
278
|
|
|
282
|
-
const removeHandler2 =
|
|
279
|
+
const removeHandler2 = vi.fn();
|
|
283
280
|
const container2 = createContainer();
|
|
284
|
-
container2.bindFactory(FOO, () => 'foo2', {onRemoved: removeHandler2});
|
|
281
|
+
container2.bindFactory(FOO, () => 'foo2', { onRemoved: removeHandler2 });
|
|
285
282
|
|
|
286
283
|
const [Monitor, monitorCallback] = createMonitor(FOO);
|
|
287
284
|
|
|
288
|
-
const {rerender} = render(
|
|
285
|
+
const { rerender } = render(
|
|
289
286
|
<CustomDependencyContainer container={container1}>
|
|
290
287
|
<Monitor />
|
|
291
288
|
</CustomDependencyContainer>,
|
|
@@ -307,8 +304,8 @@ describe('CustomDependencyContainer', () => {
|
|
|
307
304
|
});
|
|
308
305
|
});
|
|
309
306
|
|
|
310
|
-
function createMonitor<T>(token: Token<T>): [() => null,
|
|
311
|
-
const callback =
|
|
307
|
+
function createMonitor<T>(token: Token<T>): [() => null, Mock] {
|
|
308
|
+
const callback = vi.fn();
|
|
312
309
|
|
|
313
310
|
const Monitor = () => {
|
|
314
311
|
const container = useDependencyContainer();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {Container} from 'ditox';
|
|
2
|
-
import {createContainer} from 'ditox';
|
|
1
|
+
import type { Container } from 'ditox';
|
|
2
|
+
import { createContainer } from 'ditox';
|
|
3
3
|
import React, {
|
|
4
4
|
createContext,
|
|
5
5
|
ReactElement,
|
|
@@ -66,7 +66,7 @@ export type DependencyContainerParams = {
|
|
|
66
66
|
export function DependencyContainer(
|
|
67
67
|
params: DependencyContainerParams,
|
|
68
68
|
): ReactElement {
|
|
69
|
-
const {children, root, binder} = params;
|
|
69
|
+
const { children, root, binder } = params;
|
|
70
70
|
const parentContainer = useContext(DependencyContainerContext);
|
|
71
71
|
|
|
72
72
|
const container = useMemo(() => {
|
|
@@ -96,7 +96,7 @@ export function DependencyContainer(
|
|
|
96
96
|
* ```tsx
|
|
97
97
|
* const container = useMemo(() => {
|
|
98
98
|
* return createContainer();
|
|
99
|
-
* }
|
|
99
|
+
* });
|
|
100
100
|
*
|
|
101
101
|
* return (
|
|
102
102
|
* <CustomDependencyContainer container={container}>
|
|
@@ -109,7 +109,7 @@ export function CustomDependencyContainer(params: {
|
|
|
109
109
|
children: ReactNode;
|
|
110
110
|
container: Container;
|
|
111
111
|
}): ReactElement {
|
|
112
|
-
const {children, container} = params;
|
|
112
|
+
const { children, container } = params;
|
|
113
113
|
|
|
114
114
|
return (
|
|
115
115
|
<DependencyContainerContext.Provider value={container}>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {renderHook} from '@testing-library/react';
|
|
1
|
+
import { renderHook } from '@testing-library/react';
|
|
2
2
|
import {
|
|
3
3
|
bindModule,
|
|
4
4
|
createContainer,
|
|
@@ -7,12 +7,13 @@ import {
|
|
|
7
7
|
token,
|
|
8
8
|
} from 'ditox';
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
10
|
+
import { describe, expect, it } from 'vitest';
|
|
11
|
+
import { CustomDependencyContainer } from './DependencyContainer';
|
|
12
|
+
import { DependencyModule } from './DependencyModule';
|
|
13
|
+
import { useDependency } from './hooks';
|
|
13
14
|
|
|
14
15
|
describe('DependencyModule', () => {
|
|
15
|
-
type TestModule = Module<{value: number}>;
|
|
16
|
+
type TestModule = Module<{ value: number }>;
|
|
16
17
|
|
|
17
18
|
const MODULE_TOKEN = token<TestModule>();
|
|
18
19
|
const VALUE_TOKEN = token<number>();
|
|
@@ -28,8 +29,8 @@ describe('DependencyModule', () => {
|
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
it('should bind a module and its provided values', () => {
|
|
31
|
-
const {result} = renderHook(() => useDependency(VALUE_TOKEN), {
|
|
32
|
-
wrapper: ({children}) => (
|
|
32
|
+
const { result } = renderHook(() => useDependency(VALUE_TOKEN), {
|
|
33
|
+
wrapper: ({ children }) => (
|
|
33
34
|
<DependencyModule module={MODULE}>{children}</DependencyModule>
|
|
34
35
|
),
|
|
35
36
|
});
|
|
@@ -42,8 +43,8 @@ describe('DependencyModule', () => {
|
|
|
42
43
|
bindModule(parent, MODULE);
|
|
43
44
|
const parentModule = parent.resolve(MODULE_TOKEN);
|
|
44
45
|
|
|
45
|
-
const {result} = renderHook(() => useDependency(MODULE_TOKEN), {
|
|
46
|
-
wrapper: ({children}) => (
|
|
46
|
+
const { result } = renderHook(() => useDependency(MODULE_TOKEN), {
|
|
47
|
+
wrapper: ({ children }) => (
|
|
47
48
|
<CustomDependencyContainer container={parent}>
|
|
48
49
|
<DependencyModule module={MODULE} scope="scoped">
|
|
49
50
|
{children}
|
package/src/DependencyModule.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {Module, ModuleDeclaration} from 'ditox';
|
|
2
|
-
import {bindModule} from 'ditox';
|
|
3
|
-
import React, {ReactElement, ReactNode, useCallback} from 'react';
|
|
1
|
+
import type { Module, ModuleDeclaration } from 'ditox';
|
|
2
|
+
import { bindModule } from 'ditox';
|
|
3
|
+
import React, { ReactElement, ReactNode, useCallback } from 'react';
|
|
4
4
|
import {
|
|
5
5
|
DependencyContainer,
|
|
6
6
|
DependencyContainerBinder,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
* @example
|
|
18
18
|
*
|
|
19
19
|
* ```tsx
|
|
20
|
-
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {
|
|
20
|
+
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};
|
|
21
21
|
*
|
|
22
22
|
* function App() {
|
|
23
23
|
* return (
|
|
@@ -33,10 +33,10 @@ export function DependencyModule(params: {
|
|
|
33
33
|
module: ModuleDeclaration<Module<Record<string, unknown>>>;
|
|
34
34
|
scope?: 'scoped' | 'singleton';
|
|
35
35
|
}): ReactElement {
|
|
36
|
-
const {children, module, scope} = params;
|
|
36
|
+
const { children, module, scope } = params;
|
|
37
37
|
|
|
38
38
|
const binder: DependencyContainerBinder = useCallback(
|
|
39
|
-
(container) => bindModule(container, module, {scope}),
|
|
39
|
+
(container) => bindModule(container, module, { scope }),
|
|
40
40
|
[module, scope],
|
|
41
41
|
);
|
|
42
42
|
|
package/src/hooks.test.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {renderHook} from '@testing-library/react';
|
|
2
|
-
import {createContainer, token} from 'ditox';
|
|
1
|
+
import { renderHook } from '@testing-library/react';
|
|
2
|
+
import { createContainer, token } from 'ditox';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { CustomDependencyContainer } from './DependencyContainer';
|
|
5
6
|
import {
|
|
6
7
|
useDependency,
|
|
7
8
|
useDependencyContainer,
|
|
@@ -9,15 +10,15 @@ import {
|
|
|
9
10
|
} from './hooks';
|
|
10
11
|
|
|
11
12
|
beforeAll(() => {
|
|
12
|
-
|
|
13
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
describe('useDependencyContainer()', () => {
|
|
16
17
|
it('should return a provided container in "strict" mode', () => {
|
|
17
18
|
const container = createContainer();
|
|
18
19
|
|
|
19
|
-
const {result} = renderHook(() => useDependencyContainer('strict'), {
|
|
20
|
-
wrapper: ({children}) => (
|
|
20
|
+
const { result } = renderHook(() => useDependencyContainer('strict'), {
|
|
21
|
+
wrapper: ({ children }) => (
|
|
21
22
|
<CustomDependencyContainer container={container}>
|
|
22
23
|
{children}
|
|
23
24
|
</CustomDependencyContainer>
|
|
@@ -36,8 +37,8 @@ describe('useDependencyContainer()', () => {
|
|
|
36
37
|
it('should return a provided container in "optional" mode', () => {
|
|
37
38
|
const container = createContainer();
|
|
38
39
|
|
|
39
|
-
const {result} = renderHook(() => useDependencyContainer(), {
|
|
40
|
-
wrapper: ({children}) => (
|
|
40
|
+
const { result } = renderHook(() => useDependencyContainer(), {
|
|
41
|
+
wrapper: ({ children }) => (
|
|
41
42
|
<CustomDependencyContainer container={container}>
|
|
42
43
|
{children}
|
|
43
44
|
</CustomDependencyContainer>
|
|
@@ -48,7 +49,7 @@ describe('useDependencyContainer()', () => {
|
|
|
48
49
|
});
|
|
49
50
|
|
|
50
51
|
it('should return "undefined" in "optional" mode in case a container is not provided', () => {
|
|
51
|
-
const {result} = renderHook(() => useDependencyContainer());
|
|
52
|
+
const { result } = renderHook(() => useDependencyContainer());
|
|
52
53
|
expect(result.current).toBeUndefined();
|
|
53
54
|
});
|
|
54
55
|
});
|
|
@@ -59,8 +60,8 @@ describe('useDependency()', () => {
|
|
|
59
60
|
const container = createContainer();
|
|
60
61
|
container.bindValue(TOKEN, 'value');
|
|
61
62
|
|
|
62
|
-
const {result} = renderHook(() => useDependency(TOKEN), {
|
|
63
|
-
wrapper: ({children}) => (
|
|
63
|
+
const { result } = renderHook(() => useDependency(TOKEN), {
|
|
64
|
+
wrapper: ({ children }) => (
|
|
64
65
|
<CustomDependencyContainer container={container}>
|
|
65
66
|
{children}
|
|
66
67
|
</CustomDependencyContainer>
|
|
@@ -84,7 +85,7 @@ describe('useDependency()', () => {
|
|
|
84
85
|
|
|
85
86
|
expect(() => {
|
|
86
87
|
renderHook(() => useDependency(TOKEN), {
|
|
87
|
-
wrapper: ({children}) => (
|
|
88
|
+
wrapper: ({ children }) => (
|
|
88
89
|
<CustomDependencyContainer container={container}>
|
|
89
90
|
{children}
|
|
90
91
|
</CustomDependencyContainer>
|
|
@@ -100,8 +101,8 @@ describe('useOptionalDependency()', () => {
|
|
|
100
101
|
const container = createContainer();
|
|
101
102
|
container.bindValue(TOKEN, 'value');
|
|
102
103
|
|
|
103
|
-
const {result} = renderHook(() => useOptionalDependency(TOKEN), {
|
|
104
|
-
wrapper: ({children}) => (
|
|
104
|
+
const { result } = renderHook(() => useOptionalDependency(TOKEN), {
|
|
105
|
+
wrapper: ({ children }) => (
|
|
105
106
|
<CustomDependencyContainer container={container}>
|
|
106
107
|
{children}
|
|
107
108
|
</CustomDependencyContainer>
|
|
@@ -114,7 +115,7 @@ describe('useOptionalDependency()', () => {
|
|
|
114
115
|
it('should return "undefined" in case a container is not provided', () => {
|
|
115
116
|
const TOKEN = token('token');
|
|
116
117
|
|
|
117
|
-
const {result} = renderHook(() => useOptionalDependency(TOKEN));
|
|
118
|
+
const { result } = renderHook(() => useOptionalDependency(TOKEN));
|
|
118
119
|
|
|
119
120
|
expect(result.current).toBeUndefined();
|
|
120
121
|
});
|
|
@@ -123,8 +124,8 @@ describe('useOptionalDependency()', () => {
|
|
|
123
124
|
const TOKEN = token('token');
|
|
124
125
|
const container = createContainer();
|
|
125
126
|
|
|
126
|
-
const {result} = renderHook(() => useOptionalDependency(TOKEN), {
|
|
127
|
-
wrapper: ({children}) => (
|
|
127
|
+
const { result } = renderHook(() => useOptionalDependency(TOKEN), {
|
|
128
|
+
wrapper: ({ children }) => (
|
|
128
129
|
<CustomDependencyContainer container={container}>
|
|
129
130
|
{children}
|
|
130
131
|
</CustomDependencyContainer>
|
package/src/hooks.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {Container, Token} from 'ditox';
|
|
2
|
-
import {useContext, useMemo} from 'react';
|
|
3
|
-
import {DependencyContainerContext} from './DependencyContainer';
|
|
1
|
+
import { Container, Token } from 'ditox';
|
|
2
|
+
import { useContext, useMemo } from 'react';
|
|
3
|
+
import { DependencyContainerContext } from './DependencyContainer';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @category Hook
|