ditox-react 3.1.0 → 3.3.0
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 +94 -26
- package/dist/index.cjs +175 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{browser/index.d.ts → index.d.cts} +51 -47
- package/dist/{umd/index.d.ts → index.d.ts} +51 -47
- 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 -22
- package/src/DependencyContainer.test.tsx +32 -35
- package/src/DependencyContainer.tsx +13 -13
- package/src/DependencyModule.test.tsx +10 -9
- package/src/DependencyModule.tsx +7 -7
- 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
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<img alt="lemon" src="https://raw.githubusercontent.com/mnasyrov/ditox/master/lemon.svg" width="120" />
|
|
4
4
|
|
|
5
|
-
**Dependency injection
|
|
5
|
+
**Dependency injection helpers for React.js**
|
|
6
6
|
|
|
7
7
|
Please see the documentation at [ditox.js.org](https://ditox.js.org)
|
|
8
8
|
|
|
9
|
-
[](https://www.npmjs.com/package/ditox)
|
|
9
|
+
[](https://www.npmjs.com/package/ditox-react)
|
|
10
10
|
[](https://github.com/mnasyrov/ditox/stargazers)
|
|
11
|
-
[](https://www.npmjs.com/package/ditox)
|
|
12
|
-
[](https://www.npmjs.com/package/ditox-react)
|
|
12
|
+
[](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
|
|
13
13
|
[](https://coveralls.io/github/mnasyrov/ditox)
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
@@ -20,14 +20,14 @@ You can use the following command to install this package:
|
|
|
20
20
|
npm install --save ditox-react
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
[jsdelivr.com](https://jsdelivr.com) CDN
|
|
23
|
+
Packages can be used as [UMD](https://github.com/umdjs/umd) modules. Use
|
|
24
|
+
[jsdelivr.com](https://jsdelivr.com) CDN to load
|
|
25
25
|
[ditox](https://www.jsdelivr.com/package/npm/ditox) and
|
|
26
26
|
[ditox-react](https://www.jsdelivr.com/package/npm/ditox-react):
|
|
27
27
|
|
|
28
28
|
```html
|
|
29
|
-
<script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js"
|
|
30
|
-
<script src="//cdn.jsdelivr.net/npm/ditox-react
|
|
29
|
+
<script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js"></script>
|
|
30
|
+
<script src="//cdn.jsdelivr.net/npm/ditox-react/dist/umd/index.js"></script>
|
|
31
31
|
<script>
|
|
32
32
|
const container = Ditox.createContainer();
|
|
33
33
|
// DitoxReact.useDependency(SOME_TOKEN);
|
|
@@ -40,20 +40,24 @@ The packages can be used as [UMD](https://github.com/umdjs/umd) modules. Use
|
|
|
40
40
|
in React apps:
|
|
41
41
|
|
|
42
42
|
- Components:
|
|
43
|
-
- `
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- `
|
|
43
|
+
- `DependencyContainer` — creates and provides a new container to React
|
|
44
|
+
children. Optionally binds dependencies via a binder callback. Can start a
|
|
45
|
+
new root container with `root` flag.
|
|
46
|
+
- `DependencyModule` — binds a dependency module to a new container (supports
|
|
47
|
+
`scope`: `singleton` (default) or `scoped`).
|
|
48
|
+
- `CustomDependencyContainer` — provides an existing dependency container.
|
|
47
49
|
- Hooks:
|
|
48
|
-
- `useDependencyContainer()`
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- `
|
|
52
|
-
|
|
50
|
+
- `useDependencyContainer(mode?)` — returns a provided dependency container.
|
|
51
|
+
With `mode = 'strict'` it throws if the container is not provided; by
|
|
52
|
+
default it returns `undefined` when not provided.
|
|
53
|
+
- `useDependency(token)` — resolves and returns a value by a specified token.
|
|
54
|
+
Throws if a container or the value is not found.
|
|
55
|
+
- `useOptionalDependency(token)` — returns a resolved value by a specified
|
|
56
|
+
token, or `undefined` if not found or not provided.
|
|
53
57
|
|
|
54
58
|
## Usage Examples
|
|
55
59
|
|
|
56
|
-
```
|
|
60
|
+
```tsx
|
|
57
61
|
import {token} from 'ditox';
|
|
58
62
|
import {
|
|
59
63
|
DependencyContainer,
|
|
@@ -62,8 +66,8 @@ import {
|
|
|
62
66
|
useOptionalDependency,
|
|
63
67
|
} from 'ditox-react';
|
|
64
68
|
|
|
65
|
-
const FOO_TOKEN = token();
|
|
66
|
-
const BAR_TOKEN = token();
|
|
69
|
+
const FOO_TOKEN = token<string>();
|
|
70
|
+
const BAR_TOKEN = token<string>();
|
|
67
71
|
|
|
68
72
|
function appDependencyBinder(container) {
|
|
69
73
|
container.bindValue(FOO_TOKEN, 'foo');
|
|
@@ -71,15 +75,15 @@ function appDependencyBinder(container) {
|
|
|
71
75
|
|
|
72
76
|
function App() {
|
|
73
77
|
return (
|
|
74
|
-
<DependencyContainer binder={appDependencyBinder}>
|
|
78
|
+
<DependencyContainer root binder={appDependencyBinder}>
|
|
75
79
|
<NestedComponent />
|
|
76
80
|
</DependencyContainer>
|
|
77
81
|
);
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
function NestedComponent() {
|
|
81
|
-
// Get access to the container
|
|
82
|
-
const container = useDependencyContainer();
|
|
85
|
+
// Get access to the container (optionally)
|
|
86
|
+
const container = useDependencyContainer(); // or useDependencyContainer('strict') to enforce presence
|
|
83
87
|
|
|
84
88
|
// Use a resolved value
|
|
85
89
|
const foo = useDependency(FOO_TOKEN);
|
|
@@ -95,21 +99,85 @@ function NestedComponent() {
|
|
|
95
99
|
}
|
|
96
100
|
```
|
|
97
101
|
|
|
102
|
+
### Providing an existing container
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import {createContainer, token} from 'ditox';
|
|
106
|
+
import {CustomDependencyContainer, useDependency} from 'ditox-react';
|
|
107
|
+
|
|
108
|
+
const GREETING_TOKEN = token<string>();
|
|
109
|
+
|
|
110
|
+
const container = createContainer();
|
|
111
|
+
container.bindValue(GREETING_TOKEN, 'Hello');
|
|
112
|
+
|
|
113
|
+
function App() {
|
|
114
|
+
return (
|
|
115
|
+
<CustomDependencyContainer container={container}>
|
|
116
|
+
<Greeting />
|
|
117
|
+
</CustomDependencyContainer>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function Greeting() {
|
|
122
|
+
const text = useDependency(GREETING_TOKEN);
|
|
123
|
+
return <>{text}</>;
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
98
127
|
## Dependency Modules
|
|
99
128
|
|
|
100
|
-
Dependency modules can be provided to the app with `<DependencyModule />`
|
|
101
|
-
component
|
|
129
|
+
Dependency modules can be provided to the app with the `<DependencyModule />`
|
|
130
|
+
component. You can also specify a binding scope (`singleton` by default or
|
|
131
|
+
`scoped`):
|
|
102
132
|
|
|
103
133
|
```tsx
|
|
104
134
|
function App() {
|
|
105
135
|
return (
|
|
106
|
-
<DependencyModule module={LOGGER_MODULE}>
|
|
136
|
+
<DependencyModule module={LOGGER_MODULE} scope="singleton">
|
|
107
137
|
<NestedComponent />
|
|
108
138
|
</DependencyModule>
|
|
109
139
|
);
|
|
110
140
|
}
|
|
111
141
|
```
|
|
112
142
|
|
|
143
|
+
## API Reference
|
|
144
|
+
|
|
145
|
+
- Components
|
|
146
|
+
|
|
147
|
+
- DependencyContainer(props)
|
|
148
|
+
- props.children: ReactNode — React children to wrap
|
|
149
|
+
- props.root?: boolean — if true, create a new root container that does not
|
|
150
|
+
inherit from any parent container
|
|
151
|
+
- props.binder?: (container: Container) => unknown — optional callback to
|
|
152
|
+
set up bindings for the newly created container
|
|
153
|
+
- Behavior: creates a new container linked to the parent container by
|
|
154
|
+
default; removes all bindings on unmount
|
|
155
|
+
- CustomDependencyContainer(props)
|
|
156
|
+
- props.children: ReactNode — React children to wrap
|
|
157
|
+
- props.container: Container — an existing container instance to provide
|
|
158
|
+
- DependencyModule(props)
|
|
159
|
+
- props.children: ReactNode — React children to wrap
|
|
160
|
+
- props.module: ModuleDeclaration — module to bind to a new container
|
|
161
|
+
- props.scope?: 'singleton' | 'scoped' — scope for the module bindings
|
|
162
|
+
(default: 'singleton')
|
|
163
|
+
|
|
164
|
+
- Hooks
|
|
165
|
+
- useDependencyContainer(mode?: 'optional' | 'strict')
|
|
166
|
+
- Returns the container. In 'strict' mode throws if not provided; in
|
|
167
|
+
optional mode returns undefined if not provided
|
|
168
|
+
- useDependency<T>(token: Token<T>): T
|
|
169
|
+
- Resolves and returns the value; throws if not bound or container is
|
|
170
|
+
missing
|
|
171
|
+
- useOptionalDependency<T>(token: Token<T>): T | undefined
|
|
172
|
+
- Returns the value if bound, otherwise undefined
|
|
173
|
+
|
|
174
|
+
Notes:
|
|
175
|
+
|
|
176
|
+
- A parent container (if provided higher in the tree) is used as the parent for
|
|
177
|
+
new containers created by DependencyContainer and DependencyModule, unless
|
|
178
|
+
root is set to true.
|
|
179
|
+
- All bindings made inside a DependencyContainer are removed on unmount.
|
|
180
|
+
|
|
113
181
|
---
|
|
114
182
|
|
|
115
183
|
This project is licensed under the
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
let ditox = require("ditox");
|
|
30
|
+
let react = require("react");
|
|
31
|
+
react = __toESM(react);
|
|
32
|
+
|
|
33
|
+
//#region src/DependencyContainer.tsx
|
|
34
|
+
const DependencyContainerContext = (0, react.createContext)(void 0);
|
|
35
|
+
/**
|
|
36
|
+
* Provides a new dependency container to React app
|
|
37
|
+
*
|
|
38
|
+
* This component creates a new container and provides it to React children.
|
|
39
|
+
*
|
|
40
|
+
* If a `binder` callback is specified, it will be called for the new container
|
|
41
|
+
* to bind it with dependencies.
|
|
42
|
+
*
|
|
43
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
44
|
+
* To create a root container specify `root` parameter as `true`,
|
|
45
|
+
* and the container will not depend on any parent container.
|
|
46
|
+
*
|
|
47
|
+
* @param params.binder - A callback which sets up bindings for the container.
|
|
48
|
+
* @param params.root - If `true` then a new container does not depend on any parent containers
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
*
|
|
52
|
+
* ```tsx
|
|
53
|
+
* const TOKEN = token();
|
|
54
|
+
*
|
|
55
|
+
* function appDependencyBinder(container: Container) {
|
|
56
|
+
* container.bindValue(TOKEN, 'value');
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* function App() {
|
|
60
|
+
* return (
|
|
61
|
+
* <DependencyContainer root binder={appDependencyBinder}>
|
|
62
|
+
* <NestedComponent />
|
|
63
|
+
* </DependencyContainer>
|
|
64
|
+
* );
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
69
|
+
function DependencyContainer(params) {
|
|
70
|
+
const { children, root, binder } = params;
|
|
71
|
+
const parentContainer = (0, react.useContext)(DependencyContainerContext);
|
|
72
|
+
const container = (0, react.useMemo)(() => {
|
|
73
|
+
const container = (0, ditox.createContainer)(root ? void 0 : parentContainer);
|
|
74
|
+
binder === null || binder === void 0 || binder(container);
|
|
75
|
+
return container;
|
|
76
|
+
}, [
|
|
77
|
+
binder,
|
|
78
|
+
parentContainer,
|
|
79
|
+
root
|
|
80
|
+
]);
|
|
81
|
+
(0, react.useEffect)(() => {
|
|
82
|
+
return () => container.removeAll();
|
|
83
|
+
}, [container]);
|
|
84
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainerContext.Provider, { value: container }, children);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Provides a custom dependency container to React app
|
|
88
|
+
*
|
|
89
|
+
* @param params.container - a custom container
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* const container = useMemo(() => {
|
|
94
|
+
* return createContainer();
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* return (
|
|
98
|
+
* <CustomDependencyContainer container={container}>
|
|
99
|
+
* {children}
|
|
100
|
+
* </CustomDependencyContainer>
|
|
101
|
+
* );
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
function CustomDependencyContainer(params) {
|
|
105
|
+
const { children, container } = params;
|
|
106
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainerContext.Provider, { value: container }, children);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/DependencyModule.tsx
|
|
111
|
+
/**
|
|
112
|
+
* Binds the module to a new dependency container.
|
|
113
|
+
*
|
|
114
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
115
|
+
*
|
|
116
|
+
* @param params.module - Module declaration for binding
|
|
117
|
+
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
*
|
|
121
|
+
* ```tsx
|
|
122
|
+
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};
|
|
123
|
+
*
|
|
124
|
+
* function App() {
|
|
125
|
+
* return (
|
|
126
|
+
* <DependencyModule module={LOGGER_MODULE}>
|
|
127
|
+
* <NestedComponent />
|
|
128
|
+
* </DependencyModule>
|
|
129
|
+
* );
|
|
130
|
+
* }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function DependencyModule(params) {
|
|
134
|
+
const { children, module, scope } = params;
|
|
135
|
+
const binder = (0, react.useCallback)((container) => (0, ditox.bindModule)(container, module, { scope }), [module, scope]);
|
|
136
|
+
return /* @__PURE__ */ react.default.createElement(DependencyContainer, { binder }, children);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/hooks.ts
|
|
141
|
+
/**
|
|
142
|
+
* @internal
|
|
143
|
+
*/
|
|
144
|
+
function useDependencyContainer(mode) {
|
|
145
|
+
const container = (0, react.useContext)(DependencyContainerContext);
|
|
146
|
+
if (!container && mode === "strict") throw new Error("Container is not provided by DependencyContainer component");
|
|
147
|
+
return container;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @category Hook
|
|
151
|
+
*
|
|
152
|
+
* Returns a dependency by token, or fails with an error.
|
|
153
|
+
*/
|
|
154
|
+
function useDependency(token) {
|
|
155
|
+
const container = useDependencyContainer("strict");
|
|
156
|
+
return (0, react.useMemo)(() => container.resolve(token), [container, token]);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* @category Hook
|
|
160
|
+
*
|
|
161
|
+
* Returns a dependency by token, or `undefined` in case the dependency is not provided.
|
|
162
|
+
*/
|
|
163
|
+
function useOptionalDependency(token) {
|
|
164
|
+
const container = useDependencyContainer();
|
|
165
|
+
return (0, react.useMemo)(() => container === null || container === void 0 ? void 0 : container.get(token), [container, token]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//#endregion
|
|
169
|
+
exports.CustomDependencyContainer = CustomDependencyContainer;
|
|
170
|
+
exports.DependencyContainer = DependencyContainer;
|
|
171
|
+
exports.DependencyModule = DependencyModule;
|
|
172
|
+
exports.useDependency = useDependency;
|
|
173
|
+
exports.useDependencyContainer = useDependencyContainer;
|
|
174
|
+
exports.useOptionalDependency = useOptionalDependency;
|
|
175
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,MAAa,sDACX,OACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDD,SAAgB,oBACd,QACc;CACd,MAAM,EAAE,UAAU,MAAM,WAAW;CACnC,MAAM,wCAA6B,2BAA2B;CAE9D,MAAM,qCAA0B;EAC9B,MAAM,uCAA4B,OAAO,SAAY,gBAAgB;AACrE,iDAAS,UAAU;AAEnB,SAAO;IACN;EAAC;EAAQ;EAAiB;EAAK,CAAC;AAEnC,4BAAgB;AACd,eAAa,UAAU,WAAW;IACjC,CAAC,UAAU,CAAC;AAEf,QACE,4CAAC,2BAA2B,YAAS,OAAO,aACzC,SACmC;;;;;;;;;;;;;;;;;;;;AAsB1C,SAAgB,0BAA0B,QAGzB;CACf,MAAM,EAAE,UAAU,cAAc;AAEhC,QACE,4CAAC,2BAA2B,YAAS,OAAO,aACzC,SACmC;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtF1C,SAAgB,iBAAiB,QAIhB;CACf,MAAM,EAAE,UAAU,QAAQ,UAAU;CAEpC,MAAM,iCACH,oCAAyB,WAAW,QAAQ,EAAE,OAAO,CAAC,EACvD,CAAC,QAAQ,MAAM,CAChB;AAED,QAAO,4CAAC,uBAA4B,UAAS,SAA+B;;;;;;;;ACrB9E,SAAgB,uBACd,MACuB;CACvB,MAAM,kCAAuB,2BAA2B;AAExD,KAAI,CAAC,aAAa,SAAS,SACzB,OAAM,IAAI,MACR,6DACD;AAGH,QAAO;;;;;;;AAQT,SAAgB,cAAiB,OAAoB;CACnD,MAAM,YAAY,uBAAuB,SAAS;AAElD,iCAD4B,UAAU,QAAQ,MAAM,EAAE,CAAC,WAAW,MAAM,CAAC;;;;;;;AAS3E,SAAgB,sBAAyB,OAAgC;CACvE,MAAM,YAAY,wBAAwB;AAE1C,uFAD4B,UAAW,IAAI,MAAM,EAAE,CAAC,WAAW,MAAM,CAAC"}
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import { Container,
|
|
2
|
-
import {
|
|
1
|
+
import { Container, Module, ModuleDeclaration, Token } from "ditox";
|
|
2
|
+
import { ReactElement, ReactNode } from "react";
|
|
3
3
|
|
|
4
|
+
//#region src/DependencyContainer.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* A callback for binding dependencies to a container
|
|
6
7
|
*/
|
|
7
8
|
type DependencyContainerBinder = (container: Container) => unknown;
|
|
8
9
|
/**
|
|
9
|
-
* Specifies
|
|
10
|
-
* @property binder - A callback which
|
|
10
|
+
* Specifies options for a new container:
|
|
11
|
+
* @property binder - A callback which sets up bindings for the container.
|
|
11
12
|
* @property root - If `true` then a new container does not depend on any parent containers
|
|
12
13
|
*/
|
|
13
14
|
type DependencyContainerParams = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
root?: boolean;
|
|
17
|
+
binder?: DependencyContainerBinder;
|
|
17
18
|
};
|
|
18
19
|
/**
|
|
19
20
|
* Provides a new dependency container to React app
|
|
20
21
|
*
|
|
21
|
-
* This component creates a new container and provides it
|
|
22
|
+
* This component creates a new container and provides it to React children.
|
|
22
23
|
*
|
|
23
|
-
* If `binder` callback is specified, it will be called for
|
|
24
|
-
* to
|
|
24
|
+
* If a `binder` callback is specified, it will be called for the new container
|
|
25
|
+
* to bind it with dependencies.
|
|
25
26
|
*
|
|
26
|
-
* If a parent container
|
|
27
|
-
*
|
|
27
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
28
|
+
* To create a root container specify `root` parameter as `true`,
|
|
28
29
|
* and the container will not depend on any parent container.
|
|
29
30
|
*
|
|
30
|
-
* @param params.binder - A callback which
|
|
31
|
+
* @param params.binder - A callback which sets up bindings for the container.
|
|
31
32
|
* @param params.root - If `true` then a new container does not depend on any parent containers
|
|
32
33
|
*
|
|
33
34
|
* @example
|
|
@@ -59,7 +60,7 @@ declare function DependencyContainer(params: DependencyContainerParams): ReactEl
|
|
|
59
60
|
* ```tsx
|
|
60
61
|
* const container = useMemo(() => {
|
|
61
62
|
* return createContainer();
|
|
62
|
-
* }
|
|
63
|
+
* });
|
|
63
64
|
*
|
|
64
65
|
* return (
|
|
65
66
|
* <CustomDependencyContainer container={container}>
|
|
@@ -69,10 +70,40 @@ declare function DependencyContainer(params: DependencyContainerParams): ReactEl
|
|
|
69
70
|
* ```
|
|
70
71
|
*/
|
|
71
72
|
declare function CustomDependencyContainer(params: {
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
children: ReactNode;
|
|
74
|
+
container: Container;
|
|
74
75
|
}): ReactElement;
|
|
75
|
-
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/DependencyModule.d.ts
|
|
78
|
+
/**
|
|
79
|
+
* Binds the module to a new dependency container.
|
|
80
|
+
*
|
|
81
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
82
|
+
*
|
|
83
|
+
* @param params.module - Module declaration for binding
|
|
84
|
+
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
*
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};
|
|
90
|
+
*
|
|
91
|
+
* function App() {
|
|
92
|
+
* return (
|
|
93
|
+
* <DependencyModule module={LOGGER_MODULE}>
|
|
94
|
+
* <NestedComponent />
|
|
95
|
+
* </DependencyModule>
|
|
96
|
+
* );
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function DependencyModule(params: {
|
|
101
|
+
children: ReactNode;
|
|
102
|
+
module: ModuleDeclaration<Module<Record<string, unknown>>>;
|
|
103
|
+
scope?: 'scoped' | 'singleton';
|
|
104
|
+
}): ReactElement;
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/hooks.d.ts
|
|
76
107
|
/**
|
|
77
108
|
* @category Hook
|
|
78
109
|
*
|
|
@@ -97,33 +128,6 @@ declare function useDependency<T>(token: Token<T>): T;
|
|
|
97
128
|
* Returns a dependency by token, or `undefined` in case the dependency is not provided.
|
|
98
129
|
*/
|
|
99
130
|
declare function useOptionalDependency<T>(token: Token<T>): T | undefined;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
*
|
|
104
|
-
* If a parent container is exist, it is connected to the current one by default.
|
|
105
|
-
*
|
|
106
|
-
* @param params.module - Module declaration for binding
|
|
107
|
-
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
*
|
|
111
|
-
* ```tsx
|
|
112
|
-
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {
|
|
113
|
-
*
|
|
114
|
-
* function App() {
|
|
115
|
-
* return (
|
|
116
|
-
* <DependencyModule module={LOGGER_MODULE}>
|
|
117
|
-
* <NestedComponent />
|
|
118
|
-
* </DependencyModule>
|
|
119
|
-
* );
|
|
120
|
-
* }
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
declare function DependencyModule(params: {
|
|
124
|
-
children: ReactNode;
|
|
125
|
-
module: ModuleDeclaration<Module<Record<string, unknown>>>;
|
|
126
|
-
scope?: 'scoped' | 'singleton';
|
|
127
|
-
}): ReactElement;
|
|
128
|
-
|
|
129
|
-
export { CustomDependencyContainer, DependencyContainer, DependencyContainerBinder, DependencyContainerParams, DependencyModule, useDependency, useDependencyContainer, useOptionalDependency };
|
|
131
|
+
//#endregion
|
|
132
|
+
export { CustomDependencyContainer, DependencyContainer, type DependencyContainerBinder, type DependencyContainerParams, DependencyModule, useDependency, useDependencyContainer, useOptionalDependency };
|
|
133
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import { Container,
|
|
2
|
-
import {
|
|
1
|
+
import { Container, Module, ModuleDeclaration, Token } from "ditox";
|
|
2
|
+
import React, { ReactElement, ReactNode } from "react";
|
|
3
3
|
|
|
4
|
+
//#region src/DependencyContainer.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* A callback for binding dependencies to a container
|
|
6
7
|
*/
|
|
7
8
|
type DependencyContainerBinder = (container: Container) => unknown;
|
|
8
9
|
/**
|
|
9
|
-
* Specifies
|
|
10
|
-
* @property binder - A callback which
|
|
10
|
+
* Specifies options for a new container:
|
|
11
|
+
* @property binder - A callback which sets up bindings for the container.
|
|
11
12
|
* @property root - If `true` then a new container does not depend on any parent containers
|
|
12
13
|
*/
|
|
13
14
|
type DependencyContainerParams = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
root?: boolean;
|
|
17
|
+
binder?: DependencyContainerBinder;
|
|
17
18
|
};
|
|
18
19
|
/**
|
|
19
20
|
* Provides a new dependency container to React app
|
|
20
21
|
*
|
|
21
|
-
* This component creates a new container and provides it
|
|
22
|
+
* This component creates a new container and provides it to React children.
|
|
22
23
|
*
|
|
23
|
-
* If `binder` callback is specified, it will be called for
|
|
24
|
-
* to
|
|
24
|
+
* If a `binder` callback is specified, it will be called for the new container
|
|
25
|
+
* to bind it with dependencies.
|
|
25
26
|
*
|
|
26
|
-
* If a parent container
|
|
27
|
-
*
|
|
27
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
28
|
+
* To create a root container specify `root` parameter as `true`,
|
|
28
29
|
* and the container will not depend on any parent container.
|
|
29
30
|
*
|
|
30
|
-
* @param params.binder - A callback which
|
|
31
|
+
* @param params.binder - A callback which sets up bindings for the container.
|
|
31
32
|
* @param params.root - If `true` then a new container does not depend on any parent containers
|
|
32
33
|
*
|
|
33
34
|
* @example
|
|
@@ -59,7 +60,7 @@ declare function DependencyContainer(params: DependencyContainerParams): ReactEl
|
|
|
59
60
|
* ```tsx
|
|
60
61
|
* const container = useMemo(() => {
|
|
61
62
|
* return createContainer();
|
|
62
|
-
* }
|
|
63
|
+
* });
|
|
63
64
|
*
|
|
64
65
|
* return (
|
|
65
66
|
* <CustomDependencyContainer container={container}>
|
|
@@ -69,10 +70,40 @@ declare function DependencyContainer(params: DependencyContainerParams): ReactEl
|
|
|
69
70
|
* ```
|
|
70
71
|
*/
|
|
71
72
|
declare function CustomDependencyContainer(params: {
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
children: ReactNode;
|
|
74
|
+
container: Container;
|
|
74
75
|
}): ReactElement;
|
|
75
|
-
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/DependencyModule.d.ts
|
|
78
|
+
/**
|
|
79
|
+
* Binds the module to a new dependency container.
|
|
80
|
+
*
|
|
81
|
+
* If a parent container exists, it is connected to the current one by default.
|
|
82
|
+
*
|
|
83
|
+
* @param params.module - Module declaration for binding
|
|
84
|
+
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
*
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {};
|
|
90
|
+
*
|
|
91
|
+
* function App() {
|
|
92
|
+
* return (
|
|
93
|
+
* <DependencyModule module={LOGGER_MODULE}>
|
|
94
|
+
* <NestedComponent />
|
|
95
|
+
* </DependencyModule>
|
|
96
|
+
* );
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function DependencyModule(params: {
|
|
101
|
+
children: ReactNode;
|
|
102
|
+
module: ModuleDeclaration<Module<Record<string, unknown>>>;
|
|
103
|
+
scope?: 'scoped' | 'singleton';
|
|
104
|
+
}): ReactElement;
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/hooks.d.ts
|
|
76
107
|
/**
|
|
77
108
|
* @category Hook
|
|
78
109
|
*
|
|
@@ -97,33 +128,6 @@ declare function useDependency<T>(token: Token<T>): T;
|
|
|
97
128
|
* Returns a dependency by token, or `undefined` in case the dependency is not provided.
|
|
98
129
|
*/
|
|
99
130
|
declare function useOptionalDependency<T>(token: Token<T>): T | undefined;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
*
|
|
104
|
-
* If a parent container is exist, it is connected to the current one by default.
|
|
105
|
-
*
|
|
106
|
-
* @param params.module - Module declaration for binding
|
|
107
|
-
* @param params.scope - Optional scope for binding: `singleton` (default) or `scoped`.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
*
|
|
111
|
-
* ```tsx
|
|
112
|
-
* const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {
|
|
113
|
-
*
|
|
114
|
-
* function App() {
|
|
115
|
-
* return (
|
|
116
|
-
* <DependencyModule module={LOGGER_MODULE}>
|
|
117
|
-
* <NestedComponent />
|
|
118
|
-
* </DependencyModule>
|
|
119
|
-
* );
|
|
120
|
-
* }
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
declare function DependencyModule(params: {
|
|
124
|
-
children: ReactNode;
|
|
125
|
-
module: ModuleDeclaration<Module<Record<string, unknown>>>;
|
|
126
|
-
scope?: 'scoped' | 'singleton';
|
|
127
|
-
}): ReactElement;
|
|
128
|
-
|
|
129
|
-
export { CustomDependencyContainer, DependencyContainer, DependencyContainerBinder, DependencyContainerParams, DependencyModule, useDependency, useDependencyContainer, useOptionalDependency };
|
|
131
|
+
//#endregion
|
|
132
|
+
export { CustomDependencyContainer, DependencyContainer, type DependencyContainerBinder, type DependencyContainerParams, DependencyModule, useDependency, useDependencyContainer, useOptionalDependency };
|
|
133
|
+
//# sourceMappingURL=index.d.ts.map
|