@adimm/x-injection-reactjs 0.1.0 → 0.1.2
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 +109 -65
- package/dist/index.cjs +96 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -17
- package/dist/index.d.ts +15 -17
- package/dist/index.js +97 -93
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,9 +88,16 @@ export const RandomNumberComponentModule = new ComponentProviderModule({
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
export function RandomNumberComponent(props: RandomNumberComponentProps) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
return (
|
|
92
|
+
<ModuleProvider
|
|
93
|
+
module={RandomNumberComponentModule}
|
|
94
|
+
render={() => {
|
|
95
|
+
const service = useInject(RandomNumberService);
|
|
96
|
+
|
|
97
|
+
return <h1>A random number: {service.generate()}</h1>;
|
|
98
|
+
}}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
94
101
|
}
|
|
95
102
|
```
|
|
96
103
|
|
|
@@ -113,13 +120,18 @@ export const RandomNumberComponentModule = new ComponentProviderModule({
|
|
|
113
120
|
});
|
|
114
121
|
|
|
115
122
|
export function RandomNumberComponent(props: RandomNumberComponentProps) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
<ModuleProvider
|
|
124
|
+
module={RandomNumberComponentModule}
|
|
125
|
+
render={() => {
|
|
126
|
+
// This hook is necessary in order to expose the component instance
|
|
127
|
+
// context up to the parent component
|
|
128
|
+
useExposeComponentModuleContext();
|
|
129
|
+
|
|
130
|
+
const service = useInject(RandomNumberService);
|
|
131
|
+
|
|
132
|
+
return <h1>A random number: {service.generate()}</h1>;
|
|
133
|
+
}}
|
|
134
|
+
/>;
|
|
123
135
|
}
|
|
124
136
|
|
|
125
137
|
////////////////////////////////////////
|
|
@@ -139,39 +151,46 @@ export const ParentServiceComponentModule = new ComponentProviderModule({
|
|
|
139
151
|
});
|
|
140
152
|
|
|
141
153
|
export function ParentComponent(props: ParentComponentProps) {
|
|
142
|
-
const service = useInject(ParentService);
|
|
143
|
-
|
|
144
154
|
return (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
155
|
+
<ModuleProvider
|
|
156
|
+
module={ParentServiceComponentModule}
|
|
157
|
+
render={() => {
|
|
158
|
+
const service = useInject(ParentService);
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<>
|
|
162
|
+
<TapIntoComponent
|
|
163
|
+
// By using the fluid syntax
|
|
164
|
+
contextInstance={() => ({
|
|
165
|
+
// If one of the children did expose the `RandomNumberComponentModule`
|
|
166
|
+
// module, we'll be able to access its instance.
|
|
167
|
+
tryGet: RandomNumberComponentModule,
|
|
168
|
+
thenDo: (ctx) => {
|
|
169
|
+
const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
|
|
170
|
+
|
|
171
|
+
service.injectRandomNumberService(randomNumberService_FromComponentInstance);
|
|
172
|
+
},
|
|
173
|
+
})}>
|
|
174
|
+
<RandomNumberComponent />
|
|
175
|
+
</TapIntoComponent>
|
|
176
|
+
|
|
177
|
+
<TapIntoComponent
|
|
178
|
+
// By accessing the entire underlying context map which may contain even more
|
|
179
|
+
// modules exposed by more children down the tree.
|
|
180
|
+
contextInstance={(ctxMap) => {
|
|
181
|
+
const ctx = ctxMap.get(RandomNumberComponentModule.toString());
|
|
182
|
+
if (!ctx) return;
|
|
183
|
+
|
|
184
|
+
const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
|
|
185
|
+
|
|
186
|
+
service.injectRandomNumberService(randomNumberService_FromComponentInstance);
|
|
187
|
+
}}>
|
|
188
|
+
<RandomNumberComponent />
|
|
189
|
+
</TapIntoComponent>
|
|
190
|
+
</>
|
|
191
|
+
);
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
175
194
|
);
|
|
176
195
|
}
|
|
177
196
|
```
|
|
@@ -183,32 +202,57 @@ or introduce unknown bugs, please use it carefully and with diligence!
|
|
|
183
202
|
|
|
184
203
|
```tsx
|
|
185
204
|
export function ParentComponent(props: ParentComponentProps) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
return (
|
|
206
|
+
<ModuleProvder
|
|
207
|
+
module={ParentServiceComponentModule}
|
|
208
|
+
render={() => {
|
|
209
|
+
// By using this hook, the component will always re-render whenever
|
|
210
|
+
// a child using a ProviderModule which is also imported into the parent ProviderModule,
|
|
211
|
+
// has mounted and rendered!
|
|
212
|
+
useRerenderOnChildrenModuleContextLoaded();
|
|
213
|
+
|
|
214
|
+
// We should use the `useInjectOnRender` instead of the default `useInject`
|
|
215
|
+
// hook which re-uses the same instance of the injected dependency
|
|
216
|
+
// between re-renders.
|
|
217
|
+
//
|
|
218
|
+
// Note: It may still work with the `useInject` hook too, but it may not be predictable.
|
|
219
|
+
const service = useInjectOnRender(ParentService);
|
|
220
|
+
|
|
221
|
+
// At this point the `service.randomNumberService` instance should be the one
|
|
222
|
+
// from the `RandomNumberComponent` below.
|
|
223
|
+
//
|
|
224
|
+
// Note: Expect during the 1st render cycle to not be the same instance as the one used by the child component!
|
|
225
|
+
// The `xInjection` container will still supply the correct provider to the
|
|
226
|
+
// constructor parameter, but it'll be a new transient instance.
|
|
227
|
+
console.log(service.randomNumberService.generate());
|
|
228
|
+
|
|
229
|
+
// As we are now using the `useRerenderOnChildrenModuleContextLoaded` hook
|
|
230
|
+
// there's no need anymore for the `TapIntoComponent` wrapper.
|
|
231
|
+
return <RandomNumberComponent />;
|
|
232
|
+
}}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
The `ModuleProvider` component also accepts the `children` prop, this means you can also use it like this:
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
export function Component() {
|
|
242
|
+
return <h1>Hello World!</h1>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function MyApp() {
|
|
246
|
+
return (
|
|
247
|
+
<ModuleProvider module={ComponentModule}>
|
|
248
|
+
<Component />
|
|
249
|
+
</ModuleProvider>
|
|
250
|
+
);
|
|
209
251
|
}
|
|
210
252
|
```
|
|
211
253
|
|
|
254
|
+
> **Note:** You don't have to wrap your entire application with a `ModuleProvider` which provides the `AppModule`, the global container is already available to use and all your `ComponentProviderModule` know ouf-of-the-box how to access it when you provide them with providers registered into the `AppModule`.
|
|
255
|
+
|
|
212
256
|
## Documentation
|
|
213
257
|
|
|
214
258
|
Comprehensive, auto-generated documentation is available at:
|
package/dist/index.cjs
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var e, t = Object.defineProperty, n = Object.getOwnPropertyDescriptor,
|
|
3
|
+
var e, t = Object.defineProperty, n = Object.getOwnPropertyDescriptor, r = Object.getOwnPropertyNames, o = Object.prototype.hasOwnProperty, i = (e, n) => t(e, "name", {
|
|
4
4
|
value: n,
|
|
5
5
|
configurable: !0
|
|
6
6
|
}), u = {};
|
|
7
7
|
|
|
8
8
|
((e, n) => {
|
|
9
|
-
for (var
|
|
10
|
-
get: n[
|
|
9
|
+
for (var r in n) t(e, r, {
|
|
10
|
+
get: n[r],
|
|
11
11
|
enumerable: !0
|
|
12
12
|
});
|
|
13
13
|
})(u, {
|
|
14
|
-
ComponentProviderModule: () =>
|
|
15
|
-
ModuleProvider: () =>
|
|
16
|
-
REACT_X_INJECTION_CONTEXT: () =>
|
|
17
|
-
REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: () =>
|
|
18
|
-
REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE: () => O,
|
|
14
|
+
ComponentProviderModule: () => q,
|
|
15
|
+
ModuleProvider: () => P,
|
|
16
|
+
REACT_X_INJECTION_CONTEXT: () => a,
|
|
17
|
+
REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: () => d,
|
|
19
18
|
TapIntoComponent: () => b,
|
|
20
19
|
useExposeComponentModuleContext: () => h,
|
|
21
|
-
useInject: () =>
|
|
22
|
-
useInjectMany: () =>
|
|
23
|
-
useInjectManyOnRender: () =>
|
|
24
|
-
useInjectOnRender: () =>
|
|
20
|
+
useInject: () => v,
|
|
21
|
+
useInjectMany: () => R,
|
|
22
|
+
useInjectManyOnRender: () => _,
|
|
23
|
+
useInjectOnRender: () => M,
|
|
25
24
|
useRerenderOnChildrenModuleContextLoaded: () => y
|
|
26
25
|
}), module.exports = (e = u, ((e, i, u, s) => {
|
|
27
|
-
if (i && "object" == typeof i || "function" == typeof i) for (let c of
|
|
26
|
+
if (i && "object" == typeof i || "function" == typeof i) for (let c of r(i)) o.call(e, c) || c === u || t(e, c, {
|
|
28
27
|
get: () => i[c],
|
|
29
28
|
enumerable: !(s = n(i, c)) || s.enumerable
|
|
30
29
|
});
|
|
@@ -33,101 +32,73 @@ var e, t = Object.defineProperty, n = Object.getOwnPropertyDescriptor, o = Objec
|
|
|
33
32
|
value: !0
|
|
34
33
|
}), e));
|
|
35
34
|
|
|
36
|
-
var s = require("react")
|
|
35
|
+
var s = require("@adimm/x-injection"), c = require("react"), a = (0, c.createContext)(s.AppModule), d = (0,
|
|
36
|
+
c.createContext)(new Map), l = require("react");
|
|
37
37
|
|
|
38
|
-
function
|
|
39
|
-
const t = (0,
|
|
38
|
+
function p(e) {
|
|
39
|
+
const t = (0, l.useRef)(null);
|
|
40
40
|
return null === t.current && (t.current = {
|
|
41
41
|
value: e()
|
|
42
42
|
}), t.current?.value;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
i(
|
|
45
|
+
i(p, "useOnce");
|
|
46
46
|
|
|
47
|
-
var
|
|
47
|
+
var m = require("react");
|
|
48
48
|
|
|
49
|
-
function
|
|
50
|
-
const t = (0,
|
|
51
|
-
|
|
52
|
-
n.current && (
|
|
53
|
-
n.current = !0),
|
|
54
|
-
|
|
49
|
+
function C(e) {
|
|
50
|
+
const t = (0, m.useRef)(void 0), n = (0, m.useRef)(!1), r = (0, m.useRef)(!1), [, o] = (0,
|
|
51
|
+
m.useState)(0);
|
|
52
|
+
n.current && (r.current = !0), (0, m.useEffect)((() => (n.current || (t.current = e(),
|
|
53
|
+
n.current = !0), o((e => e + 1)), () => {
|
|
54
|
+
r.current && t.current?.();
|
|
55
55
|
})), []);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
i(
|
|
58
|
+
i(C, "useEffectOnce");
|
|
59
59
|
|
|
60
|
-
var
|
|
61
|
-
C.createContext)(p.AppModule), f = (0, C.createContext)(new Map), O = (0, C.createContext)({
|
|
62
|
-
r: 0
|
|
63
|
-
}), x = require("react");
|
|
60
|
+
var f = require("react");
|
|
64
61
|
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
return React.createElement(m.Provider, {
|
|
70
|
-
value: i
|
|
71
|
-
}, React.createElement(O.Provider, {
|
|
72
|
-
value: {
|
|
73
|
-
r: 0
|
|
74
|
-
}
|
|
75
|
-
}, React.createElement(_, {
|
|
76
|
-
children: e,
|
|
77
|
-
module: i,
|
|
78
|
-
tryReInitModuleOnMount: n,
|
|
79
|
-
disposeModuleOnUnmount: o
|
|
80
|
-
})));
|
|
62
|
+
function O() {
|
|
63
|
+
const [, e] = (0, f.useState)(0);
|
|
64
|
+
return () => e((e => e + 1));
|
|
81
65
|
}
|
|
82
66
|
|
|
83
|
-
|
|
84
|
-
const r = (0, x.useContext)(f), i = (0, x.useContext)(O);
|
|
85
|
-
return d((() => {
|
|
86
|
-
const e = t.ctx.toNaked();
|
|
87
|
-
if (r) {
|
|
88
|
-
const e = t.ctx.toNaked().imports.map((e => r.get(e.toString())?.toString() === e.toString() ? r.get(e.toString()) : e));
|
|
89
|
-
e.length > 0 && (t.ctx.toNaked()._lazyInit({
|
|
90
|
-
...t.ctx.toNaked()._initialOptions,
|
|
91
|
-
imports: e
|
|
92
|
-
}), i.r++);
|
|
93
|
-
}
|
|
94
|
-
return e.isDisposed && n && e._lazyInit(n), () => {
|
|
95
|
-
o && !e.isDisposed && e._dispose();
|
|
96
|
-
};
|
|
97
|
-
})), e;
|
|
98
|
-
}
|
|
67
|
+
i(O, "useRerender");
|
|
99
68
|
|
|
100
|
-
|
|
101
|
-
|
|
69
|
+
var x = require("react");
|
|
70
|
+
|
|
71
|
+
function M(e, t) {
|
|
72
|
+
return (0, x.useContext)(a).ctx.get(e, t?.isOptional);
|
|
102
73
|
}
|
|
103
74
|
|
|
104
|
-
function
|
|
105
|
-
return
|
|
75
|
+
function v(e, t) {
|
|
76
|
+
return p((() => M(e, t)));
|
|
106
77
|
}
|
|
107
78
|
|
|
108
|
-
i(M, "
|
|
109
|
-
i(E, "useInject");
|
|
79
|
+
i(M, "useInjectOnRender"), i(v, "useInject");
|
|
110
80
|
|
|
111
81
|
var I = require("react");
|
|
112
82
|
|
|
113
|
-
function
|
|
114
|
-
return (0, I.useContext)(
|
|
83
|
+
function _({deps: e}) {
|
|
84
|
+
return (0, I.useContext)(a).ctx.getMany(...e);
|
|
115
85
|
}
|
|
116
86
|
|
|
117
|
-
function
|
|
118
|
-
return
|
|
87
|
+
function R({deps: e, options: t}) {
|
|
88
|
+
return p((() => _({
|
|
119
89
|
options: t,
|
|
120
90
|
deps: e
|
|
121
91
|
})));
|
|
122
92
|
}
|
|
123
93
|
|
|
124
|
-
i(
|
|
94
|
+
i(_, "useInjectManyOnRender"), i(R, "useInjectMany");
|
|
125
95
|
|
|
126
|
-
var
|
|
96
|
+
var E = require("react");
|
|
127
97
|
|
|
128
98
|
function h() {
|
|
129
|
-
const e = (0,
|
|
130
|
-
|
|
99
|
+
const e = (0, E.useContext)(a);
|
|
100
|
+
if (e.ctx.toNaked().isAppModule) return;
|
|
101
|
+
(0, E.useContext)(d).set(e.ctx.toString(), e.ctx);
|
|
131
102
|
}
|
|
132
103
|
|
|
133
104
|
i(h, "useExposeComponentModuleContext");
|
|
@@ -135,24 +106,58 @@ i(h, "useExposeComponentModuleContext");
|
|
|
135
106
|
var j = require("react");
|
|
136
107
|
|
|
137
108
|
function y() {
|
|
138
|
-
const e = (0, j.useContext)(
|
|
109
|
+
const e = (0, j.useContext)(a), t = (0, j.useContext)(d), n = O();
|
|
139
110
|
(0, j.useEffect)((() => {
|
|
140
|
-
|
|
141
|
-
|
|
111
|
+
const r = e.ctx.toNaked(), o = r.imports.map((e => {
|
|
112
|
+
const n = e.toString();
|
|
113
|
+
return t.get(n)?.toString() === n ? t.get(n) : e;
|
|
114
|
+
}));
|
|
115
|
+
o.length > 0 && (r._lazyInit({
|
|
116
|
+
...r._initialOptions,
|
|
117
|
+
imports: o
|
|
118
|
+
}), n());
|
|
119
|
+
}), [ e, t ]);
|
|
142
120
|
}
|
|
143
121
|
|
|
144
122
|
i(y, "useRerenderOnChildrenModuleContextLoaded");
|
|
145
123
|
|
|
146
|
-
var
|
|
124
|
+
var g = require("react");
|
|
125
|
+
|
|
126
|
+
function P({children: e, render: t, module: n, tryReInitModuleOnMount: r, disposeModuleOnUnmount: o}) {
|
|
127
|
+
const i = n.toNaked().isAppModule, u = (0, g.useCallback)((() => t?.()), []), s = {
|
|
128
|
+
ctx: i ? n : n.toNaked()._convertToContextualizedComponentInstance()
|
|
129
|
+
};
|
|
130
|
+
return React.createElement(a.Provider, {
|
|
131
|
+
value: s
|
|
132
|
+
}, React.createElement(N, {
|
|
133
|
+
children: e ?? React.createElement(u, null),
|
|
134
|
+
module: s,
|
|
135
|
+
tryReInitModuleOnMount: r,
|
|
136
|
+
disposeModuleOnUnmount: o
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function N({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUnmount: r = !1}) {
|
|
141
|
+
return C((() => {
|
|
142
|
+
const e = t.ctx.toNaked();
|
|
143
|
+
return e.isDisposed && n && e._lazyInit(n), () => {
|
|
144
|
+
r && !e.isDisposed && e._dispose();
|
|
145
|
+
};
|
|
146
|
+
})), e;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
i(P, "ModuleProvider"), i(N, "XInjectionChildrenRenderer");
|
|
150
|
+
|
|
151
|
+
var S = require("@adimm/x-injection"), q = class e extends S.ProviderModule {
|
|
147
152
|
static {
|
|
148
153
|
i(this, "ComponentProviderModule");
|
|
149
154
|
}
|
|
150
155
|
_initializedFromComponent;
|
|
151
156
|
_initialOptions;
|
|
152
157
|
constructor(e) {
|
|
153
|
-
super(
|
|
158
|
+
super(S.ProviderModuleHelpers.buildInternalConstructorParams({
|
|
154
159
|
...e,
|
|
155
|
-
defaultScope: e.defaultScope ??
|
|
160
|
+
defaultScope: e.defaultScope ?? S.InjectionScope.Request,
|
|
156
161
|
identifier: Symbol(`Component${e.identifier.description}`)
|
|
157
162
|
})), this._initializedFromComponent = !1, this._initialOptions = e;
|
|
158
163
|
}
|
|
@@ -164,8 +169,8 @@ var P = require("@adimm/x-injection"), S = class e extends P.ProviderModule {
|
|
|
164
169
|
}
|
|
165
170
|
_convertToContextualizedComponentInstance() {
|
|
166
171
|
if (this.isAppModule || this.isDisposed) return this;
|
|
167
|
-
const t = this._getProviders().map((e => (0,
|
|
168
|
-
scope:
|
|
172
|
+
const t = this._getProviders().map((e => (0, S.isClassOrFunction)(e) ? (0, S.isClass)(e) ? {
|
|
173
|
+
scope: S.InjectionScope.Singleton,
|
|
169
174
|
provide: e,
|
|
170
175
|
useClass: e
|
|
171
176
|
} : {
|
|
@@ -173,7 +178,7 @@ var P = require("@adimm/x-injection"), S = class e extends P.ProviderModule {
|
|
|
173
178
|
useValue: e
|
|
174
179
|
} : {
|
|
175
180
|
...e,
|
|
176
|
-
scope:
|
|
181
|
+
scope: S.InjectionScope.Singleton
|
|
177
182
|
})), n = new e({
|
|
178
183
|
...this._initialOptions,
|
|
179
184
|
providers: t
|
|
@@ -184,21 +189,21 @@ var P = require("@adimm/x-injection"), S = class e extends P.ProviderModule {
|
|
|
184
189
|
|
|
185
190
|
function b({children: e, contextInstance: t}) {
|
|
186
191
|
const n = (0, T.useMemo)((() => new Map), []);
|
|
187
|
-
return React.createElement(
|
|
192
|
+
return React.createElement(d.Provider, {
|
|
188
193
|
value: n
|
|
189
|
-
}, React.createElement(
|
|
194
|
+
}, React.createElement(k, {
|
|
190
195
|
contextInstance: t
|
|
191
196
|
}), e);
|
|
192
197
|
}
|
|
193
198
|
|
|
194
|
-
function
|
|
195
|
-
const t = (0, T.useContext)(
|
|
199
|
+
function k({contextInstance: e}) {
|
|
200
|
+
const t = (0, T.useContext)(d);
|
|
196
201
|
return (0, T.useEffect)((() => {
|
|
197
202
|
const n = e?.(t);
|
|
198
203
|
if (!n) return;
|
|
199
|
-
const
|
|
200
|
-
|
|
204
|
+
const r = t.get(n.tryGet.toString());
|
|
205
|
+
r && n.thenDo(r);
|
|
201
206
|
}), [ t ]), null;
|
|
202
207
|
}
|
|
203
208
|
|
|
204
|
-
i(b, "TapIntoComponent"), i(
|
|
209
|
+
i(b, "TapIntoComponent"), i(k, "CtxExposer");//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["export * from './core';\nexport type * from './types';\n","import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useContext, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n\n const moduleCtxReference = {\n ctx: useMemo(() => {\n return isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance();\n }, [children, module, tryReInitModuleOnMount, disposeModuleOnUnmount]),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["useOnce","fn","ref","useRef","current","value","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","import_react","import_react","REACT_X_INJECTION_CONTEXT","createContext","AppModule","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","import_react","ModuleProvider","children","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","moduleCtxReference","ctx","useMemo","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","import_react","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","import_react","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","import_react","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","import_x_injection","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","import_react","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/react-context.ts","../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/hooks/use-rerender.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["export * from './core';\nexport type * from './types';\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n","import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import { useState } from 'react';\n\nexport function useRerender(): () => void {\n const [, setRerender] = useState(0);\n\n return () => setRerender((x) => x + 1);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../react-context';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../react-context';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../react-context';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n if (componentModule.ctx.toNaked().isAppModule) return;\n\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect } from 'react';\n\nimport { useRerender } from '../../helpers';\nimport type { IComponentProviderModuleNaked } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../react-context';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const parentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n const rerenderComponent = useRerender();\n\n useEffect(() => {\n const parentModuleNaked = parentModule.ctx.toNaked();\n\n const contextualizedImportedModules = parentModuleNaked.imports.map((importedModule) => {\n const importedModuleId = importedModule.toString();\n\n const shouldReplaceImportedModuleWithContextualized =\n ctxMap.get(importedModuleId)?.toString() === importedModuleId;\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return ctxMap.get(importedModuleId) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n parentModuleNaked._lazyInit({\n ...parentModuleNaked._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n rerenderComponent();\n }\n }, [parentModule, ctxMap]);\n}\n","import { useCallback } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule } from '../../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../../react-context';\nimport type { ModuleProviderProps } from './models';\n\nexport function ModuleProvider({\n children,\n render,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n const Renderer = useCallback(() => render?.(), []);\n\n const moduleCtxReference = {\n ctx: isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance(),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <XInjectionChildrenRenderer\n children={children ?? <Renderer />}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Request,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../react-context';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["REACT_X_INJECTION_CONTEXT","createContext","AppModule","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","import_react","useOnce","fn","ref","useRef","current","value","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","import_react","useRerender","setRerender","useState","x","import_react","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","import_react","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","import_react","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","toNaked","isAppModule","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","toString","import_react","useRerenderOnChildrenModuleContextLoaded","parentModule","useContext","REACT_X_INJECTION_CONTEXT","ctxMap","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderComponent","useRerender","useEffect","parentModuleNaked","ctx","toNaked","contextualizedImportedModules","imports","map","importedModule","importedModuleId","toString","shouldReplaceImportedModuleWithContextualized","get","length","_lazyInit","_initialOptions","import_react","ModuleProvider","children","render","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","Renderer","useCallback","moduleCtxReference","ctx","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","XInjectionChildrenRenderer","useEffectOnce","moduleNaked","isDisposed","_lazyInit","_dispose","import_x_injection","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Request","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","import_react","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
2
1
|
import * as react from 'react';
|
|
2
|
+
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
interface IComponentProviderModuleNaked extends IComponentProviderModule {
|
|
@@ -33,6 +33,16 @@ interface IComponentProviderModule extends IProviderModule {
|
|
|
33
33
|
interface UseInjectSharedOptions {
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The `React.Context` value to be provided to a `React.Provider`.
|
|
38
|
+
*
|
|
39
|
+
* Its default value is a reference to the {@link AppModule}.
|
|
40
|
+
*/
|
|
41
|
+
declare const REACT_X_INJECTION_CONTEXT: react.Context<{
|
|
42
|
+
ctx: IComponentProviderModule;
|
|
43
|
+
}>;
|
|
44
|
+
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: react.Context<Map<string, IComponentProviderModule>>;
|
|
45
|
+
|
|
36
46
|
/**
|
|
37
47
|
* React `hook` which can be used inside a component to inject the required {@link provider | dependency}.
|
|
38
48
|
*
|
|
@@ -110,21 +120,9 @@ declare function useExposeComponentModuleContext(): void;
|
|
|
110
120
|
*/
|
|
111
121
|
declare function useRerenderOnChildrenModuleContextLoaded(): void;
|
|
112
122
|
|
|
113
|
-
/**
|
|
114
|
-
* The `React.Context` value to be provided to a `React.Provider`.
|
|
115
|
-
*
|
|
116
|
-
* Its default value is a reference to the {@link AppModule}.
|
|
117
|
-
*/
|
|
118
|
-
declare const REACT_X_INJECTION_CONTEXT: react.Context<{
|
|
119
|
-
ctx: IComponentProviderModule;
|
|
120
|
-
}>;
|
|
121
|
-
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: react.Context<Map<string, IComponentProviderModule>>;
|
|
122
|
-
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE: react.Context<{
|
|
123
|
-
r: number;
|
|
124
|
-
}>;
|
|
125
|
-
|
|
126
123
|
interface ModuleProviderProps {
|
|
127
|
-
children
|
|
124
|
+
children?: React.ReactNode;
|
|
125
|
+
render?: () => React.ReactNode;
|
|
128
126
|
/** The {@link IComponentProviderModule | ComponentProviderModule} instance which must be accessible by this component. */
|
|
129
127
|
module: IComponentProviderModule;
|
|
130
128
|
/**
|
|
@@ -150,7 +148,7 @@ interface ModuleProviderProps {
|
|
|
150
148
|
disposeModuleOnUnmount?: boolean;
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
declare function ModuleProvider({ children, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
declare function ModuleProvider({ children, render, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
|
|
154
152
|
|
|
155
153
|
/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
|
|
156
154
|
declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
|
|
@@ -242,4 +240,4 @@ interface WithComponentInstanceCtxFluidSyntax {
|
|
|
242
240
|
*/
|
|
243
241
|
declare function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps): react_jsx_runtime.JSX.Element;
|
|
244
242
|
|
|
245
|
-
export { ComponentProviderModule, type IComponentProviderModule, type IComponentProviderModuleNaked, ModuleProvider, REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,
|
|
243
|
+
export { ComponentProviderModule, type IComponentProviderModule, type IComponentProviderModuleNaked, ModuleProvider, REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT, TapIntoComponent, type TapIntoComponentContextProps, type UseInjectOptions, type UseInjectSharedOptions, type WithComponentInstanceCtxFluidSyntax, useExposeComponentModuleContext, useInject, useInjectMany, useInjectManyOnRender, useInjectOnRender, useRerenderOnChildrenModuleContextLoaded };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
2
1
|
import * as react from 'react';
|
|
2
|
+
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
interface IComponentProviderModuleNaked extends IComponentProviderModule {
|
|
@@ -33,6 +33,16 @@ interface IComponentProviderModule extends IProviderModule {
|
|
|
33
33
|
interface UseInjectSharedOptions {
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The `React.Context` value to be provided to a `React.Provider`.
|
|
38
|
+
*
|
|
39
|
+
* Its default value is a reference to the {@link AppModule}.
|
|
40
|
+
*/
|
|
41
|
+
declare const REACT_X_INJECTION_CONTEXT: react.Context<{
|
|
42
|
+
ctx: IComponentProviderModule;
|
|
43
|
+
}>;
|
|
44
|
+
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: react.Context<Map<string, IComponentProviderModule>>;
|
|
45
|
+
|
|
36
46
|
/**
|
|
37
47
|
* React `hook` which can be used inside a component to inject the required {@link provider | dependency}.
|
|
38
48
|
*
|
|
@@ -110,21 +120,9 @@ declare function useExposeComponentModuleContext(): void;
|
|
|
110
120
|
*/
|
|
111
121
|
declare function useRerenderOnChildrenModuleContextLoaded(): void;
|
|
112
122
|
|
|
113
|
-
/**
|
|
114
|
-
* The `React.Context` value to be provided to a `React.Provider`.
|
|
115
|
-
*
|
|
116
|
-
* Its default value is a reference to the {@link AppModule}.
|
|
117
|
-
*/
|
|
118
|
-
declare const REACT_X_INJECTION_CONTEXT: react.Context<{
|
|
119
|
-
ctx: IComponentProviderModule;
|
|
120
|
-
}>;
|
|
121
|
-
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT: react.Context<Map<string, IComponentProviderModule>>;
|
|
122
|
-
declare const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE: react.Context<{
|
|
123
|
-
r: number;
|
|
124
|
-
}>;
|
|
125
|
-
|
|
126
123
|
interface ModuleProviderProps {
|
|
127
|
-
children
|
|
124
|
+
children?: React.ReactNode;
|
|
125
|
+
render?: () => React.ReactNode;
|
|
128
126
|
/** The {@link IComponentProviderModule | ComponentProviderModule} instance which must be accessible by this component. */
|
|
129
127
|
module: IComponentProviderModule;
|
|
130
128
|
/**
|
|
@@ -150,7 +148,7 @@ interface ModuleProviderProps {
|
|
|
150
148
|
disposeModuleOnUnmount?: boolean;
|
|
151
149
|
}
|
|
152
150
|
|
|
153
|
-
declare function ModuleProvider({ children, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
declare function ModuleProvider({ children, render, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
|
|
154
152
|
|
|
155
153
|
/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
|
|
156
154
|
declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
|
|
@@ -242,4 +240,4 @@ interface WithComponentInstanceCtxFluidSyntax {
|
|
|
242
240
|
*/
|
|
243
241
|
declare function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps): react_jsx_runtime.JSX.Element;
|
|
244
242
|
|
|
245
|
-
export { ComponentProviderModule, type IComponentProviderModule, type IComponentProviderModuleNaked, ModuleProvider, REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,
|
|
243
|
+
export { ComponentProviderModule, type IComponentProviderModule, type IComponentProviderModuleNaked, ModuleProvider, REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT, TapIntoComponent, type TapIntoComponentContextProps, type UseInjectOptions, type UseInjectSharedOptions, type WithComponentInstanceCtxFluidSyntax, useExposeComponentModuleContext, useInject, useInjectMany, useInjectManyOnRender, useInjectOnRender, useRerenderOnChildrenModuleContextLoaded };
|
package/dist/index.js
CHANGED
|
@@ -3,134 +3,138 @@ var e = Object.defineProperty, t = (t, n) => e(t, "name", {
|
|
|
3
3
|
configurable: !0
|
|
4
4
|
});
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { AppModule as n } from "@adimm/x-injection";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import { createContext as o } from "react";
|
|
9
|
+
|
|
10
|
+
var r = o(n), i = o(new Map);
|
|
11
|
+
|
|
12
|
+
import { useRef as s } from "react";
|
|
13
|
+
|
|
14
|
+
function c(e) {
|
|
15
|
+
const t = s(null);
|
|
10
16
|
return null === t.current && (t.current = {
|
|
11
17
|
value: e()
|
|
12
18
|
}), t.current?.value;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
|
-
t(
|
|
21
|
+
t(c, "useOnce");
|
|
16
22
|
|
|
17
|
-
import { useEffect as
|
|
23
|
+
import { useEffect as u, useRef as a, useState as d } from "react";
|
|
18
24
|
|
|
19
|
-
function
|
|
20
|
-
const t =
|
|
21
|
-
n.current && (o.current = !0),
|
|
22
|
-
|
|
25
|
+
function p(e) {
|
|
26
|
+
const t = a(void 0), n = a(!1), o = a(!1), [, r] = d(0);
|
|
27
|
+
n.current && (o.current = !0), u((() => (n.current || (t.current = e(), n.current = !0),
|
|
28
|
+
r((e => e + 1)), () => {
|
|
23
29
|
o.current && t.current?.();
|
|
24
30
|
})), []);
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
t(
|
|
28
|
-
|
|
29
|
-
import { useContext as u } from "react";
|
|
30
|
-
|
|
31
|
-
import { AppModule as a } from "@adimm/x-injection";
|
|
32
|
-
|
|
33
|
-
import { createContext as d } from "react";
|
|
33
|
+
t(p, "useEffectOnce");
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
r: 0
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
import { useContext as f, useMemo as x } from "react";
|
|
35
|
+
import { useState as l } from "react";
|
|
40
36
|
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
return React.createElement(p.Provider, {
|
|
46
|
-
value: i
|
|
47
|
-
}, React.createElement(m.Provider, {
|
|
48
|
-
value: {
|
|
49
|
-
r: 0
|
|
50
|
-
}
|
|
51
|
-
}, React.createElement(v, {
|
|
52
|
-
children: e,
|
|
53
|
-
module: i,
|
|
54
|
-
tryReInitModuleOnMount: n,
|
|
55
|
-
disposeModuleOnUnmount: o
|
|
56
|
-
})));
|
|
37
|
+
function m() {
|
|
38
|
+
const [, e] = l(0);
|
|
39
|
+
return () => e((e => e + 1));
|
|
57
40
|
}
|
|
58
41
|
|
|
59
|
-
|
|
60
|
-
const r = f(l), i = f(m);
|
|
61
|
-
return c((() => {
|
|
62
|
-
const e = t.ctx.toNaked();
|
|
63
|
-
if (r) {
|
|
64
|
-
const e = t.ctx.toNaked().imports.map((e => r.get(e.toString())?.toString() === e.toString() ? r.get(e.toString()) : e));
|
|
65
|
-
e.length > 0 && (t.ctx.toNaked()._lazyInit({
|
|
66
|
-
...t.ctx.toNaked()._initialOptions,
|
|
67
|
-
imports: e
|
|
68
|
-
}), i.r++);
|
|
69
|
-
}
|
|
70
|
-
return e.isDisposed && n && e._lazyInit(n), () => {
|
|
71
|
-
o && !e.isDisposed && e._dispose();
|
|
72
|
-
};
|
|
73
|
-
})), e;
|
|
74
|
-
}
|
|
42
|
+
t(m, "useRerender");
|
|
75
43
|
|
|
76
|
-
|
|
77
|
-
|
|
44
|
+
import { useContext as f } from "react";
|
|
45
|
+
|
|
46
|
+
function x(e, t) {
|
|
47
|
+
return f(r).ctx.get(e, t?.isOptional);
|
|
78
48
|
}
|
|
79
49
|
|
|
80
|
-
function
|
|
81
|
-
return
|
|
50
|
+
function C(e, t) {
|
|
51
|
+
return c((() => x(e, t)));
|
|
82
52
|
}
|
|
83
53
|
|
|
84
|
-
t(
|
|
85
|
-
t(h, "useInject");
|
|
54
|
+
t(x, "useInjectOnRender"), t(C, "useInject");
|
|
86
55
|
|
|
87
|
-
import { useContext as
|
|
56
|
+
import { useContext as M } from "react";
|
|
88
57
|
|
|
89
|
-
function
|
|
90
|
-
return
|
|
58
|
+
function v({deps: e}) {
|
|
59
|
+
return M(r).ctx.getMany(...e);
|
|
91
60
|
}
|
|
92
61
|
|
|
93
|
-
function
|
|
94
|
-
return
|
|
62
|
+
function h({deps: e, options: t}) {
|
|
63
|
+
return c((() => v({
|
|
95
64
|
options: t,
|
|
96
65
|
deps: e
|
|
97
66
|
})));
|
|
98
67
|
}
|
|
99
68
|
|
|
100
|
-
t(
|
|
69
|
+
t(v, "useInjectManyOnRender"), t(h, "useInjectMany");
|
|
101
70
|
|
|
102
|
-
import { useContext as
|
|
71
|
+
import { useContext as I } from "react";
|
|
72
|
+
|
|
73
|
+
function O() {
|
|
74
|
+
const e = I(r);
|
|
75
|
+
if (e.ctx.toNaked().isAppModule) return;
|
|
76
|
+
I(i).set(e.ctx.toString(), e.ctx);
|
|
77
|
+
}
|
|
103
78
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
79
|
+
t(O, "useExposeComponentModuleContext");
|
|
80
|
+
|
|
81
|
+
import { useContext as R, useEffect as g } from "react";
|
|
82
|
+
|
|
83
|
+
function _() {
|
|
84
|
+
const e = R(r), t = R(i), n = m();
|
|
85
|
+
g((() => {
|
|
86
|
+
const o = e.ctx.toNaked(), r = o.imports.map((e => {
|
|
87
|
+
const n = e.toString();
|
|
88
|
+
return t.get(n)?.toString() === n ? t.get(n) : e;
|
|
89
|
+
}));
|
|
90
|
+
r.length > 0 && (o._lazyInit({
|
|
91
|
+
...o._initialOptions,
|
|
92
|
+
imports: r
|
|
93
|
+
}), n());
|
|
94
|
+
}), [ e, t ]);
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
t(
|
|
97
|
+
t(_, "useRerenderOnChildrenModuleContextLoaded");
|
|
110
98
|
|
|
111
|
-
import {
|
|
99
|
+
import { useCallback as y } from "react";
|
|
112
100
|
|
|
113
|
-
function
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
101
|
+
function E({children: e, render: t, module: n, tryReInitModuleOnMount: o, disposeModuleOnUnmount: i}) {
|
|
102
|
+
const s = n.toNaked().isAppModule, c = y((() => t?.()), []), u = {
|
|
103
|
+
ctx: s ? n : n.toNaked()._convertToContextualizedComponentInstance()
|
|
104
|
+
};
|
|
105
|
+
return React.createElement(r.Provider, {
|
|
106
|
+
value: u
|
|
107
|
+
}, React.createElement(S, {
|
|
108
|
+
children: e ?? React.createElement(c, null),
|
|
109
|
+
module: u,
|
|
110
|
+
tryReInitModuleOnMount: o,
|
|
111
|
+
disposeModuleOnUnmount: i
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function S({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUnmount: o = !1}) {
|
|
116
|
+
return p((() => {
|
|
117
|
+
const e = t.ctx.toNaked();
|
|
118
|
+
return e.isDisposed && n && e._lazyInit(n), () => {
|
|
119
|
+
o && !e.isDisposed && e._dispose();
|
|
120
|
+
};
|
|
121
|
+
})), e;
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
t(
|
|
124
|
+
t(E, "ModuleProvider"), t(S, "XInjectionChildrenRenderer");
|
|
121
125
|
|
|
122
|
-
import { InjectionScope as
|
|
126
|
+
import { InjectionScope as j, isClass as z, isClassOrFunction as P, ProviderModule as k, ProviderModuleHelpers as N } from "@adimm/x-injection";
|
|
123
127
|
|
|
124
|
-
var
|
|
128
|
+
var b = class e extends k {
|
|
125
129
|
static {
|
|
126
130
|
t(this, "ComponentProviderModule");
|
|
127
131
|
}
|
|
128
132
|
_initializedFromComponent;
|
|
129
133
|
_initialOptions;
|
|
130
134
|
constructor(e) {
|
|
131
|
-
super(
|
|
135
|
+
super(N.buildInternalConstructorParams({
|
|
132
136
|
...e,
|
|
133
|
-
defaultScope: e.defaultScope ??
|
|
137
|
+
defaultScope: e.defaultScope ?? j.Request,
|
|
134
138
|
identifier: Symbol(`Component${e.identifier.description}`)
|
|
135
139
|
})), this._initializedFromComponent = !1, this._initialOptions = e;
|
|
136
140
|
}
|
|
@@ -142,8 +146,8 @@ var D = class e extends N {
|
|
|
142
146
|
}
|
|
143
147
|
_convertToContextualizedComponentInstance() {
|
|
144
148
|
if (this.isAppModule || this.isDisposed) return this;
|
|
145
|
-
const t = this._getProviders().map((e =>
|
|
146
|
-
scope:
|
|
149
|
+
const t = this._getProviders().map((e => P(e) ? z(e) ? {
|
|
150
|
+
scope: j.Singleton,
|
|
147
151
|
provide: e,
|
|
148
152
|
useClass: e
|
|
149
153
|
} : {
|
|
@@ -151,7 +155,7 @@ var D = class e extends N {
|
|
|
151
155
|
useValue: e
|
|
152
156
|
} : {
|
|
153
157
|
...e,
|
|
154
|
-
scope:
|
|
158
|
+
scope: j.Singleton
|
|
155
159
|
})), n = new e({
|
|
156
160
|
...this._initialOptions,
|
|
157
161
|
providers: t
|
|
@@ -160,19 +164,19 @@ var D = class e extends N {
|
|
|
160
164
|
}
|
|
161
165
|
};
|
|
162
166
|
|
|
163
|
-
import { useContext as
|
|
167
|
+
import { useContext as D, useEffect as w, useMemo as A } from "react";
|
|
164
168
|
|
|
165
|
-
function
|
|
166
|
-
const n =
|
|
167
|
-
return React.createElement(
|
|
169
|
+
function F({children: e, contextInstance: t}) {
|
|
170
|
+
const n = A((() => new Map), []);
|
|
171
|
+
return React.createElement(i.Provider, {
|
|
168
172
|
value: n
|
|
169
|
-
}, React.createElement(
|
|
173
|
+
}, React.createElement(T, {
|
|
170
174
|
contextInstance: t
|
|
171
175
|
}), e);
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
function
|
|
175
|
-
const t =
|
|
178
|
+
function T({contextInstance: e}) {
|
|
179
|
+
const t = D(i);
|
|
176
180
|
return w((() => {
|
|
177
181
|
const n = e?.(t);
|
|
178
182
|
if (!n) return;
|
|
@@ -181,6 +185,6 @@ function A({contextInstance: e}) {
|
|
|
181
185
|
}), [ t ]), null;
|
|
182
186
|
}
|
|
183
187
|
|
|
184
|
-
t(
|
|
188
|
+
t(F, "TapIntoComponent"), t(T, "CtxExposer");
|
|
185
189
|
|
|
186
|
-
export {
|
|
190
|
+
export { b as ComponentProviderModule, E as ModuleProvider, r as REACT_X_INJECTION_CONTEXT, i as REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT, F as TapIntoComponent, O as useExposeComponentModuleContext, C as useInject, h as useInjectMany, v as useInjectManyOnRender, x as useInjectOnRender, _ as useRerenderOnChildrenModuleContextLoaded };//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useContext, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n\n const moduleCtxReference = {\n ctx: useMemo(() => {\n return isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance();\n }, [children, module, tryReInitModuleOnMount, disposeModuleOnUnmount]),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":";;;;AAAA,SAASA,cAAc;AAEhB,SAASC,QAAWC,IAAW;AACpC,QAAMC,MAAMC,OAA4B,IAAA;AAExC,MAAID,IAAIE,YAAY,MAAM;AACxBF,QAAIE,UAAU;MAAEC,OAAOJ,GAAAA;IAAK;EAC9B;AAEA,SAAOC,IAAIE,SAASC;AACtB;AARgBL;;;ACFhB,SAASM,WAAWC,UAAAA,SAAQC,gBAAgB;AAKrC,SAASC,cAAcC,QAAkC;AAC9D,QAAMC,cAAcC,QAA6BC,MAAAA;AACjD,QAAMC,eAAeF,QAAO,KAAA;AAC5B,QAAMG,oBAAoBH,QAAO,KAAA;AACjC,QAAM,CAAA,EAAGI,aAAAA,IAAiBC,SAAS,CAAA;AAEnC,MAAIH,aAAaI,QAASH,mBAAkBG,UAAU;AAEtDC,YAAU,MAAA;AAER,QAAI,CAACL,aAAaI,SAAS;AACzBP,kBAAYO,UAAUR,OAAAA;AACtBI,mBAAaI,UAAU;IACzB;AAGAF,kBAAc,CAACI,MAAMA,IAAI,CAAA;AAEzB,WAAO,MAAA;AAGL,UAAI,CAACL,kBAAkBG,QAAS;AAEhCP,kBAAYO,UAAO;IACrB;EACF,GAAG,CAAA,CAAE;AACP;AA1BgBT;;;ACJhB,SAASY,cAAAA,mBAAkB;;;ACD3B,SAASC,iBAAiB;AAC1B,SAASC,qBAAqB;AASvB,IAAMC,4BAA4BD,cAAiDD,SAAAA;AAEnF,IAAMG,qDAAqDF,cAChE,oBAAIG,IAAAA,CAAAA;AAGC,IAAMC,6DAA6DJ,cAA6B;EAAEK,GAAG;AAAE,CAAA;;;AChB9G,SAASC,YAAYC,eAAe;AAY7B,SAASC,eAAe,EAC7BC,UACAC,QACAC,wBACAC,uBAAsB,GACF;AACpB,QAAMC,cAAcH,OAAOI,QAAO,EAAGD;AAErC,QAAME,qBAAqB;IACzBC,KAAKC,QAAQ,MAAA;AACX,aAAOJ,cAAcH,SAASA,OAAOI,QAAO,EAAGI,0CAAyC;IAC1F,GAAG;MAACT;MAAUC;MAAQC;MAAwBC;KAAuB;EACvE;AAEA,SACE,sBAAA,cAACO,0BAA0BC,UAAQ;IAACC,OAAON;KACzC,sBAAA,cAACO,2DAA2DF,UAAQ;IAACC,OAAO;MAAEE,GAAG;IAAE;KACjF,sBAAA,cAACC,4BAAAA;IACCf;IACAC,QAAQK;IACRJ;IACAC;;AAKV;AA1BgBJ;AA4BhB,SAASgB,2BAA2B,EAClCf,UACAC,QACAC,wBACAC,yBAAyB,MAAK,GACwD;AACtF,QAAMa,0BAA0BC,WAAWC,kDAAAA;AAC3C,QAAMC,oBAAoBF,WAAWJ,0DAAAA;AAUrCO,gBAAc,MAAA;AAGZ,UAAMC,cAAcpB,OAAOM,IAAIF,QAAO;AAEtC,QAAIW,yBAAyB;AAC3B,YAAMM,gCAAgCrB,OAAOM,IAAIF,QAAO,EAAGkB,QAAQC,IAAI,CAACC,mBAAAA;AACtE,cAAMC,gDACJV,wBAAwBW,IAAIF,eAAeG,SAAQ,CAAA,GAAKA,SAAAA,MAAeH,eAAeG,SAAQ;AAGhG,YAAI,CAACF,8CACH,QAAOD;AAET,eAAOT,wBAAwBW,IAAIF,eAAeG,SAAQ,CAAA;MAC5D,CAAA;AAEA,UAAIN,8BAA8BO,SAAS,GAAG;AAC5C5B,eAAOM,IAAIF,QAAO,EAAGyB,UAAU;UAC7B,GAAG7B,OAAOM,IAAIF,QAAO,EAAG0B;UACxBR,SAASD;QACX,CAAA;AAGAH,0BAAkBL;MACpB;IACF;AAGA,QAAIO,YAAYW,cAAc9B,wBAAwB;AAEpDmB,kBAAYS,UAAU5B,sBAAAA;IACxB;AAEA,WAAO,MAAA;AAGL,UAAI,CAACC,0BAA0BkB,YAAYW,WAAY;AAEvDX,kBAAYY,SAAQ;IACtB;EACF,CAAA;AAEA,SAAOjC;AACT;AA7DSe;;;AFvBF,SAASmB,kBAAqBC,UAA4BC,SAA0B;AACzF,QAAMC,kBAAkBC,YAAWC,yBAAAA;AAEnC,SAAOF,gBAAgBG,IAAIC,IAAIN,UAAUC,SAASM,UAAAA;AACpD;AAJgBR;;;AGDT,SAASS,UAAaC,UAA4BC,SAA0B;AACjF,SAAOC,QAAQ,MAAMC,kBAAkBH,UAAUC,OAAAA,CAAAA;AACnD;AAFgBF;;;ACVhB,SAASK,cAAAA,mBAAkB;AAepB,SAASC,sBAAqF,EACnGC,KAAI,GAIL;AACC,QAAMC,kBAAkBC,YAAWC,yBAAAA;AAEnC,SAAOF,gBAAgBG,IAAIC,QAAO,GAAIL,IAAAA;AACxC;AATgBD;;;ACLT,SAASO,cAA6E,EAC3FC,MACAC,QAAO,GAIR;AACC,SAAOC,QAAQ,MAAMC,sBAAsB;IAAEF;IAASD;EAAK,CAAA,CAAA;AAC7D;AARgBD;;;AChBhB,SAASK,cAAAA,mBAAkB;AAIpB,SAASC,kCAAAA;AACd,QAAMC,kBAAkBC,YAAWC,yBAAAA;AACnC,QAAMC,UAAUF,YAAWG,kDAAAA;AAE3BD,UAAQE,IAAIL,gBAAgBM,IAAIC,SAAQ,GAAIP,gBAAgBM,GAAG;AACjE;AALgBP;;;ACJhB,SAASS,cAAAA,aAAYC,aAAAA,YAAWC,YAAAA,iBAAgB;AAiBzC,SAASC,2CAAAA;AACd,QAAMC,oBAAoBC,YAAWC,0DAAAA;AACrC,QAAM,CAAA,EAAGC,WAAAA,IAAeC,UAAS,CAAA;AAEjCC,EAAAA,WAAU,MAAA;AACRF,gBAAY,CAACG,MAAMA,IAAI,CAAA;EACzB,GAAG;IAACN,kBAAkBO;GAAE;AAC1B;AAPgBR;;;ACjBhB,SACES,gBACAC,SACAC,mBACAC,gBACAC,6BAMK;AAKA,IAAMC,0BAAN,MAAMA,iCAAgCC,eAAAA;EAhB7C,OAgB6CA;;;EACxBC;EACAC;EAEnBC,YAAYC,SAAgC;AAC1C,UACEC,sBAAsBC,+BAA+B;MACnD,GAAGF;;;MAGHG,cAAcH,QAAQG,gBAAgBC,eAAeC;MACrDC,YAAYC,OAAO,YAAYP,QAAQM,WAAWE,WAAW,EAAE;IACjE,CAAA,CAAA;AAGF,SAAKX,4BAA4B;AACjC,SAAKC,kBAAkBE;EACzB;EAESS,UAAgE;AACvE,WAAO;EACT;;EAGAC,UAAgB;AACd,SAAKC,SAAQ;EACf;;;;;;;EAQUC,4CAAsE;AAC9E,QAAI,KAAKC,eAAe,KAAKC,WAAY,QAAO;AAEhD,UAAMC,0BAA0B,KAAKC,cAAa,EAAGC,IAAI,CAACC,aAAAA;AACxD,UAAI,CAACC,kBAAkBD,QAAAA,GAAW;AAChC,eAAO;UACL,GAAGA;UACHE,OAAOhB,eAAeiB;QACxB;MACF;AAEA,UAAIC,QAAQJ,QAAAA,GAAW;AACrB,eAAO;UACLE,OAAOhB,eAAeiB;UACtBE,SAASL;UACTM,UAAUN;QACZ;MACF;AAEA,aAAO;QACLK,SAASL;QACTO,UAAUP;MACZ;IACF,CAAA;AAEA,UAAMQ,kBAAkB,IAAI/B,yBAAwB;MAClD,GAAG,KAAKG;MACR6B,WAAWZ;IACb,CAAA;AAGAW,oBAAgB7B,4BAA4B;AAE5C,WAAO6B;EACT;AACF;;;ACrFA,SAASE,cAAAA,aAAYC,aAAAA,YAAWC,WAAAA,gBAAe;AAaxC,SAASC,iBAAiB,EAAEC,UAAUC,gBAAe,GAAgC;AAC1F,QAAMC,mBAAmBC,SAAQ,MAAM,oBAAIC,IAAAA,GAAO,CAAA,CAAE;AAEpD,SACE,sBAAA,cAACC,mDAAmDC,UAAQ;IAACC,OAAOL;KAClE,sBAAA,cAACM,YAAAA;IAAWP;MACXD,QAAAA;AAGP;AATgBD;AAWhB,SAASS,WAAW,EAAEP,gBAAe,GAAoD;AACvF,QAAMQ,SAASC,YAAWL,kDAAAA;AAE1BM,EAAAA,WAAU,MAAA;AACR,UAAMC,cAAcX,kBAAkBQ,MAAAA;AACtC,QAAI,CAACG,YAAa;AAElB,UAAMC,YAAYJ,OAAOK,IAAIF,YAAYG,OAAOC,SAAQ,CAAA;AAExD,QAAI,CAACH,UAAW;AAEhBD,gBAAYK,OAAOJ,SAAAA;EACrB,GAAG;IAACJ;GAAO;AAEX,SAAO;AACT;AAfSD;","names":["useRef","useOnce","fn","ref","useRef","current","value","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContext","AppModule","createContext","REACT_X_INJECTION_CONTEXT","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","useContext","useMemo","ModuleProvider","children","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","moduleCtxReference","ctx","useMemo","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","useContext","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","useContext","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","useContext","useEffect","useState","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","InjectionScope","isClass","isClassOrFunction","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","useContext","useEffect","useMemo","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/react-context.ts","../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/hooks/use-rerender.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n","import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import { useState } from 'react';\n\nexport function useRerender(): () => void {\n const [, setRerender] = useState(0);\n\n return () => setRerender((x) => x + 1);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../react-context';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../react-context';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../react-context';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n if (componentModule.ctx.toNaked().isAppModule) return;\n\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect } from 'react';\n\nimport { useRerender } from '../../helpers';\nimport type { IComponentProviderModuleNaked } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../react-context';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const parentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n const rerenderComponent = useRerender();\n\n useEffect(() => {\n const parentModuleNaked = parentModule.ctx.toNaked();\n\n const contextualizedImportedModules = parentModuleNaked.imports.map((importedModule) => {\n const importedModuleId = importedModule.toString();\n\n const shouldReplaceImportedModuleWithContextualized =\n ctxMap.get(importedModuleId)?.toString() === importedModuleId;\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return ctxMap.get(importedModuleId) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n parentModuleNaked._lazyInit({\n ...parentModuleNaked._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n rerenderComponent();\n }\n }, [parentModule, ctxMap]);\n}\n","import { useCallback } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule } from '../../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../../react-context';\nimport type { ModuleProviderProps } from './models';\n\nexport function ModuleProvider({\n children,\n render,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n const Renderer = useCallback(() => render?.(), []);\n\n const moduleCtxReference = {\n ctx: isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance(),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <XInjectionChildrenRenderer\n children={children ?? <Renderer />}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Request,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../react-context';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["AppModule","createContext","REACT_X_INJECTION_CONTEXT","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","useRef","useOnce","fn","ref","useRef","current","value","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useState","useRerender","setRerender","useState","x","useContext","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","useContext","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","useContext","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","toNaked","isAppModule","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","toString","useContext","useEffect","useRerenderOnChildrenModuleContextLoaded","parentModule","useContext","REACT_X_INJECTION_CONTEXT","ctxMap","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderComponent","useRerender","useEffect","parentModuleNaked","ctx","toNaked","contextualizedImportedModules","imports","map","importedModule","importedModuleId","toString","shouldReplaceImportedModuleWithContextualized","get","length","_lazyInit","_initialOptions","useCallback","ModuleProvider","children","render","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","Renderer","useCallback","moduleCtxReference","ctx","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","XInjectionChildrenRenderer","useEffectOnce","moduleNaked","isDisposed","_lazyInit","_dispose","InjectionScope","isClass","isClassOrFunction","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Request","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","useContext","useEffect","useMemo","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adimm/x-injection-reactjs",
|
|
3
3
|
"description": "ReactJS integration of the `xInjection` library.",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"author": "Adi-Marian Mutu",
|
|
6
6
|
"homepage": "https://github.com/AdiMarianMutu/x-injection-reactjs#readme",
|
|
7
7
|
"bugs": "https://github.com/AdiMarianMutu/x-injection-reactjs/issues",
|