@adimm/x-injection-reactjs 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -25
- package/dist/index.cjs +110 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -14
- package/dist/index.d.ts +102 -14
- package/dist/index.js +89 -64
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -120,7 +120,7 @@ If you prefer to use the `const Component = () => {}` syntax, then you must use
|
|
|
120
120
|
|
|
121
121
|
```tsx
|
|
122
122
|
// The UserInfo component will correctly infer the interface of `UserInfoProps` automatically!
|
|
123
|
-
export const UserInfo = provideModuleToComponent(UserComponentModule, ({ firstName, lastName }
|
|
123
|
+
export const UserInfo = provideModuleToComponent<UserInfoProps>(UserComponentModule, ({ firstName, lastName }) => {
|
|
124
124
|
const userService = useInject(UserService);
|
|
125
125
|
|
|
126
126
|
userService.firstName = firstName;
|
|
@@ -263,7 +263,7 @@ export interface InputboxProps {
|
|
|
263
263
|
initialValue: string;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
export const Inputbox = provideModuleToComponent(InputboxModule, ({ initialValue }
|
|
266
|
+
export const Inputbox = provideModuleToComponent<InputboxProps>(InputboxModule, ({ initialValue }) => {
|
|
267
267
|
const service = useInject(InputboxService);
|
|
268
268
|
const [, setCurrentValue] = useState(initialValue);
|
|
269
269
|
service.setStateValue = setCurrentValue;
|
|
@@ -304,7 +304,7 @@ export interface ListviewProps {
|
|
|
304
304
|
items: any[];
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
-
export const Listview = provideModuleToComponent(ListviewModule, ({ items }
|
|
307
|
+
export const Listview = provideModuleToComponent<ListviewProps>(ListviewModule, ({ items }) => {
|
|
308
308
|
const service = useInject(ListviewService);
|
|
309
309
|
|
|
310
310
|
/* Remaining fancy implementation */
|
|
@@ -362,15 +362,9 @@ export interface DropdownProps {
|
|
|
362
362
|
initialSelectedValue: number;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
export const Dropdown = provideModuleToComponent(
|
|
365
|
+
export const Dropdown = provideModuleToComponent<DropdownProps>(
|
|
366
366
|
ListviewModule,
|
|
367
|
-
({
|
|
368
|
-
listviewProps,
|
|
369
|
-
initialSelectedValue,
|
|
370
|
-
// Here it is important that we get access to the contextualized module
|
|
371
|
-
// so we can forward it to the `Listview` component!
|
|
372
|
-
module,
|
|
373
|
-
}: DropdownProps) => {
|
|
367
|
+
({ listviewProps, initialSelectedValue }) => {
|
|
374
368
|
const service = useInject(DropdownService);
|
|
375
369
|
|
|
376
370
|
/* Remaining fancy implementation */
|
|
@@ -379,9 +373,9 @@ export const Dropdown = provideModuleToComponent(
|
|
|
379
373
|
<div className="fancy-dropdown">
|
|
380
374
|
<span>{initialSelectedValue}</span>
|
|
381
375
|
|
|
382
|
-
{/* Here we
|
|
383
|
-
|
|
384
|
-
<Listview
|
|
376
|
+
{/* Here we tell the `ListView` component to actually use the `ListviewService` instance we provide via the `useValue` property. */}
|
|
377
|
+
{/* Each `useInject(ListviewService)` used inside the `ListView` component will automatically resolve to `service.listviewService`. */}
|
|
378
|
+
<Listview {...listviewProps} inject={[{ provide: ListviewService, useValue: service.listviewService }]} />
|
|
385
379
|
</div>
|
|
386
380
|
);
|
|
387
381
|
}
|
|
@@ -437,16 +431,11 @@ export interface AutocompleteProps {
|
|
|
437
431
|
currentText: string;
|
|
438
432
|
}
|
|
439
433
|
|
|
440
|
-
export const Autocomplete = provideModuleToComponent(
|
|
441
|
-
AutocompleteModule,
|
|
442
|
-
({
|
|
443
|
-
dropdownProps,
|
|
444
|
-
currentText,
|
|
445
|
-
|
|
446
|
-
module,
|
|
447
|
-
}: AutocompleteProps) => {
|
|
434
|
+
export const Autocomplete = provideModuleToComponent<AutocompleteProps>(AutocompleteModule, ({ inputboxProps, dropdownProps, currentText }) => {
|
|
448
435
|
const service = useInject(AutocompleteService);
|
|
449
436
|
|
|
437
|
+
service.inputboxService.currentValue = currentText;
|
|
438
|
+
|
|
450
439
|
console.log(service.dropdownService.listviewService.items);
|
|
451
440
|
// Produces: [29, 9, 1969]
|
|
452
441
|
|
|
@@ -454,9 +443,9 @@ export const Autocomplete = provideModuleToComponent(
|
|
|
454
443
|
|
|
455
444
|
return (
|
|
456
445
|
<div className="fancy-autocomplete">
|
|
457
|
-
{/* Let's not forget to
|
|
458
|
-
<Inputbox {...inputboxProps}
|
|
459
|
-
<Dropdown {...dropdownProps}
|
|
446
|
+
{/* Let's not forget to replace the injection providers of both components we want to control */}
|
|
447
|
+
<Inputbox {...inputboxProps} inject={[{ provide: InputboxService, useValue: service.inputboxService }]} >
|
|
448
|
+
<Dropdown {...dropdownProps} inject={[{ provide: DropdownService, useValue: service.dropdownService }]} />
|
|
460
449
|
</div>
|
|
461
450
|
);
|
|
462
451
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var e, t = Object.create,
|
|
3
|
+
var e, t = Object.create, r = Object.defineProperty, o = Object.getOwnPropertyDescriptor, n = Object.getOwnPropertyNames, i = Object.getPrototypeOf, s = Object.prototype.hasOwnProperty, u = (e, t) => r(e, "name", {
|
|
4
4
|
value: t,
|
|
5
5
|
configurable: !0
|
|
6
|
-
}), a = (e, t, i,
|
|
7
|
-
if (t && "object" == typeof t || "function" == typeof t) for (let a of n(t))
|
|
6
|
+
}), a = (e, t, i, u) => {
|
|
7
|
+
if (t && "object" == typeof t || "function" == typeof t) for (let a of n(t)) s.call(e, a) || a === i || r(e, a, {
|
|
8
8
|
get: () => t[a],
|
|
9
|
-
enumerable: !(
|
|
9
|
+
enumerable: !(u = o(t, a)) || u.enumerable
|
|
10
10
|
});
|
|
11
11
|
return e;
|
|
12
|
-
}, d = (e,
|
|
12
|
+
}, d = (e, o, n) => (n = null != e ? t(i(e)) : {}, a(!o && e && e.__esModule ? n : r(n, "default", {
|
|
13
13
|
value: e,
|
|
14
14
|
enumerable: !0
|
|
15
15
|
}), e)), c = {};
|
|
16
16
|
|
|
17
17
|
((e, t) => {
|
|
18
|
-
for (var
|
|
19
|
-
get: t[
|
|
18
|
+
for (var o in t) r(e, o, {
|
|
19
|
+
get: t[o],
|
|
20
20
|
enumerable: !0
|
|
21
21
|
});
|
|
22
22
|
})(c, {
|
|
23
23
|
ComponentProviderModule: () => C,
|
|
24
|
-
ProvideModule: () =>
|
|
24
|
+
ProvideModule: () => _,
|
|
25
25
|
REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT: () => p,
|
|
26
|
-
hookFactory: () =>
|
|
27
|
-
provideModuleToComponent: () =>
|
|
26
|
+
hookFactory: () => A,
|
|
27
|
+
provideModuleToComponent: () => S,
|
|
28
28
|
useComponentModule: () => f,
|
|
29
|
-
useInject: () =>
|
|
29
|
+
useInject: () => h,
|
|
30
30
|
useInjectMany: () => M
|
|
31
|
-
}), module.exports = (e = c, a(
|
|
31
|
+
}), module.exports = (e = c, a(r({}, "__esModule", {
|
|
32
32
|
value: !0
|
|
33
33
|
}), e));
|
|
34
34
|
|
|
@@ -38,7 +38,7 @@ function f() {
|
|
|
38
38
|
return (0, m.useContext)(p);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function
|
|
41
|
+
function h(e, t) {
|
|
42
42
|
return f().get(e, t?.isOptional);
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -46,27 +46,40 @@ function M(...e) {
|
|
|
46
46
|
return f().getMany(...e);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
u(f, "useComponentModule"), u(h, "useInject"), u(M, "useInjectMany");
|
|
50
50
|
|
|
51
|
-
var
|
|
51
|
+
var v = require("@adimm/x-injection"), C = class e extends v.ProviderModule {
|
|
52
52
|
static {
|
|
53
|
-
|
|
53
|
+
u(this, "ComponentProviderModule");
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
originalIdentifier;
|
|
56
|
+
hasContextualizedImports;
|
|
57
|
+
initializedFromComponent;
|
|
56
58
|
constructor(e) {
|
|
57
|
-
|
|
59
|
+
const t = Symbol(`Component${e.identifier.description}`), r = !e.markAsGlobal && (e.contextualizeImports ?? !0), o = r ? new Map : void 0;
|
|
60
|
+
super(v.ProviderModuleHelpers.buildInternalConstructorParams({
|
|
58
61
|
...e,
|
|
59
|
-
defaultScope: e.defaultScope ??
|
|
60
|
-
identifier:
|
|
61
|
-
|
|
62
|
+
defaultScope: e.defaultScope ?? v.InjectionScope.Singleton,
|
|
63
|
+
identifier: t,
|
|
64
|
+
imports: r ? e.imports?.map((e => {
|
|
65
|
+
const n = "function" == typeof e ? e() : e;
|
|
66
|
+
return r ? () => {
|
|
67
|
+
const e = n._createContextualizedComponentInstance(t);
|
|
68
|
+
return o.set(n.originalIdentifier.toString(), e), e;
|
|
69
|
+
} : n;
|
|
70
|
+
})) : e.imports,
|
|
71
|
+
dynamicExports: u(((e, t) => r ? t.map((e => {
|
|
72
|
+
if (!(e instanceof v.ProviderModule)) return e;
|
|
73
|
+
return o.get(e.originalIdentifier.toString());
|
|
74
|
+
})) : t), "dynamicExports")
|
|
75
|
+
})), this.originalIdentifier = e.identifier, this.hasContextualizedImports = r,
|
|
76
|
+
this.initializedFromComponent = !1;
|
|
62
77
|
}
|
|
63
78
|
toNaked() {
|
|
64
79
|
return this;
|
|
65
80
|
}
|
|
66
81
|
clone(t) {
|
|
67
|
-
|
|
68
|
-
t?.providersMap && (o = o.map((e => t.providersMap(e, this))));
|
|
69
|
-
const r = new e(h.ProviderModuleHelpers.buildInternalConstructorParams({
|
|
82
|
+
const r = t, o = new e(v.ProviderModuleHelpers.buildInternalConstructorParams({
|
|
70
83
|
isAppModule: this.isAppModule,
|
|
71
84
|
markAsGlobal: this.isMarkedAsGlobal,
|
|
72
85
|
identifier: Symbol(this.identifier.description.replace("Component", "")),
|
|
@@ -74,107 +87,117 @@ var h = require("@adimm/x-injection"), C = class e extends h.ProviderModule {
|
|
|
74
87
|
dynamicExports: this.dynamicExports,
|
|
75
88
|
onReady: this.onReady,
|
|
76
89
|
onDispose: this.onDispose,
|
|
77
|
-
|
|
90
|
+
contextualizeImports: this.hasContextualizedImports,
|
|
91
|
+
importedProvidersMap: this.importedProvidersMap,
|
|
78
92
|
imports: [ ...this.imports ],
|
|
79
|
-
providers:
|
|
80
|
-
exports: [ ...this.exports ]
|
|
93
|
+
providers: [ ...this.providers ],
|
|
94
|
+
exports: [ ...this.exports ],
|
|
95
|
+
...r
|
|
81
96
|
}));
|
|
82
|
-
return
|
|
97
|
+
return o.initializedFromComponent = this.initializedFromComponent, o.registeredBindingSideEffects = new Map(this.registeredBindingSideEffects),
|
|
98
|
+
o;
|
|
83
99
|
}
|
|
84
|
-
|
|
85
|
-
this.
|
|
100
|
+
_createContextualizedComponentInstance(e) {
|
|
101
|
+
if (this.initializedFromComponent) return this;
|
|
102
|
+
const t = this.clone().toNaked();
|
|
103
|
+
return t.identifier = Symbol(`${e ? `[Importer:${e.description ?? "Unknown"}]` : ""}Contextualized${t.identifier.description}`),
|
|
104
|
+
t.initializedFromComponent = !0, t;
|
|
86
105
|
}
|
|
87
|
-
|
|
88
|
-
if (this._initializedFromComponent) return this;
|
|
89
|
-
const e = this.clone().toNaked();
|
|
90
|
-
return e.identifier = Symbol(`Contextualized${e.identifier.description}`), e._initializedFromComponent = !0,
|
|
91
|
-
e;
|
|
92
|
-
}
|
|
93
|
-
}, y = d(require("react"), 1), P = require("react"), b = require("react");
|
|
106
|
+
}, y = d(require("react"), 1), g = require("@adimm/x-injection"), P = require("react"), b = require("react");
|
|
94
107
|
|
|
95
|
-
function
|
|
96
|
-
const t = (0, b.useRef)(void 0),
|
|
108
|
+
function x(e) {
|
|
109
|
+
const t = (0, b.useRef)(void 0), r = (0, b.useRef)(!1), o = (0, b.useRef)(!1), [, n] = (0,
|
|
97
110
|
b.useState)(0);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
r.current && (o.current = !0), (0, b.useEffect)((() => (r.current || (t.current = e(),
|
|
112
|
+
r.current = !0), n((e => e + 1)), () => {
|
|
113
|
+
o.current && t.current?.();
|
|
101
114
|
})), []);
|
|
102
115
|
}
|
|
103
116
|
|
|
104
|
-
function
|
|
105
|
-
const
|
|
106
|
-
const o =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
o
|
|
111
|
-
|
|
117
|
+
function I(e, t) {
|
|
118
|
+
const r = (0, P.useMemo)((() => {
|
|
119
|
+
const {module: r, inject: o} = t ?? {};
|
|
120
|
+
let n = (r ?? e).toNaked();
|
|
121
|
+
if (n.isMarkedAsGlobal && o) throw new g.InjectionProviderModuleError(n, "The 'inject' prop can be used only with modules which are not marked as global!");
|
|
122
|
+
if (n.isMarkedAsGlobal || (n = n._createContextualizedComponentInstance().toNaked()),
|
|
123
|
+
o) {
|
|
124
|
+
const e = new Map(n.registeredSideEffects);
|
|
125
|
+
n.registeredSideEffects.clear(), o.forEach((e => {
|
|
126
|
+
n.__unbind(e), n.moduleUtils.bindToContainer(e, n.defaultScope.native);
|
|
127
|
+
})), n.registeredBindingSideEffects = e;
|
|
128
|
+
}
|
|
129
|
+
return n;
|
|
130
|
+
}), [ e, t?.inject ]);
|
|
131
|
+
return x((() => () => {
|
|
132
|
+
r.dispose();
|
|
133
|
+
})), r;
|
|
112
134
|
}
|
|
113
135
|
|
|
114
|
-
|
|
136
|
+
u(x, "useEffectOnce"), u(I, "useContextualizedModule");
|
|
115
137
|
|
|
116
|
-
var
|
|
138
|
+
var j, E = require("@adimm/x-injection");
|
|
117
139
|
|
|
118
|
-
function
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
140
|
+
!function(e) {
|
|
141
|
+
function t(e, t, r) {
|
|
142
|
+
const o = {
|
|
143
|
+
...t
|
|
144
|
+
};
|
|
145
|
+
return ("object" == typeof e && "type" in e && (0, E.isFunction)(e.type) || (0,
|
|
146
|
+
E.isFunction)(e)) && (o.module = r), o;
|
|
147
|
+
}
|
|
148
|
+
u(t, "forwardPropsWithModule"), e.forwardPropsWithModule = t;
|
|
149
|
+
}(j || (j = {}));
|
|
127
150
|
|
|
128
|
-
var
|
|
151
|
+
var w = y.default.memo(z);
|
|
129
152
|
|
|
130
|
-
function
|
|
131
|
-
return
|
|
132
|
-
const
|
|
153
|
+
function S(e, t) {
|
|
154
|
+
return r => {
|
|
155
|
+
const o = I(e, r);
|
|
133
156
|
return y.default.createElement(p.Provider, {
|
|
134
|
-
value:
|
|
135
|
-
}, y.default.createElement(
|
|
136
|
-
module:
|
|
137
|
-
componentProps:
|
|
157
|
+
value: o
|
|
158
|
+
}, y.default.createElement(w, {
|
|
159
|
+
module: o,
|
|
160
|
+
componentProps: r,
|
|
138
161
|
component: t
|
|
139
162
|
}));
|
|
140
163
|
};
|
|
141
164
|
}
|
|
142
165
|
|
|
143
|
-
function
|
|
144
|
-
return y.default.createElement(y.default.Fragment, null, t(
|
|
166
|
+
function z({module: e, component: t, componentProps: r}) {
|
|
167
|
+
return y.default.createElement(y.default.Fragment, null, t(j.forwardPropsWithModule(t, r, e)));
|
|
145
168
|
}
|
|
146
169
|
|
|
147
|
-
|
|
170
|
+
u(S, "provideModuleToComponent"), u(z, "_ComponentRenderer");
|
|
148
171
|
|
|
149
|
-
var
|
|
172
|
+
var O = d(require("react"), 1);
|
|
150
173
|
|
|
151
|
-
function
|
|
152
|
-
const
|
|
153
|
-
return
|
|
154
|
-
value:
|
|
174
|
+
function _({module: e, children: t}) {
|
|
175
|
+
const r = t.props ?? {}, o = I(e, r), n = (0, O.useMemo)((() => O.default.cloneElement(t, j.forwardPropsWithModule(t, r, o))), [ r, o ]);
|
|
176
|
+
return O.default.createElement(p.Provider, {
|
|
177
|
+
value: o
|
|
155
178
|
}, n);
|
|
156
179
|
}
|
|
157
180
|
|
|
158
|
-
|
|
181
|
+
u(_, "ProvideModule");
|
|
159
182
|
|
|
160
|
-
var
|
|
183
|
+
var k = require("react"), q = require("@adimm/x-injection"), F = class e extends q.InjectionProviderModuleError {
|
|
161
184
|
static {
|
|
162
|
-
|
|
185
|
+
u(this, "InjectionHookFactoryError");
|
|
163
186
|
}
|
|
164
187
|
name=e.name;
|
|
165
188
|
};
|
|
166
189
|
|
|
167
|
-
function
|
|
168
|
-
return
|
|
169
|
-
const
|
|
170
|
-
if (0 === t.length) throw new
|
|
171
|
-
return
|
|
190
|
+
function A({use: e, inject: t}) {
|
|
191
|
+
return r => {
|
|
192
|
+
const o = f(), n = (0, k.useMemo)((() => {
|
|
193
|
+
if (0 === t.length) throw new F(o, "The 'deps' property array is missing!");
|
|
194
|
+
return o.getMany(...t);
|
|
172
195
|
}), [ t ]);
|
|
173
196
|
return e({
|
|
174
|
-
...
|
|
197
|
+
...r,
|
|
175
198
|
deps: [ ...n ]
|
|
176
199
|
});
|
|
177
200
|
};
|
|
178
201
|
}
|
|
179
202
|
|
|
180
|
-
|
|
203
|
+
u(A, "hookFactory");//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/react-context.ts","../src/core/hooks/use-component-module.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many.ts","../src/core/component-provider-module.ts","../src/core/provide-module/provide-module.arrow-function.tsx","../src/helpers/hooks/use-contextualized-module.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/forward-props-with-module.ts","../src/core/provide-module/provide-module.provider.tsx","../src/core/hook-factory.ts","../src/errors/hook-factory.ts"],"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\nexport const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT = createContext<IComponentProviderModule>(AppModule as any);\n","import { useContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/** Can be used to retrieve the {@link IComponentProviderModule} from the current context. */\nexport function useComponentModule(): IComponentProviderModule {\n return useContext(REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve a single dependency from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectOptions}.\n * @returns The resolved {@link T | dependency}.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useComponentModule();\n\n return componentModule.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve multiple dependencies at once from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\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: D | unknown[]\n): ProviderModuleGetManySignature<D> {\n const componentModule = useComponentModule();\n\n return componentModule.getMany(...deps);\n}\n","import {\n InjectionScope,\n ProviderModule,\n ProviderModuleHelpers,\n type CloneParams,\n type IProviderModuleNaked,\n type ProviderModuleOptions,\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\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n defaultScope: options.defaultScope ?? InjectionScope.Singleton,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n override clone(options?: CloneParams): IComponentProviderModule {\n let providers = [...this.providers];\n\n if (options?.providersMap) {\n providers = providers.map((provider) => options.providersMap!(provider, this));\n }\n\n const clonedModule = new ComponentProviderModule(\n ProviderModuleHelpers.buildInternalConstructorParams({\n isAppModule: this.isAppModule,\n markAsGlobal: this.isMarkedAsGlobal,\n identifier: Symbol(this.identifier.description!.replace('Component', '')),\n defaultScope: this.defaultScope.native,\n dynamicExports: this.dynamicExports,\n onReady: this.onReady,\n onDispose: this.onDispose,\n importedProvidersMap: options?.importedProvidersMap,\n imports: [...this.imports],\n providers,\n exports: [...this.exports],\n })\n );\n\n //@ts-expect-error Read-only method.\n clonedModule._initializedFromComponent = this._initializedFromComponent;\n\n return clonedModule;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n //#region IComponentProviderModuleNaked methods\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.\n */\n protected _createContextualizedComponentInstance(): IComponentProviderModule {\n if (this._initializedFromComponent) return this;\n\n const ctxModule = this.clone().toNaked();\n\n //@ts-expect-error Read-only property\n ctxModule.identifier = Symbol(`Contextualized${ctxModule.identifier.description}`);\n ctxModule._initializedFromComponent = true;\n\n return ctxModule;\n }\n\n //#endregion\n}\n","import React from 'react';\n\nimport { forwardPropsWithModule, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\nconst ComponentRenderer = React.memo(_ComponentRenderer);\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * export const MyComponent = provideModuleToComponent(\n * MyComponentModule,\n * ({ firstName, lastName }: MyComponentProps) => {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n * );\n *\n * function App() {\n * return <MyComponent firstName={'John'} lastName={'Doe'} />;\n * }\n * ```\n *\n * @param module The {@link IComponentProviderModule | Module} which should be consumed by the {@link component}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function provideModuleToComponent<\n P extends Record<string, any>,\n C extends ReactElementWithProviderModule<P> = ReactElementWithProviderModule<P>,\n>(module: IComponentProviderModule, component: ReactElementWithProviderModule<P>): C {\n return ((componentProps: PropsWithModule<P>) => {\n const moduleCtx = useContextualizedModule(module, componentProps.module);\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n <ComponentRenderer module={moduleCtx} componentProps={componentProps} component={component as any} />\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n }) as any;\n}\n\nfunction _ComponentRenderer<P extends Record<string, any>>({\n module,\n component,\n componentProps,\n}: {\n module: IComponentProviderModule;\n component: ReactElementWithProviderModule<P>;\n componentProps: P;\n}) {\n return <>{component(forwardPropsWithModule(component, componentProps, module))}</>;\n}\n\nexport type ReactElementWithProviderModule<P extends Record<string, any>> = (p: PropsWithModule<P>) => React.ReactNode;\n","import { useMemo } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { useEffectOnce } from './use-effect-once';\n\nexport function useContextualizedModule(\n originalModule: IComponentProviderModule,\n forwardedModule?: IComponentProviderModule\n): IComponentProviderModule {\n const ctxModule = useMemo(() => {\n const module = (forwardedModule ?? originalModule).toNaked();\n\n if (module.isMarkedAsGlobal) return module;\n\n return module._createContextualizedComponentInstance();\n }, [originalModule, forwardedModule]);\n\n useEffectOnce(() => {\n return () => {\n ctxModule.dispose();\n };\n });\n\n return ctxModule;\n}\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 { isFunction } from '@adimm/x-injection';\n\nimport type { ReactElementWithProviderModule } from '../core';\nimport type { IComponentProviderModule, PropsWithModule } from '../types';\n\nexport function forwardPropsWithModule<P extends Record<string, any>>(\n component: ReactElementWithProviderModule<P> | React.ReactElement,\n props: Record<string, any>,\n module: IComponentProviderModule\n): PropsWithModule<P> {\n const isReactElement = typeof component === 'object' && 'type' in component;\n\n const result = {\n ...props,\n } as any;\n\n if ((isReactElement && isFunction(component.type)) || isFunction(component)) {\n result['module'] = module;\n }\n\n return result;\n}\n","import React, { useMemo } from 'react';\n\nimport { forwardPropsWithModule, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * function MyComponent({ firstName, lastName }: MyComponentProps) {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n *\n * function App() {\n * return (\n * <ProvideModule module={MyComponentModule}>\n * <MyComponent firstName={'John'} lastName={'Doe'} />\n * </ProvideModule>\n * );\n * }\n * ```\n *\n * @param param0 See {@link ProvideModuleFunctionParams}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function ProvideModule({ module, children }: ProvideModuleFunctionParams) {\n /* istanbul ignore next */\n const componentProps = (children.props ?? {}) as any;\n const moduleCtx = useContextualizedModule(module, componentProps.module);\n const component = useMemo(\n () => React.cloneElement(children, forwardPropsWithModule(children, componentProps, moduleCtx)),\n [componentProps, moduleCtx]\n );\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n {component}\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n}\n\nexport interface ProvideModuleFunctionParams {\n /** The {@link IComponentProviderModule | Module} which should be consumed by the {@link children | component}. */\n module: IComponentProviderModule;\n\n children: React.ReactElement;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport { InjectionHookFactoryError } from '../errors';\nimport { useComponentModule } from './hooks';\n\nexport function hookFactory<P extends HookParams, D extends any[], T>({\n use: hook,\n inject,\n}: HookFactoryParams<P, D, T>): (p: P) => T {\n return (p: P) => {\n const componentModule = useComponentModule();\n\n const deps = useMemo(() => {\n if (inject.length === 0) {\n throw new InjectionHookFactoryError(componentModule, `The 'deps' property array is missing!`);\n }\n\n return componentModule.getMany(...inject);\n }, [inject]);\n\n return hook({ ...p, deps: [...deps] } as any);\n };\n}\n\nexport interface HookFactoryParams<P extends HookParams, D extends any[], T> {\n use: HookWithProviderModuleDependencies<P, D, T>;\n inject: ProviderToken[];\n}\n\nexport type HookWithProviderModuleDependencies<P extends HookParams, D extends any[], T> = (p: HookWithDeps<P, D>) => T;\n\nexport type HookWithDeps<P extends HookParams, D extends any[]> = P & {\n /** Array containing the resolved dependencies from the component context. */\n deps: D;\n};\n\ntype HookParams = Record<string, any> | void;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\n\nexport class InjectionHookFactoryError extends InjectionProviderModuleError {\n override name = InjectionHookFactoryError.name;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;ACAA,yBAA0B;AAC1B,mBAA8B;AAIvB,IAAMA,gDAA4CC,4BAAwCC,4BAAAA;;;ACLjG,IAAAC,gBAA2B;AAMpB,SAASC,qBAAAA;AACd,aAAOC,0BAAWC,yCAAAA;AACpB;AAFgBF;;;ACST,SAASG,UAAaC,UAA4BC,SAA0B;AACjF,QAAMC,kBAAkBC,mBAAAA;AAExB,SAAOD,gBAAgBE,IAAIJ,UAAUC,SAASI,UAAAA;AAChD;AAJgBN;;;ACDT,SAASO,iBACXC,MAAmB;AAEtB,QAAMC,kBAAkBC,mBAAAA;AAExB,SAAOD,gBAAgBE,QAAO,GAAIH,IAAAA;AACpC;AANgBD;;;ACdhB,IAAAK,sBAOO;AAKA,IAAMC,0BAAN,MAAMA,iCAAgCC,mCAAAA;EAZ7C,OAY6CA;;;EACxBC;EAEnBC,YAAYC,SAAgC;AAC1C,UACEC,0CAAsBC,+BAA+B;MACnD,GAAGF;MACHG,cAAcH,QAAQG,gBAAgBC,mCAAeC;MACrDC,YAAYC,OAAO,YAAYP,QAAQM,WAAWE,WAAW,EAAE;IACjE,CAAA,CAAA;AAGF,SAAKV,4BAA4B;EACnC;EAESW,UAAgE;AACvE,WAAO;EACT;;EAGSC,MAAMV,SAAiD;AAC9D,QAAIW,YAAY;SAAI,KAAKA;;AAEzB,QAAIX,SAASY,cAAc;AACzBD,kBAAYA,UAAUE,IAAI,CAACC,aAAad,QAAQY,aAAcE,UAAU,IAAI,CAAA;IAC9E;AAEA,UAAMC,eAAe,IAAInB,yBACvBK,0CAAsBC,+BAA+B;MACnDc,aAAa,KAAKA;MAClBC,cAAc,KAAKC;MACnBZ,YAAYC,OAAO,KAAKD,WAAWE,YAAaW,QAAQ,aAAa,EAAA,CAAA;MACrEhB,cAAc,KAAKA,aAAaiB;MAChCC,gBAAgB,KAAKA;MACrBC,SAAS,KAAKA;MACdC,WAAW,KAAKA;MAChBC,sBAAsBxB,SAASwB;MAC/BC,SAAS;WAAI,KAAKA;;MAClBd;MACAe,SAAS;WAAI,KAAKA;;IACpB,CAAA,CAAA;AAIFX,iBAAajB,4BAA4B,KAAKA;AAE9C,WAAOiB;EACT;;EAGAY,UAAgB;AACd,SAAKC,SAAQ;EACf;;;;;;;EASUC,yCAAmE;AAC3E,QAAI,KAAK/B,0BAA2B,QAAO;AAE3C,UAAMgC,YAAY,KAAKpB,MAAK,EAAGD,QAAO;AAGtCqB,cAAUxB,aAAaC,OAAO,iBAAiBuB,UAAUxB,WAAWE,WAAW,EAAE;AACjFsB,cAAUhC,4BAA4B;AAEtC,WAAOgC;EACT;AAGF;;;ACtFA,IAAAC,gBAAkB;;;ACAlB,IAAAC,gBAAwB;;;ACAxB,IAAAC,gBAA4C;AAKrC,SAASC,cAAcC,QAAkC;AAC9D,QAAMC,kBAAcC,sBAA6BC,MAAAA;AACjD,QAAMC,mBAAeF,sBAAO,KAAA;AAC5B,QAAMG,wBAAoBH,sBAAO,KAAA;AACjC,QAAM,CAAA,EAAGI,aAAAA,QAAiBC,wBAAS,CAAA;AAEnC,MAAIH,aAAaI,QAASH,mBAAkBG,UAAU;AAEtDC,+BAAU,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;;;ADAT,SAASY,wBACdC,gBACAC,iBAA0C;AAE1C,QAAMC,gBAAYC,uBAAQ,MAAA;AACxB,UAAMC,WAAUH,mBAAmBD,gBAAgBK,QAAO;AAE1D,QAAID,QAAOE,iBAAkB,QAAOF;AAEpC,WAAOA,QAAOG,uCAAsC;EACtD,GAAG;IAACP;IAAgBC;GAAgB;AAEpCO,gBAAc,MAAA;AACZ,WAAO,MAAA;AACLN,gBAAUO,QAAO;IACnB;EACF,CAAA;AAEA,SAAOP;AACT;AAnBgBH;;;AELhB,IAAAW,sBAA2B;AAKpB,SAASC,uBACdC,WACAC,OACAC,SAAgC;AAEhC,QAAMC,iBAAiB,OAAOH,cAAc,YAAY,UAAUA;AAElE,QAAMI,SAAS;IACb,GAAGH;EACL;AAEA,MAAKE,sBAAkBE,gCAAWL,UAAUM,IAAI,SAAMD,gCAAWL,SAAAA,GAAY;AAC3EI,WAAO,QAAA,IAAYF;EACrB;AAEA,SAAOE;AACT;AAhBgBL;;;AHChB,IAAMQ,oBAAoBC,8BAAAA,QAAMC,KAAKC,kBAAAA;AA6B9B,SAASC,yBAGdC,SAAkCC,WAA4C;AAC9E,SAAQ,CAACC,mBAAAA;AACP,UAAMC,YAAYC,wBAAwBJ,SAAQE,eAAeF,MAAM;AAEvE,WACE,8BAAAJ,QAAA,cAACS,0CAA0CC,UAAQ;MAACC,OAAOJ;OACzD,8BAAAP,QAAA,cAACD,mBAAAA;MAAkBK,QAAQG;MAAWD;MAAgCD;;EAG5E;AACF;AAbgBF;AAehB,SAASD,mBAAkD,EACzDE,QAAAA,SACAC,WACAC,eAAc,GAKf;AACC,SAAO,8BAAAN,QAAA,cAAA,cAAAA,QAAA,UAAA,MAAGK,UAAUO,uBAAuBP,WAAWC,gBAAgBF,OAAAA,CAAAA,CAAAA;AACxE;AAVSF;;;AIlDT,IAAAW,gBAA+B;AAkCxB,SAASC,cAAc,EAAEC,QAAAA,SAAQC,SAAQ,GAA+B;AAE7E,QAAMC,iBAAkBD,SAASE,SAAS,CAAC;AAC3C,QAAMC,YAAYC,wBAAwBL,SAAQE,eAAeF,MAAM;AACvE,QAAMM,gBAAYC,uBAChB,MAAMC,8BAAAA,QAAMC,aAAaR,UAAUS,uBAAuBT,UAAUC,gBAAgBE,SAAAA,CAAAA,GACpF;IAACF;IAAgBE;GAAU;AAG7B,SACE,8BAAAI,QAAA,cAACG,0CAA0CC,UAAQ;IAACC,OAAOT;KACxDE,SAAAA;AAGP;AAdgBP;;;ACjChB,IAAAe,gBAAwB;;;ACDxB,IAAAC,sBAA6C;AAEtC,IAAMC,4BAAN,MAAMA,mCAAkCC,iDAAAA;EAF/C,OAE+CA;;;EACpCC,OAAOF,2BAA0BE;AAC5C;;;ADEO,SAASC,YAAsD,EACpEC,KAAKC,MACLC,OAAM,GACqB;AAC3B,SAAO,CAACC,MAAAA;AACN,UAAMC,kBAAkBC,mBAAAA;AAExB,UAAMC,WAAOC,uBAAQ,MAAA;AACnB,UAAIL,OAAOM,WAAW,GAAG;AACvB,cAAM,IAAIC,0BAA0BL,iBAAiB,uCAAuC;MAC9F;AAEA,aAAOA,gBAAgBM,QAAO,GAAIR,MAAAA;IACpC,GAAG;MAACA;KAAO;AAEX,WAAOD,KAAK;MAAE,GAAGE;MAAGG,MAAM;WAAIA;;IAAM,CAAA;EACtC;AACF;AAjBgBP;","names":["REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","createContext","AppModule","import_react","useComponentModule","useContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useInject","provider","options","componentModule","useComponentModule","get","isOptional","useInjectMany","deps","componentModule","useComponentModule","getMany","import_x_injection","ComponentProviderModule","ProviderModule","_initializedFromComponent","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Singleton","identifier","Symbol","description","toNaked","clone","providers","providersMap","map","provider","clonedModule","isAppModule","markAsGlobal","isMarkedAsGlobal","replace","native","dynamicExports","onReady","onDispose","importedProvidersMap","imports","exports","dispose","_dispose","_createContextualizedComponentInstance","ctxModule","import_react","import_react","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContextualizedModule","originalModule","forwardedModule","ctxModule","useMemo","module","toNaked","isMarkedAsGlobal","_createContextualizedComponentInstance","useEffectOnce","dispose","import_x_injection","forwardPropsWithModule","component","props","module","isReactElement","result","isFunction","type","ComponentRenderer","React","memo","_ComponentRenderer","provideModuleToComponent","module","component","componentProps","moduleCtx","useContextualizedModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","forwardPropsWithModule","import_react","ProvideModule","module","children","componentProps","props","moduleCtx","useContextualizedModule","component","useMemo","React","cloneElement","forwardPropsWithModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","import_react","import_x_injection","InjectionHookFactoryError","InjectionProviderModuleError","name","hookFactory","use","hook","inject","p","componentModule","useComponentModule","deps","useMemo","length","InjectionHookFactoryError","getMany"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/react-context.ts","../src/core/hooks/use-component-module.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many.ts","../src/core/component-provider-module.ts","../src/core/provide-module/provide-module.arrow-function.tsx","../src/helpers/hooks/use-contextualized-module.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/component-provider-module.ts","../src/core/provide-module/provide-module.provider.tsx","../src/core/hook-factory.ts","../src/errors/hook-factory.ts"],"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\nexport const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT = createContext<IComponentProviderModule>(AppModule as any);\n","import { useContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/** Can be used to retrieve the {@link IComponentProviderModule} from the current context. */\nexport function useComponentModule(): IComponentProviderModule {\n return useContext(REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve a single dependency from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectOptions}.\n * @returns The resolved {@link T | dependency}.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useComponentModule();\n\n return componentModule.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve multiple dependencies at once from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\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: D | unknown[]\n): ProviderModuleGetManySignature<D> {\n const componentModule = useComponentModule();\n\n return componentModule.getMany(...deps);\n}\n","import {\n InjectionScope,\n ProviderModule,\n ProviderModuleHelpers,\n type IProviderModule,\n type IProviderModuleNaked,\n type ProviderModuleOptionsInternal,\n} from '@adimm/x-injection';\n\nimport type { ComponentProviderModuleOptions, 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 originalIdentifier: symbol;\n protected readonly hasContextualizedImports: IComponentProviderModuleNaked['hasContextualizedImports'];\n protected readonly initializedFromComponent: IComponentProviderModuleNaked['initializedFromComponent'];\n\n constructor(options: ComponentProviderModuleOptions) {\n const identifier = Symbol(`Component${options.identifier.description}`);\n const contextualizeImports = options.markAsGlobal ? false : options.contextualizeImports ?? true;\n const contextualizedImportsCache: Map<string, IProviderModule> | undefined = contextualizeImports\n ? new Map()\n : undefined;\n\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n defaultScope: options.defaultScope ?? InjectionScope.Singleton,\n identifier: identifier,\n imports: !contextualizeImports\n ? options.imports\n : options.imports?.map((imp) => {\n const module = (typeof imp === 'function' ? imp() : imp) as IComponentProviderModuleNaked;\n /* istanbul ignore next */\n if (!contextualizeImports) return module;\n\n return () => {\n const ctxModule = module._createContextualizedComponentInstance(identifier);\n\n contextualizedImportsCache!.set(module.originalIdentifier.toString(), ctxModule);\n\n return ctxModule;\n };\n }),\n dynamicExports: (_, exports) => {\n if (!contextualizeImports) return exports;\n\n return exports.map((exp) => {\n if (!(exp instanceof ProviderModule)) return exp;\n\n const cachedCtxModule = contextualizedImportsCache!.get(\n (exp as unknown as IComponentProviderModuleNaked).originalIdentifier.toString()\n )!;\n\n return cachedCtxModule;\n });\n },\n })\n );\n\n this.originalIdentifier = options.identifier;\n this.hasContextualizedImports = contextualizeImports;\n this.initializedFromComponent = false;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n override clone(options?: Partial<ComponentProviderModuleOptions>): IComponentProviderModule {\n const _options = options as ProviderModuleOptionsInternal;\n\n const clonedModule = new ComponentProviderModule(\n ProviderModuleHelpers.buildInternalConstructorParams({\n isAppModule: this.isAppModule,\n markAsGlobal: this.isMarkedAsGlobal,\n identifier: Symbol(this.identifier.description!.replace('Component', '')),\n defaultScope: this.defaultScope.native,\n dynamicExports: this.dynamicExports,\n onReady: this.onReady,\n onDispose: this.onDispose,\n contextualizeImports: this.hasContextualizedImports,\n importedProvidersMap: this.importedProvidersMap,\n imports: [...this.imports],\n providers: [...this.providers],\n exports: [...this.exports],\n ..._options,\n } as ComponentProviderModuleOptions)\n );\n\n //@ts-expect-error Read-only method.\n clonedModule.initializedFromComponent = this.initializedFromComponent;\n //@ts-expect-error Read-only method.\n clonedModule.registeredBindingSideEffects = new Map(this.registeredBindingSideEffects);\n\n return clonedModule;\n }\n\n //#region IComponentProviderModuleNaked methods\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.\n */\n protected _createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule {\n if (this.initializedFromComponent) return this;\n\n const ctxModule = this.clone().toNaked();\n\n /* istanbul ignore next */\n //@ts-expect-error Read-only property\n ctxModule.identifier = Symbol(\n `${parentIdentifier ? `[Importer:${parentIdentifier.description ?? 'Unknown'}]` : ''}Contextualized${ctxModule.identifier.description}`\n );\n ctxModule.initializedFromComponent = true;\n\n return ctxModule;\n }\n\n //#endregion\n}\n","import React from 'react';\n\nimport { ComponentProviderModuleHelpers, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\nconst ComponentRenderer = React.memo(_ComponentRenderer);\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * export const MyComponent = provideModuleToComponent<MyComponentProps>(\n * MyComponentModule,\n * ({ firstName, lastName }) => {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n * );\n *\n * function App() {\n * return <MyComponent firstName={'John'} lastName={'Doe'} />;\n * }\n * ```\n *\n * @param module The {@link IComponentProviderModule | Module} which should be consumed by the {@link component}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function provideModuleToComponent<\n P extends Record<string, any>,\n C extends ReactElementWithProviderModule<P> = ReactElementWithProviderModule<P>,\n>(module: IComponentProviderModule, component: ReactElementWithProviderModule<P>): C {\n return ((componentProps: PropsWithModule<P>) => {\n const moduleCtx = useContextualizedModule(module, componentProps);\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n <ComponentRenderer module={moduleCtx} componentProps={componentProps} component={component as any} />\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n }) as any;\n}\n\nfunction _ComponentRenderer<P extends Record<string, any>>({\n module,\n component,\n componentProps,\n}: {\n module: IComponentProviderModule;\n component: ReactElementWithProviderModule<P>;\n componentProps: P;\n}) {\n return <>{component(ComponentProviderModuleHelpers.forwardPropsWithModule(component, componentProps, module))}</>;\n}\n\nexport type ReactElementWithProviderModule<P extends Record<string, any>> = (p: PropsWithModule<P>) => React.ReactNode;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { useEffectOnce } from './use-effect-once';\n\nexport function useContextualizedModule(\n originalModule: IComponentProviderModule,\n componentProps?: PropsWithModule<object>\n): IComponentProviderModule {\n const ctxModule = useMemo(() => {\n /* istanbul ignore next */\n const { module: forwardedModule, inject } = componentProps ?? {};\n let module = (forwardedModule ?? originalModule).toNaked();\n\n if (module.isMarkedAsGlobal && inject) {\n throw new InjectionProviderModuleError(\n module,\n `The 'inject' prop can be used only with modules which are not marked as global!`\n );\n }\n\n if (!module.isMarkedAsGlobal) {\n module = module._createContextualizedComponentInstance().toNaked();\n }\n\n if (inject) {\n const sideEffectsOriginal = new Map(module.registeredSideEffects);\n module.registeredSideEffects.clear();\n\n inject.forEach((provider) => {\n module.__unbind(provider);\n\n module.moduleUtils.bindToContainer(provider, module.defaultScope.native);\n });\n\n //@ts-expect-error Read-only property.\n module.registeredBindingSideEffects = sideEffectsOriginal;\n }\n\n return module;\n }, [originalModule, componentProps?.inject]);\n\n useEffectOnce(() => {\n return () => {\n ctxModule.dispose();\n };\n });\n\n return ctxModule;\n}\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 { isFunction } from '@adimm/x-injection';\n\nimport type { ReactElementWithProviderModule } from '../core';\nimport type { IComponentProviderModule, PropsWithModule } from '../types';\n\nexport namespace ComponentProviderModuleHelpers {\n export function forwardPropsWithModule<P extends Record<string, any>>(\n component: ReactElementWithProviderModule<P> | React.ReactElement,\n props: Record<string, any>,\n module: IComponentProviderModule\n ): PropsWithModule<P> {\n const isReactElement = typeof component === 'object' && 'type' in component;\n\n const result = {\n ...props,\n } as any;\n\n if ((isReactElement && isFunction(component.type)) || isFunction(component)) {\n result['module'] = module;\n }\n\n return result;\n }\n}\n","import React, { useMemo } from 'react';\n\nimport { ComponentProviderModuleHelpers, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * function MyComponent({ firstName, lastName }: MyComponentProps) {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n *\n * function App() {\n * return (\n * <ProvideModule module={MyComponentModule}>\n * <MyComponent firstName={'John'} lastName={'Doe'} />\n * </ProvideModule>\n * );\n * }\n * ```\n *\n * @param param0 See {@link ProvideModuleFunctionParams}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function ProvideModule({ module, children }: ProvideModuleFunctionParams) {\n /* istanbul ignore next */\n const componentProps = (children.props ?? {}) as PropsWithModule<object>;\n const moduleCtx = useContextualizedModule(module, componentProps);\n const component = useMemo(\n () =>\n React.cloneElement(\n children,\n ComponentProviderModuleHelpers.forwardPropsWithModule(children, componentProps, moduleCtx)\n ),\n [componentProps, moduleCtx]\n );\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n {component}\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n}\n\nexport interface ProvideModuleFunctionParams {\n /** The {@link IComponentProviderModule | Module} which should be consumed by the {@link children | component}. */\n module: IComponentProviderModule;\n\n children: React.ReactElement;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport { InjectionHookFactoryError } from '../errors';\nimport { useComponentModule } from './hooks';\n\nexport function hookFactory<P extends HookParams, D extends any[], T>({\n use: hook,\n inject,\n}: HookFactoryParams<P, D, T>): (p: P) => T {\n return (p: P) => {\n const componentModule = useComponentModule();\n\n const deps = useMemo(() => {\n if (inject.length === 0) {\n throw new InjectionHookFactoryError(componentModule, `The 'deps' property array is missing!`);\n }\n\n return componentModule.getMany(...inject);\n }, [inject]);\n\n return hook({ ...p, deps: [...deps] } as any);\n };\n}\n\nexport interface HookFactoryParams<P extends HookParams, D extends any[], T> {\n use: HookWithProviderModuleDependencies<P, D, T>;\n inject: ProviderToken[];\n}\n\nexport type HookWithProviderModuleDependencies<P extends HookParams, D extends any[], T> = (p: HookWithDeps<P, D>) => T;\n\nexport type HookWithDeps<P extends HookParams, D extends any[]> = P & {\n /** Array containing the resolved dependencies from the component context. */\n deps: D;\n};\n\ntype HookParams = Record<string, any> | void;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\n\nexport class InjectionHookFactoryError extends InjectionProviderModuleError {\n override name = InjectionHookFactoryError.name;\n}\n"],"mappings":"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","names":["REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","createContext","AppModule","import_react","useComponentModule","useContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useInject","provider","options","componentModule","useComponentModule","get","isOptional","useInjectMany","deps","componentModule","useComponentModule","getMany","import_x_injection","ComponentProviderModule","ProviderModule","originalIdentifier","hasContextualizedImports","initializedFromComponent","constructor","options","identifier","Symbol","description","contextualizeImports","markAsGlobal","contextualizedImportsCache","Map","undefined","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Singleton","imports","map","imp","module","ctxModule","_createContextualizedComponentInstance","set","toString","dynamicExports","_","exports","exp","cachedCtxModule","get","toNaked","clone","_options","clonedModule","isAppModule","isMarkedAsGlobal","replace","native","onReady","onDispose","importedProvidersMap","providers","registeredBindingSideEffects","parentIdentifier","import_react","import_x_injection","import_react","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContextualizedModule","originalModule","componentProps","ctxModule","useMemo","module","forwardedModule","inject","toNaked","isMarkedAsGlobal","InjectionProviderModuleError","_createContextualizedComponentInstance","sideEffectsOriginal","Map","registeredSideEffects","clear","forEach","provider","__unbind","moduleUtils","bindToContainer","defaultScope","native","registeredBindingSideEffects","useEffectOnce","dispose","import_x_injection","ComponentProviderModuleHelpers","forwardPropsWithModule","component","props","module","isReactElement","result","isFunction","type","ComponentRenderer","React","memo","_ComponentRenderer","provideModuleToComponent","module","component","componentProps","moduleCtx","useContextualizedModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","ComponentProviderModuleHelpers","forwardPropsWithModule","import_react","ProvideModule","module","children","componentProps","props","moduleCtx","useContextualizedModule","component","useMemo","React","cloneElement","ComponentProviderModuleHelpers","forwardPropsWithModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","import_react","import_x_injection","InjectionHookFactoryError","InjectionProviderModuleError","name","hookFactory","use","hook","inject","p","componentModule","useComponentModule","deps","useMemo","length","InjectionHookFactoryError","getMany"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,16 +1,42 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule
|
|
3
|
+
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, DependencyProvider, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
+
interface ComponentProviderModuleOptions extends ProviderModuleOptions {
|
|
7
|
+
/**
|
|
8
|
+
* When set to `true`, it'll automatically `contextualize` all the `imports` array.
|
|
9
|
+
*
|
|
10
|
+
* **Note:** _This is required when you have a parent component which renders one or more children
|
|
11
|
+
* and does also need to control their providers._
|
|
12
|
+
* _If not set to `true`, then the children providers would be resolved from their original `module`, therefore_
|
|
13
|
+
* _if your parent component has multiple instances of itself, all its children will actually share_
|
|
14
|
+
* _the same providers, especially when their module injection scope is set to `Singleton` (by default)._
|
|
15
|
+
*
|
|
16
|
+
* **Note2:** _If a module has {@link ProviderModuleOptions.markAsGlobal | markAsGlobal} set to `true`,_
|
|
17
|
+
* _this will automatically default to `false`._
|
|
18
|
+
*
|
|
19
|
+
* Defaults to `true`.
|
|
20
|
+
*/
|
|
21
|
+
contextualizeImports?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
interface IComponentProviderModuleNaked extends IComponentProviderModule {
|
|
25
|
+
/**
|
|
26
|
+
* The original `id` which was assigned to this module.
|
|
27
|
+
*
|
|
28
|
+
* **Note:** _The module initial {@link ComponentProviderModuleOptions.identifier | id} will be suffixed with `Contextualized`._
|
|
29
|
+
*/
|
|
30
|
+
originalIdentifier: symbol;
|
|
31
|
+
/** See {@link ComponentProviderModuleOptions.contextualizeImports}. */
|
|
32
|
+
hasContextualizedImports: ComponentProviderModuleOptions['contextualizeImports'];
|
|
7
33
|
/** Indicates if this module has been initialized by a React Component or not. */
|
|
8
|
-
|
|
34
|
+
initializedFromComponent: boolean;
|
|
9
35
|
/**
|
|
10
36
|
* It is used internally by the `ProviderModule` to create a new cloned
|
|
11
37
|
* module which will be consumed only by that specific component instance.
|
|
12
38
|
*/
|
|
13
|
-
_createContextualizedComponentInstance(): IComponentProviderModule;
|
|
39
|
+
_createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule;
|
|
14
40
|
}
|
|
15
41
|
|
|
16
42
|
interface IComponentProviderModule extends IProviderModule {
|
|
@@ -25,17 +51,78 @@ interface IComponentProviderModule extends IProviderModule {
|
|
|
25
51
|
*
|
|
26
52
|
* _eg: When changing page, removable components and so on._
|
|
27
53
|
*/
|
|
28
|
-
dispose(): void
|
|
54
|
+
dispose(): Promise<void>;
|
|
29
55
|
}
|
|
30
56
|
|
|
31
57
|
type PropsWithModule<P extends Record<string, any>> = P & {
|
|
32
58
|
/**
|
|
33
59
|
* The {@link IComponentProviderModule | Module} which this component should consume.
|
|
34
60
|
*
|
|
35
|
-
* **Note:**
|
|
36
|
-
*
|
|
61
|
+
* **Note:** _Can be used to easily mock an entire module._
|
|
62
|
+
*
|
|
63
|
+
* example:
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const CarModule = new ComponentProviderMdule({
|
|
66
|
+
* identifier: Symbol('CarModule'),
|
|
67
|
+
* imports: [CarEngineModule, CarDashboardModule],
|
|
68
|
+
* providers: [CarService],
|
|
69
|
+
* exports: [CarService],
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* const cbMock = jest.fn();
|
|
73
|
+
*
|
|
74
|
+
* const CarModuleMocked = CarModule.clone({
|
|
75
|
+
* providers: [
|
|
76
|
+
* {
|
|
77
|
+
* provide: CarService, useValue: { startEngine: cbMock }
|
|
78
|
+
* },
|
|
79
|
+
* ]
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* await act(async () => render(<CarComponent module={CarModuleMocked} />));
|
|
83
|
+
*
|
|
84
|
+
* await waitFor(async () => {
|
|
85
|
+
* expect(cbMock).toHaveBeenCalled();
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
37
88
|
*/
|
|
38
89
|
module?: IComponentProviderModule;
|
|
90
|
+
/**
|
|
91
|
+
* Can be used to control the dependencies consumed by this component.
|
|
92
|
+
* This is useful when you want to provide an already resolved instance of a dependency down the component tree.
|
|
93
|
+
*
|
|
94
|
+
* **Note:** _It'll throw when attempting to provide the `inject` prop to a component using a module_
|
|
95
|
+
* _marked as global!_
|
|
96
|
+
*
|
|
97
|
+
* eg:
|
|
98
|
+
* ```tsx
|
|
99
|
+
* class InputboxService {
|
|
100
|
+
* currentValue = '';
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* class FormService {
|
|
104
|
+
* constructor(
|
|
105
|
+
* public readonly firstNameInputbox: InputboxService,
|
|
106
|
+
* public readonly lastNameInputbox: InputboxService
|
|
107
|
+
* ) {
|
|
108
|
+
* this.firstNameInputbox.currentValue = 'John';
|
|
109
|
+
* this.lastNameInputbox.currentValue = 'Doe';
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* const Form = provideModuleToComponent(FormModule, () => {
|
|
114
|
+
* const service = useInject(FormService);
|
|
115
|
+
*
|
|
116
|
+
* return (
|
|
117
|
+
* <>
|
|
118
|
+
* <Inputbox inject={[{ provide: InputboxService, useValue: service.firstNameInputbox }]} />
|
|
119
|
+
* <Inputbox inject={[{ provide: InputboxService, useValue: service.lastNameInputbox }]} />
|
|
120
|
+
* </>
|
|
121
|
+
* );
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
inject?: DependencyProvider[];
|
|
39
126
|
};
|
|
40
127
|
|
|
41
128
|
declare const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT: React.Context<IComponentProviderModule>;
|
|
@@ -74,17 +161,18 @@ declare function useComponentModule(): IComponentProviderModule;
|
|
|
74
161
|
|
|
75
162
|
/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
|
|
76
163
|
declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
|
|
77
|
-
protected readonly
|
|
78
|
-
|
|
164
|
+
protected readonly originalIdentifier: symbol;
|
|
165
|
+
protected readonly hasContextualizedImports: IComponentProviderModuleNaked['hasContextualizedImports'];
|
|
166
|
+
protected readonly initializedFromComponent: IComponentProviderModuleNaked['initializedFromComponent'];
|
|
167
|
+
constructor(options: ComponentProviderModuleOptions);
|
|
79
168
|
toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked;
|
|
80
|
-
clone(options?:
|
|
81
|
-
dispose(): void;
|
|
169
|
+
clone(options?: Partial<ComponentProviderModuleOptions>): IComponentProviderModule;
|
|
82
170
|
/**
|
|
83
171
|
* **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**
|
|
84
172
|
*
|
|
85
173
|
* See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.
|
|
86
174
|
*/
|
|
87
|
-
protected _createContextualizedComponentInstance(): IComponentProviderModule;
|
|
175
|
+
protected _createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule;
|
|
88
176
|
}
|
|
89
177
|
|
|
90
178
|
/**
|
|
@@ -97,9 +185,9 @@ declare class ComponentProviderModule extends ProviderModule implements ICompone
|
|
|
97
185
|
* lastName: string;
|
|
98
186
|
* }
|
|
99
187
|
*
|
|
100
|
-
* export const MyComponent = provideModuleToComponent(
|
|
188
|
+
* export const MyComponent = provideModuleToComponent<MyComponentProps>(
|
|
101
189
|
* MyComponentModule,
|
|
102
|
-
* ({ firstName, lastName }
|
|
190
|
+
* ({ firstName, lastName }) => {
|
|
103
191
|
* const service = useInject(MyComponentService);
|
|
104
192
|
*
|
|
105
193
|
* return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>
|
|
@@ -164,4 +252,4 @@ type HookWithDeps<P extends HookParams, D extends any[]> = P & {
|
|
|
164
252
|
};
|
|
165
253
|
type HookParams = Record<string, any> | void;
|
|
166
254
|
|
|
167
|
-
export { ComponentProviderModule, type HookFactoryParams, type HookWithDeps, type HookWithProviderModuleDependencies, type IComponentProviderModule, type IComponentProviderModuleNaked, type PropsWithModule, ProvideModule, type ProvideModuleFunctionParams, REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT, type ReactElementWithProviderModule, type UseInjectOptions, hookFactory, provideModuleToComponent, useComponentModule, useInject, useInjectMany };
|
|
255
|
+
export { ComponentProviderModule, type ComponentProviderModuleOptions, type HookFactoryParams, type HookWithDeps, type HookWithProviderModuleDependencies, type IComponentProviderModule, type IComponentProviderModuleNaked, type PropsWithModule, ProvideModule, type ProvideModuleFunctionParams, REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT, type ReactElementWithProviderModule, type UseInjectOptions, hookFactory, provideModuleToComponent, useComponentModule, useInject, useInjectMany };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,42 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { IProviderModule, IProviderModuleNaked, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule
|
|
3
|
+
import { ProviderModuleOptions, IProviderModule, IProviderModuleNaked, DependencyProvider, ProviderToken, ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderModule } from '@adimm/x-injection';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
+
interface ComponentProviderModuleOptions extends ProviderModuleOptions {
|
|
7
|
+
/**
|
|
8
|
+
* When set to `true`, it'll automatically `contextualize` all the `imports` array.
|
|
9
|
+
*
|
|
10
|
+
* **Note:** _This is required when you have a parent component which renders one or more children
|
|
11
|
+
* and does also need to control their providers._
|
|
12
|
+
* _If not set to `true`, then the children providers would be resolved from their original `module`, therefore_
|
|
13
|
+
* _if your parent component has multiple instances of itself, all its children will actually share_
|
|
14
|
+
* _the same providers, especially when their module injection scope is set to `Singleton` (by default)._
|
|
15
|
+
*
|
|
16
|
+
* **Note2:** _If a module has {@link ProviderModuleOptions.markAsGlobal | markAsGlobal} set to `true`,_
|
|
17
|
+
* _this will automatically default to `false`._
|
|
18
|
+
*
|
|
19
|
+
* Defaults to `true`.
|
|
20
|
+
*/
|
|
21
|
+
contextualizeImports?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
interface IComponentProviderModuleNaked extends IComponentProviderModule {
|
|
25
|
+
/**
|
|
26
|
+
* The original `id` which was assigned to this module.
|
|
27
|
+
*
|
|
28
|
+
* **Note:** _The module initial {@link ComponentProviderModuleOptions.identifier | id} will be suffixed with `Contextualized`._
|
|
29
|
+
*/
|
|
30
|
+
originalIdentifier: symbol;
|
|
31
|
+
/** See {@link ComponentProviderModuleOptions.contextualizeImports}. */
|
|
32
|
+
hasContextualizedImports: ComponentProviderModuleOptions['contextualizeImports'];
|
|
7
33
|
/** Indicates if this module has been initialized by a React Component or not. */
|
|
8
|
-
|
|
34
|
+
initializedFromComponent: boolean;
|
|
9
35
|
/**
|
|
10
36
|
* It is used internally by the `ProviderModule` to create a new cloned
|
|
11
37
|
* module which will be consumed only by that specific component instance.
|
|
12
38
|
*/
|
|
13
|
-
_createContextualizedComponentInstance(): IComponentProviderModule;
|
|
39
|
+
_createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule;
|
|
14
40
|
}
|
|
15
41
|
|
|
16
42
|
interface IComponentProviderModule extends IProviderModule {
|
|
@@ -25,17 +51,78 @@ interface IComponentProviderModule extends IProviderModule {
|
|
|
25
51
|
*
|
|
26
52
|
* _eg: When changing page, removable components and so on._
|
|
27
53
|
*/
|
|
28
|
-
dispose(): void
|
|
54
|
+
dispose(): Promise<void>;
|
|
29
55
|
}
|
|
30
56
|
|
|
31
57
|
type PropsWithModule<P extends Record<string, any>> = P & {
|
|
32
58
|
/**
|
|
33
59
|
* The {@link IComponentProviderModule | Module} which this component should consume.
|
|
34
60
|
*
|
|
35
|
-
* **Note:**
|
|
36
|
-
*
|
|
61
|
+
* **Note:** _Can be used to easily mock an entire module._
|
|
62
|
+
*
|
|
63
|
+
* example:
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const CarModule = new ComponentProviderMdule({
|
|
66
|
+
* identifier: Symbol('CarModule'),
|
|
67
|
+
* imports: [CarEngineModule, CarDashboardModule],
|
|
68
|
+
* providers: [CarService],
|
|
69
|
+
* exports: [CarService],
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* const cbMock = jest.fn();
|
|
73
|
+
*
|
|
74
|
+
* const CarModuleMocked = CarModule.clone({
|
|
75
|
+
* providers: [
|
|
76
|
+
* {
|
|
77
|
+
* provide: CarService, useValue: { startEngine: cbMock }
|
|
78
|
+
* },
|
|
79
|
+
* ]
|
|
80
|
+
* });
|
|
81
|
+
*
|
|
82
|
+
* await act(async () => render(<CarComponent module={CarModuleMocked} />));
|
|
83
|
+
*
|
|
84
|
+
* await waitFor(async () => {
|
|
85
|
+
* expect(cbMock).toHaveBeenCalled();
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
37
88
|
*/
|
|
38
89
|
module?: IComponentProviderModule;
|
|
90
|
+
/**
|
|
91
|
+
* Can be used to control the dependencies consumed by this component.
|
|
92
|
+
* This is useful when you want to provide an already resolved instance of a dependency down the component tree.
|
|
93
|
+
*
|
|
94
|
+
* **Note:** _It'll throw when attempting to provide the `inject` prop to a component using a module_
|
|
95
|
+
* _marked as global!_
|
|
96
|
+
*
|
|
97
|
+
* eg:
|
|
98
|
+
* ```tsx
|
|
99
|
+
* class InputboxService {
|
|
100
|
+
* currentValue = '';
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* class FormService {
|
|
104
|
+
* constructor(
|
|
105
|
+
* public readonly firstNameInputbox: InputboxService,
|
|
106
|
+
* public readonly lastNameInputbox: InputboxService
|
|
107
|
+
* ) {
|
|
108
|
+
* this.firstNameInputbox.currentValue = 'John';
|
|
109
|
+
* this.lastNameInputbox.currentValue = 'Doe';
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* const Form = provideModuleToComponent(FormModule, () => {
|
|
114
|
+
* const service = useInject(FormService);
|
|
115
|
+
*
|
|
116
|
+
* return (
|
|
117
|
+
* <>
|
|
118
|
+
* <Inputbox inject={[{ provide: InputboxService, useValue: service.firstNameInputbox }]} />
|
|
119
|
+
* <Inputbox inject={[{ provide: InputboxService, useValue: service.lastNameInputbox }]} />
|
|
120
|
+
* </>
|
|
121
|
+
* );
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
inject?: DependencyProvider[];
|
|
39
126
|
};
|
|
40
127
|
|
|
41
128
|
declare const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT: React.Context<IComponentProviderModule>;
|
|
@@ -74,17 +161,18 @@ declare function useComponentModule(): IComponentProviderModule;
|
|
|
74
161
|
|
|
75
162
|
/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
|
|
76
163
|
declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
|
|
77
|
-
protected readonly
|
|
78
|
-
|
|
164
|
+
protected readonly originalIdentifier: symbol;
|
|
165
|
+
protected readonly hasContextualizedImports: IComponentProviderModuleNaked['hasContextualizedImports'];
|
|
166
|
+
protected readonly initializedFromComponent: IComponentProviderModuleNaked['initializedFromComponent'];
|
|
167
|
+
constructor(options: ComponentProviderModuleOptions);
|
|
79
168
|
toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked;
|
|
80
|
-
clone(options?:
|
|
81
|
-
dispose(): void;
|
|
169
|
+
clone(options?: Partial<ComponentProviderModuleOptions>): IComponentProviderModule;
|
|
82
170
|
/**
|
|
83
171
|
* **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**
|
|
84
172
|
*
|
|
85
173
|
* See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.
|
|
86
174
|
*/
|
|
87
|
-
protected _createContextualizedComponentInstance(): IComponentProviderModule;
|
|
175
|
+
protected _createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule;
|
|
88
176
|
}
|
|
89
177
|
|
|
90
178
|
/**
|
|
@@ -97,9 +185,9 @@ declare class ComponentProviderModule extends ProviderModule implements ICompone
|
|
|
97
185
|
* lastName: string;
|
|
98
186
|
* }
|
|
99
187
|
*
|
|
100
|
-
* export const MyComponent = provideModuleToComponent(
|
|
188
|
+
* export const MyComponent = provideModuleToComponent<MyComponentProps>(
|
|
101
189
|
* MyComponentModule,
|
|
102
|
-
* ({ firstName, lastName }
|
|
190
|
+
* ({ firstName, lastName }) => {
|
|
103
191
|
* const service = useInject(MyComponentService);
|
|
104
192
|
*
|
|
105
193
|
* return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>
|
|
@@ -164,4 +252,4 @@ type HookWithDeps<P extends HookParams, D extends any[]> = P & {
|
|
|
164
252
|
};
|
|
165
253
|
type HookParams = Record<string, any> | void;
|
|
166
254
|
|
|
167
|
-
export { ComponentProviderModule, type HookFactoryParams, type HookWithDeps, type HookWithProviderModuleDependencies, type IComponentProviderModule, type IComponentProviderModuleNaked, type PropsWithModule, ProvideModule, type ProvideModuleFunctionParams, REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT, type ReactElementWithProviderModule, type UseInjectOptions, hookFactory, provideModuleToComponent, useComponentModule, useInject, useInjectMany };
|
|
255
|
+
export { ComponentProviderModule, type ComponentProviderModuleOptions, type HookFactoryParams, type HookWithDeps, type HookWithProviderModuleDependencies, type IComponentProviderModule, type IComponentProviderModuleNaked, type PropsWithModule, ProvideModule, type ProvideModuleFunctionParams, REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT, type ReactElementWithProviderModule, type UseInjectOptions, hookFactory, provideModuleToComponent, useComponentModule, useInject, useInjectMany };
|
package/dist/index.js
CHANGED
|
@@ -19,33 +19,46 @@ function a(e, t) {
|
|
|
19
19
|
return s().get(e, t?.isOptional);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function
|
|
22
|
+
function d(...e) {
|
|
23
23
|
return s().getMany(...e);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
t(s, "useComponentModule"), t(a, "useInject"), t(
|
|
26
|
+
t(s, "useComponentModule"), t(a, "useInject"), t(d, "useInjectMany");
|
|
27
27
|
|
|
28
|
-
import { InjectionScope as c, ProviderModule as
|
|
28
|
+
import { InjectionScope as c, ProviderModule as m, ProviderModuleHelpers as p } from "@adimm/x-injection";
|
|
29
29
|
|
|
30
|
-
var u = class e extends
|
|
30
|
+
var u, l = class e extends m {
|
|
31
31
|
static {
|
|
32
32
|
t(this, "ComponentProviderModule");
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
originalIdentifier;
|
|
35
|
+
hasContextualizedImports;
|
|
36
|
+
initializedFromComponent;
|
|
35
37
|
constructor(e) {
|
|
36
|
-
|
|
38
|
+
const o = Symbol(`Component${e.identifier.description}`), n = !e.markAsGlobal && (e.contextualizeImports ?? !0), r = n ? new Map : void 0;
|
|
39
|
+
super(p.buildInternalConstructorParams({
|
|
37
40
|
...e,
|
|
38
41
|
defaultScope: e.defaultScope ?? c.Singleton,
|
|
39
|
-
identifier:
|
|
40
|
-
|
|
42
|
+
identifier: o,
|
|
43
|
+
imports: n ? e.imports?.map((e => {
|
|
44
|
+
const t = "function" == typeof e ? e() : e;
|
|
45
|
+
return n ? () => {
|
|
46
|
+
const e = t._createContextualizedComponentInstance(o);
|
|
47
|
+
return r.set(t.originalIdentifier.toString(), e), e;
|
|
48
|
+
} : t;
|
|
49
|
+
})) : e.imports,
|
|
50
|
+
dynamicExports: t(((e, t) => n ? t.map((e => {
|
|
51
|
+
if (!(e instanceof m)) return e;
|
|
52
|
+
return r.get(e.originalIdentifier.toString());
|
|
53
|
+
})) : t), "dynamicExports")
|
|
54
|
+
})), this.originalIdentifier = e.identifier, this.hasContextualizedImports = n,
|
|
55
|
+
this.initializedFromComponent = !1;
|
|
41
56
|
}
|
|
42
57
|
toNaked() {
|
|
43
58
|
return this;
|
|
44
59
|
}
|
|
45
60
|
clone(t) {
|
|
46
|
-
|
|
47
|
-
t?.providersMap && (o = o.map((e => t.providersMap(e, this))));
|
|
48
|
-
const n = new e(d.buildInternalConstructorParams({
|
|
61
|
+
const o = t, n = new e(p.buildInternalConstructorParams({
|
|
49
62
|
isAppModule: this.isAppModule,
|
|
50
63
|
markAsGlobal: this.isMarkedAsGlobal,
|
|
51
64
|
identifier: Symbol(this.identifier.description.replace("Component", "")),
|
|
@@ -53,70 +66,82 @@ var u = class e extends p {
|
|
|
53
66
|
dynamicExports: this.dynamicExports,
|
|
54
67
|
onReady: this.onReady,
|
|
55
68
|
onDispose: this.onDispose,
|
|
56
|
-
|
|
69
|
+
contextualizeImports: this.hasContextualizedImports,
|
|
70
|
+
importedProvidersMap: this.importedProvidersMap,
|
|
57
71
|
imports: [ ...this.imports ],
|
|
58
|
-
providers:
|
|
59
|
-
exports: [ ...this.exports ]
|
|
72
|
+
providers: [ ...this.providers ],
|
|
73
|
+
exports: [ ...this.exports ],
|
|
74
|
+
...o
|
|
60
75
|
}));
|
|
61
|
-
return n.
|
|
76
|
+
return n.initializedFromComponent = this.initializedFromComponent, n.registeredBindingSideEffects = new Map(this.registeredBindingSideEffects),
|
|
77
|
+
n;
|
|
62
78
|
}
|
|
63
|
-
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const e = this.clone().toNaked();
|
|
69
|
-
return e.identifier = Symbol(`Contextualized${e.identifier.description}`), e._initializedFromComponent = !0,
|
|
70
|
-
e;
|
|
79
|
+
_createContextualizedComponentInstance(e) {
|
|
80
|
+
if (this.initializedFromComponent) return this;
|
|
81
|
+
const t = this.clone().toNaked();
|
|
82
|
+
return t.identifier = Symbol(`${e ? `[Importer:${e.description ?? "Unknown"}]` : ""}Contextualized${t.identifier.description}`),
|
|
83
|
+
t.initializedFromComponent = !0, t;
|
|
71
84
|
}
|
|
72
85
|
};
|
|
73
86
|
|
|
74
|
-
import
|
|
87
|
+
import f from "react";
|
|
88
|
+
|
|
89
|
+
import { InjectionProviderModuleError as h } from "@adimm/x-injection";
|
|
75
90
|
|
|
76
|
-
import { useMemo as
|
|
91
|
+
import { useMemo as C } from "react";
|
|
77
92
|
|
|
78
|
-
import { useEffect as
|
|
93
|
+
import { useEffect as M, useRef as g, useState as x } from "react";
|
|
79
94
|
|
|
80
|
-
function
|
|
81
|
-
const t =
|
|
82
|
-
o.current && (n.current = !0),
|
|
95
|
+
function v(e) {
|
|
96
|
+
const t = g(void 0), o = g(!1), n = g(!1), [, r] = x(0);
|
|
97
|
+
o.current && (n.current = !0), M((() => (o.current || (t.current = e(), o.current = !0),
|
|
83
98
|
r((e => e + 1)), () => {
|
|
84
99
|
n.current && t.current?.();
|
|
85
100
|
})), []);
|
|
86
101
|
}
|
|
87
102
|
|
|
88
103
|
function y(e, t) {
|
|
89
|
-
const o =
|
|
90
|
-
const o =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
104
|
+
const o = C((() => {
|
|
105
|
+
const {module: o, inject: n} = t ?? {};
|
|
106
|
+
let r = (o ?? e).toNaked();
|
|
107
|
+
if (r.isMarkedAsGlobal && n) throw new h(r, "The 'inject' prop can be used only with modules which are not marked as global!");
|
|
108
|
+
if (r.isMarkedAsGlobal || (r = r._createContextualizedComponentInstance().toNaked()),
|
|
109
|
+
n) {
|
|
110
|
+
const e = new Map(r.registeredSideEffects);
|
|
111
|
+
r.registeredSideEffects.clear(), n.forEach((e => {
|
|
112
|
+
r.__unbind(e), r.moduleUtils.bindToContainer(e, r.defaultScope.native);
|
|
113
|
+
})), r.registeredBindingSideEffects = e;
|
|
114
|
+
}
|
|
115
|
+
return r;
|
|
116
|
+
}), [ e, t?.inject ]);
|
|
117
|
+
return v((() => () => {
|
|
94
118
|
o.dispose();
|
|
95
119
|
})), o;
|
|
96
120
|
}
|
|
97
121
|
|
|
98
|
-
t(
|
|
99
|
-
|
|
100
|
-
import { isFunction as x } from "@adimm/x-injection";
|
|
122
|
+
t(v, "useEffectOnce"), t(y, "useContextualizedModule");
|
|
101
123
|
|
|
102
|
-
|
|
103
|
-
const n = {
|
|
104
|
-
...t
|
|
105
|
-
};
|
|
106
|
-
return ("object" == typeof e && "type" in e && x(e.type) || x(e)) && (n.module = o),
|
|
107
|
-
n;
|
|
108
|
-
}
|
|
124
|
+
import { isFunction as I } from "@adimm/x-injection";
|
|
109
125
|
|
|
110
|
-
|
|
126
|
+
!function(e) {
|
|
127
|
+
function o(e, t, o) {
|
|
128
|
+
const n = {
|
|
129
|
+
...t
|
|
130
|
+
};
|
|
131
|
+
return ("object" == typeof e && "type" in e && I(e.type) || I(e)) && (n.module = o),
|
|
132
|
+
n;
|
|
133
|
+
}
|
|
134
|
+
t(o, "forwardPropsWithModule"), e.forwardPropsWithModule = o;
|
|
135
|
+
}(u || (u = {}));
|
|
111
136
|
|
|
112
|
-
var
|
|
137
|
+
var E = f.memo(z);
|
|
113
138
|
|
|
114
|
-
function
|
|
139
|
+
function b(e, t) {
|
|
115
140
|
return o => {
|
|
116
|
-
const n = y(e, o
|
|
117
|
-
return
|
|
141
|
+
const n = y(e, o);
|
|
142
|
+
return f.createElement(r.Provider, {
|
|
118
143
|
value: n
|
|
119
|
-
},
|
|
144
|
+
}, f.createElement(E, {
|
|
120
145
|
module: n,
|
|
121
146
|
componentProps: o,
|
|
122
147
|
component: t
|
|
@@ -125,37 +150,37 @@ function j(e, t) {
|
|
|
125
150
|
}
|
|
126
151
|
|
|
127
152
|
function z({module: e, component: t, componentProps: o}) {
|
|
128
|
-
return
|
|
153
|
+
return f.createElement(f.Fragment, null, t(u.forwardPropsWithModule(t, o, e)));
|
|
129
154
|
}
|
|
130
155
|
|
|
131
|
-
t(
|
|
156
|
+
t(b, "provideModuleToComponent"), t(z, "_ComponentRenderer");
|
|
132
157
|
|
|
133
|
-
import
|
|
158
|
+
import P, { useMemo as S } from "react";
|
|
134
159
|
|
|
135
|
-
function
|
|
136
|
-
const o = t.props ?? {}, n = y(e, o
|
|
137
|
-
return
|
|
160
|
+
function j({module: e, children: t}) {
|
|
161
|
+
const o = t.props ?? {}, n = y(e, o), i = S((() => P.cloneElement(t, u.forwardPropsWithModule(t, o, n))), [ o, n ]);
|
|
162
|
+
return P.createElement(r.Provider, {
|
|
138
163
|
value: n
|
|
139
164
|
}, i);
|
|
140
165
|
}
|
|
141
166
|
|
|
142
|
-
t(
|
|
167
|
+
t(j, "ProvideModule");
|
|
143
168
|
|
|
144
|
-
import { useMemo as
|
|
169
|
+
import { useMemo as w } from "react";
|
|
145
170
|
|
|
146
171
|
import { InjectionProviderModuleError as k } from "@adimm/x-injection";
|
|
147
172
|
|
|
148
|
-
var
|
|
173
|
+
var F = class e extends k {
|
|
149
174
|
static {
|
|
150
175
|
t(this, "InjectionHookFactoryError");
|
|
151
176
|
}
|
|
152
177
|
name=e.name;
|
|
153
178
|
};
|
|
154
179
|
|
|
155
|
-
function
|
|
180
|
+
function A({use: e, inject: t}) {
|
|
156
181
|
return o => {
|
|
157
|
-
const n = s(), r =
|
|
158
|
-
if (0 === t.length) throw new
|
|
182
|
+
const n = s(), r = w((() => {
|
|
183
|
+
if (0 === t.length) throw new F(n, "The 'deps' property array is missing!");
|
|
159
184
|
return n.getMany(...t);
|
|
160
185
|
}), [ t ]);
|
|
161
186
|
return e({
|
|
@@ -165,6 +190,6 @@ function I({use: e, inject: t}) {
|
|
|
165
190
|
};
|
|
166
191
|
}
|
|
167
192
|
|
|
168
|
-
t(
|
|
193
|
+
t(A, "hookFactory");
|
|
169
194
|
|
|
170
|
-
export {
|
|
195
|
+
export { l as ComponentProviderModule, j as ProvideModule, r as REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT, A as hookFactory, b as provideModuleToComponent, s as useComponentModule, a as useInject, d as useInjectMany };//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/react-context.ts","../src/core/hooks/use-component-module.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many.ts","../src/core/component-provider-module.ts","../src/core/provide-module/provide-module.arrow-function.tsx","../src/helpers/hooks/use-contextualized-module.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/forward-props-with-module.ts","../src/core/provide-module/provide-module.provider.tsx","../src/core/hook-factory.ts","../src/errors/hook-factory.ts"],"sourcesContent":["import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../types';\n\nexport const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT = createContext<IComponentProviderModule>(AppModule as any);\n","import { useContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/** Can be used to retrieve the {@link IComponentProviderModule} from the current context. */\nexport function useComponentModule(): IComponentProviderModule {\n return useContext(REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve a single dependency from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectOptions}.\n * @returns The resolved {@link T | dependency}.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useComponentModule();\n\n return componentModule.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve multiple dependencies at once from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\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: D | unknown[]\n): ProviderModuleGetManySignature<D> {\n const componentModule = useComponentModule();\n\n return componentModule.getMany(...deps);\n}\n","import {\n InjectionScope,\n ProviderModule,\n ProviderModuleHelpers,\n type CloneParams,\n type IProviderModuleNaked,\n type ProviderModuleOptions,\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\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n defaultScope: options.defaultScope ?? InjectionScope.Singleton,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n override clone(options?: CloneParams): IComponentProviderModule {\n let providers = [...this.providers];\n\n if (options?.providersMap) {\n providers = providers.map((provider) => options.providersMap!(provider, this));\n }\n\n const clonedModule = new ComponentProviderModule(\n ProviderModuleHelpers.buildInternalConstructorParams({\n isAppModule: this.isAppModule,\n markAsGlobal: this.isMarkedAsGlobal,\n identifier: Symbol(this.identifier.description!.replace('Component', '')),\n defaultScope: this.defaultScope.native,\n dynamicExports: this.dynamicExports,\n onReady: this.onReady,\n onDispose: this.onDispose,\n importedProvidersMap: options?.importedProvidersMap,\n imports: [...this.imports],\n providers,\n exports: [...this.exports],\n })\n );\n\n //@ts-expect-error Read-only method.\n clonedModule._initializedFromComponent = this._initializedFromComponent;\n\n return clonedModule;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n //#region IComponentProviderModuleNaked methods\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.\n */\n protected _createContextualizedComponentInstance(): IComponentProviderModule {\n if (this._initializedFromComponent) return this;\n\n const ctxModule = this.clone().toNaked();\n\n //@ts-expect-error Read-only property\n ctxModule.identifier = Symbol(`Contextualized${ctxModule.identifier.description}`);\n ctxModule._initializedFromComponent = true;\n\n return ctxModule;\n }\n\n //#endregion\n}\n","import React from 'react';\n\nimport { forwardPropsWithModule, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\nconst ComponentRenderer = React.memo(_ComponentRenderer);\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * export const MyComponent = provideModuleToComponent(\n * MyComponentModule,\n * ({ firstName, lastName }: MyComponentProps) => {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n * );\n *\n * function App() {\n * return <MyComponent firstName={'John'} lastName={'Doe'} />;\n * }\n * ```\n *\n * @param module The {@link IComponentProviderModule | Module} which should be consumed by the {@link component}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function provideModuleToComponent<\n P extends Record<string, any>,\n C extends ReactElementWithProviderModule<P> = ReactElementWithProviderModule<P>,\n>(module: IComponentProviderModule, component: ReactElementWithProviderModule<P>): C {\n return ((componentProps: PropsWithModule<P>) => {\n const moduleCtx = useContextualizedModule(module, componentProps.module);\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n <ComponentRenderer module={moduleCtx} componentProps={componentProps} component={component as any} />\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n }) as any;\n}\n\nfunction _ComponentRenderer<P extends Record<string, any>>({\n module,\n component,\n componentProps,\n}: {\n module: IComponentProviderModule;\n component: ReactElementWithProviderModule<P>;\n componentProps: P;\n}) {\n return <>{component(forwardPropsWithModule(component, componentProps, module))}</>;\n}\n\nexport type ReactElementWithProviderModule<P extends Record<string, any>> = (p: PropsWithModule<P>) => React.ReactNode;\n","import { useMemo } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { useEffectOnce } from './use-effect-once';\n\nexport function useContextualizedModule(\n originalModule: IComponentProviderModule,\n forwardedModule?: IComponentProviderModule\n): IComponentProviderModule {\n const ctxModule = useMemo(() => {\n const module = (forwardedModule ?? originalModule).toNaked();\n\n if (module.isMarkedAsGlobal) return module;\n\n return module._createContextualizedComponentInstance();\n }, [originalModule, forwardedModule]);\n\n useEffectOnce(() => {\n return () => {\n ctxModule.dispose();\n };\n });\n\n return ctxModule;\n}\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 { isFunction } from '@adimm/x-injection';\n\nimport type { ReactElementWithProviderModule } from '../core';\nimport type { IComponentProviderModule, PropsWithModule } from '../types';\n\nexport function forwardPropsWithModule<P extends Record<string, any>>(\n component: ReactElementWithProviderModule<P> | React.ReactElement,\n props: Record<string, any>,\n module: IComponentProviderModule\n): PropsWithModule<P> {\n const isReactElement = typeof component === 'object' && 'type' in component;\n\n const result = {\n ...props,\n } as any;\n\n if ((isReactElement && isFunction(component.type)) || isFunction(component)) {\n result['module'] = module;\n }\n\n return result;\n}\n","import React, { useMemo } from 'react';\n\nimport { forwardPropsWithModule, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * function MyComponent({ firstName, lastName }: MyComponentProps) {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n *\n * function App() {\n * return (\n * <ProvideModule module={MyComponentModule}>\n * <MyComponent firstName={'John'} lastName={'Doe'} />\n * </ProvideModule>\n * );\n * }\n * ```\n *\n * @param param0 See {@link ProvideModuleFunctionParams}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function ProvideModule({ module, children }: ProvideModuleFunctionParams) {\n /* istanbul ignore next */\n const componentProps = (children.props ?? {}) as any;\n const moduleCtx = useContextualizedModule(module, componentProps.module);\n const component = useMemo(\n () => React.cloneElement(children, forwardPropsWithModule(children, componentProps, moduleCtx)),\n [componentProps, moduleCtx]\n );\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n {component}\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n}\n\nexport interface ProvideModuleFunctionParams {\n /** The {@link IComponentProviderModule | Module} which should be consumed by the {@link children | component}. */\n module: IComponentProviderModule;\n\n children: React.ReactElement;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport { InjectionHookFactoryError } from '../errors';\nimport { useComponentModule } from './hooks';\n\nexport function hookFactory<P extends HookParams, D extends any[], T>({\n use: hook,\n inject,\n}: HookFactoryParams<P, D, T>): (p: P) => T {\n return (p: P) => {\n const componentModule = useComponentModule();\n\n const deps = useMemo(() => {\n if (inject.length === 0) {\n throw new InjectionHookFactoryError(componentModule, `The 'deps' property array is missing!`);\n }\n\n return componentModule.getMany(...inject);\n }, [inject]);\n\n return hook({ ...p, deps: [...deps] } as any);\n };\n}\n\nexport interface HookFactoryParams<P extends HookParams, D extends any[], T> {\n use: HookWithProviderModuleDependencies<P, D, T>;\n inject: ProviderToken[];\n}\n\nexport type HookWithProviderModuleDependencies<P extends HookParams, D extends any[], T> = (p: HookWithDeps<P, D>) => T;\n\nexport type HookWithDeps<P extends HookParams, D extends any[]> = P & {\n /** Array containing the resolved dependencies from the component context. */\n deps: D;\n};\n\ntype HookParams = Record<string, any> | void;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\n\nexport class InjectionHookFactoryError extends InjectionProviderModuleError {\n override name = InjectionHookFactoryError.name;\n}\n"],"mappings":"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","names":["AppModule","createContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useContext","useComponentModule","useContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useInject","provider","options","componentModule","useComponentModule","get","isOptional","useInjectMany","deps","componentModule","useComponentModule","getMany","InjectionScope","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","_initializedFromComponent","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Singleton","identifier","Symbol","description","toNaked","clone","providers","providersMap","map","provider","clonedModule","isAppModule","markAsGlobal","isMarkedAsGlobal","replace","native","dynamicExports","onReady","onDispose","importedProvidersMap","imports","exports","dispose","_dispose","_createContextualizedComponentInstance","ctxModule","React","useMemo","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContextualizedModule","originalModule","forwardedModule","ctxModule","useMemo","module","toNaked","isMarkedAsGlobal","_createContextualizedComponentInstance","useEffectOnce","dispose","isFunction","forwardPropsWithModule","component","props","module","isReactElement","result","isFunction","type","ComponentRenderer","React","memo","_ComponentRenderer","provideModuleToComponent","module","component","componentProps","moduleCtx","useContextualizedModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","forwardPropsWithModule","React","useMemo","ProvideModule","module","children","componentProps","props","moduleCtx","useContextualizedModule","component","useMemo","React","cloneElement","forwardPropsWithModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","useMemo","InjectionProviderModuleError","InjectionHookFactoryError","InjectionProviderModuleError","name","hookFactory","use","hook","inject","p","componentModule","useComponentModule","deps","useMemo","length","InjectionHookFactoryError","getMany"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/react-context.ts","../src/core/hooks/use-component-module.ts","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many.ts","../src/core/component-provider-module.ts","../src/core/provide-module/provide-module.arrow-function.tsx","../src/helpers/hooks/use-contextualized-module.ts","../src/helpers/hooks/use-effect-once.ts","../src/helpers/component-provider-module.ts","../src/core/provide-module/provide-module.provider.tsx","../src/core/hook-factory.ts","../src/errors/hook-factory.ts"],"sourcesContent":["import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../types';\n\nexport const REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT = createContext<IComponentProviderModule>(AppModule as any);\n","import { useContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/** Can be used to retrieve the {@link IComponentProviderModule} from the current context. */\nexport function useComponentModule(): IComponentProviderModule {\n return useContext(REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve a single dependency from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectOptions}.\n * @returns The resolved {@link T | dependency}.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useComponentModule();\n\n return componentModule.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useComponentModule } from './use-component-module';\n\n/**\n * Low-level hook which can be used to resolve multiple dependencies at once from the current\n * context module.\n *\n * **Note:** _In order to better modularize your code-base, you should strive to create custom hooks by using the_\n * _`hookFactory` method to compose a custom hook._\n *\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: D | unknown[]\n): ProviderModuleGetManySignature<D> {\n const componentModule = useComponentModule();\n\n return componentModule.getMany(...deps);\n}\n","import {\n InjectionScope,\n ProviderModule,\n ProviderModuleHelpers,\n type IProviderModule,\n type IProviderModuleNaked,\n type ProviderModuleOptionsInternal,\n} from '@adimm/x-injection';\n\nimport type { ComponentProviderModuleOptions, 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 originalIdentifier: symbol;\n protected readonly hasContextualizedImports: IComponentProviderModuleNaked['hasContextualizedImports'];\n protected readonly initializedFromComponent: IComponentProviderModuleNaked['initializedFromComponent'];\n\n constructor(options: ComponentProviderModuleOptions) {\n const identifier = Symbol(`Component${options.identifier.description}`);\n const contextualizeImports = options.markAsGlobal ? false : options.contextualizeImports ?? true;\n const contextualizedImportsCache: Map<string, IProviderModule> | undefined = contextualizeImports\n ? new Map()\n : undefined;\n\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n defaultScope: options.defaultScope ?? InjectionScope.Singleton,\n identifier: identifier,\n imports: !contextualizeImports\n ? options.imports\n : options.imports?.map((imp) => {\n const module = (typeof imp === 'function' ? imp() : imp) as IComponentProviderModuleNaked;\n /* istanbul ignore next */\n if (!contextualizeImports) return module;\n\n return () => {\n const ctxModule = module._createContextualizedComponentInstance(identifier);\n\n contextualizedImportsCache!.set(module.originalIdentifier.toString(), ctxModule);\n\n return ctxModule;\n };\n }),\n dynamicExports: (_, exports) => {\n if (!contextualizeImports) return exports;\n\n return exports.map((exp) => {\n if (!(exp instanceof ProviderModule)) return exp;\n\n const cachedCtxModule = contextualizedImportsCache!.get(\n (exp as unknown as IComponentProviderModuleNaked).originalIdentifier.toString()\n )!;\n\n return cachedCtxModule;\n });\n },\n })\n );\n\n this.originalIdentifier = options.identifier;\n this.hasContextualizedImports = contextualizeImports;\n this.initializedFromComponent = false;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n override clone(options?: Partial<ComponentProviderModuleOptions>): IComponentProviderModule {\n const _options = options as ProviderModuleOptionsInternal;\n\n const clonedModule = new ComponentProviderModule(\n ProviderModuleHelpers.buildInternalConstructorParams({\n isAppModule: this.isAppModule,\n markAsGlobal: this.isMarkedAsGlobal,\n identifier: Symbol(this.identifier.description!.replace('Component', '')),\n defaultScope: this.defaultScope.native,\n dynamicExports: this.dynamicExports,\n onReady: this.onReady,\n onDispose: this.onDispose,\n contextualizeImports: this.hasContextualizedImports,\n importedProvidersMap: this.importedProvidersMap,\n imports: [...this.imports],\n providers: [...this.providers],\n exports: [...this.exports],\n ..._options,\n } as ComponentProviderModuleOptions)\n );\n\n //@ts-expect-error Read-only method.\n clonedModule.initializedFromComponent = this.initializedFromComponent;\n //@ts-expect-error Read-only method.\n clonedModule.registeredBindingSideEffects = new Map(this.registeredBindingSideEffects);\n\n return clonedModule;\n }\n\n //#region IComponentProviderModuleNaked methods\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._createContextualizedComponentInstance}.\n */\n protected _createContextualizedComponentInstance(parentIdentifier?: symbol): IComponentProviderModule {\n if (this.initializedFromComponent) return this;\n\n const ctxModule = this.clone().toNaked();\n\n /* istanbul ignore next */\n //@ts-expect-error Read-only property\n ctxModule.identifier = Symbol(\n `${parentIdentifier ? `[Importer:${parentIdentifier.description ?? 'Unknown'}]` : ''}Contextualized${ctxModule.identifier.description}`\n );\n ctxModule.initializedFromComponent = true;\n\n return ctxModule;\n }\n\n //#endregion\n}\n","import React from 'react';\n\nimport { ComponentProviderModuleHelpers, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\nconst ComponentRenderer = React.memo(_ComponentRenderer);\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * export const MyComponent = provideModuleToComponent<MyComponentProps>(\n * MyComponentModule,\n * ({ firstName, lastName }) => {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n * );\n *\n * function App() {\n * return <MyComponent firstName={'John'} lastName={'Doe'} />;\n * }\n * ```\n *\n * @param module The {@link IComponentProviderModule | Module} which should be consumed by the {@link component}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function provideModuleToComponent<\n P extends Record<string, any>,\n C extends ReactElementWithProviderModule<P> = ReactElementWithProviderModule<P>,\n>(module: IComponentProviderModule, component: ReactElementWithProviderModule<P>): C {\n return ((componentProps: PropsWithModule<P>) => {\n const moduleCtx = useContextualizedModule(module, componentProps);\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n <ComponentRenderer module={moduleCtx} componentProps={componentProps} component={component as any} />\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n }) as any;\n}\n\nfunction _ComponentRenderer<P extends Record<string, any>>({\n module,\n component,\n componentProps,\n}: {\n module: IComponentProviderModule;\n component: ReactElementWithProviderModule<P>;\n componentProps: P;\n}) {\n return <>{component(ComponentProviderModuleHelpers.forwardPropsWithModule(component, componentProps, module))}</>;\n}\n\nexport type ReactElementWithProviderModule<P extends Record<string, any>> = (p: PropsWithModule<P>) => React.ReactNode;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { useEffectOnce } from './use-effect-once';\n\nexport function useContextualizedModule(\n originalModule: IComponentProviderModule,\n componentProps?: PropsWithModule<object>\n): IComponentProviderModule {\n const ctxModule = useMemo(() => {\n /* istanbul ignore next */\n const { module: forwardedModule, inject } = componentProps ?? {};\n let module = (forwardedModule ?? originalModule).toNaked();\n\n if (module.isMarkedAsGlobal && inject) {\n throw new InjectionProviderModuleError(\n module,\n `The 'inject' prop can be used only with modules which are not marked as global!`\n );\n }\n\n if (!module.isMarkedAsGlobal) {\n module = module._createContextualizedComponentInstance().toNaked();\n }\n\n if (inject) {\n const sideEffectsOriginal = new Map(module.registeredSideEffects);\n module.registeredSideEffects.clear();\n\n inject.forEach((provider) => {\n module.__unbind(provider);\n\n module.moduleUtils.bindToContainer(provider, module.defaultScope.native);\n });\n\n //@ts-expect-error Read-only property.\n module.registeredBindingSideEffects = sideEffectsOriginal;\n }\n\n return module;\n }, [originalModule, componentProps?.inject]);\n\n useEffectOnce(() => {\n return () => {\n ctxModule.dispose();\n };\n });\n\n return ctxModule;\n}\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 { isFunction } from '@adimm/x-injection';\n\nimport type { ReactElementWithProviderModule } from '../core';\nimport type { IComponentProviderModule, PropsWithModule } from '../types';\n\nexport namespace ComponentProviderModuleHelpers {\n export function forwardPropsWithModule<P extends Record<string, any>>(\n component: ReactElementWithProviderModule<P> | React.ReactElement,\n props: Record<string, any>,\n module: IComponentProviderModule\n ): PropsWithModule<P> {\n const isReactElement = typeof component === 'object' && 'type' in component;\n\n const result = {\n ...props,\n } as any;\n\n if ((isReactElement && isFunction(component.type)) || isFunction(component)) {\n result['module'] = module;\n }\n\n return result;\n }\n}\n","import React, { useMemo } from 'react';\n\nimport { ComponentProviderModuleHelpers, useContextualizedModule } from '../../helpers';\nimport type { IComponentProviderModule, PropsWithModule } from '../../types';\nimport { REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT } from '../react-context';\n\n/**\n * Can be used to easily provide a {@link module} to any component.\n *\n * @example\n * ```tsx\n * interface MyComponentProps {\n * firstName: string;\n * lastName: string;\n * }\n *\n * function MyComponent({ firstName, lastName }: MyComponentProps) {\n * const service = useInject(MyComponentService);\n *\n * return <h1>Hello {service.computeUserName(firstName, lastName)}!</h1>\n * }\n *\n * function App() {\n * return (\n * <ProvideModule module={MyComponentModule}>\n * <MyComponent firstName={'John'} lastName={'Doe'} />\n * </ProvideModule>\n * );\n * }\n * ```\n *\n * @param param0 See {@link ProvideModuleFunctionParams}.\n * @returns The provided {@link toComponent | Component}.\n */\nexport function ProvideModule({ module, children }: ProvideModuleFunctionParams) {\n /* istanbul ignore next */\n const componentProps = (children.props ?? {}) as PropsWithModule<object>;\n const moduleCtx = useContextualizedModule(module, componentProps);\n const component = useMemo(\n () =>\n React.cloneElement(\n children,\n ComponentProviderModuleHelpers.forwardPropsWithModule(children, componentProps, moduleCtx)\n ),\n [componentProps, moduleCtx]\n );\n\n return (\n <REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider value={moduleCtx}>\n {component}\n </REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT.Provider>\n );\n}\n\nexport interface ProvideModuleFunctionParams {\n /** The {@link IComponentProviderModule | Module} which should be consumed by the {@link children | component}. */\n module: IComponentProviderModule;\n\n children: React.ReactElement;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useMemo } from 'react';\n\nimport { InjectionHookFactoryError } from '../errors';\nimport { useComponentModule } from './hooks';\n\nexport function hookFactory<P extends HookParams, D extends any[], T>({\n use: hook,\n inject,\n}: HookFactoryParams<P, D, T>): (p: P) => T {\n return (p: P) => {\n const componentModule = useComponentModule();\n\n const deps = useMemo(() => {\n if (inject.length === 0) {\n throw new InjectionHookFactoryError(componentModule, `The 'deps' property array is missing!`);\n }\n\n return componentModule.getMany(...inject);\n }, [inject]);\n\n return hook({ ...p, deps: [...deps] } as any);\n };\n}\n\nexport interface HookFactoryParams<P extends HookParams, D extends any[], T> {\n use: HookWithProviderModuleDependencies<P, D, T>;\n inject: ProviderToken[];\n}\n\nexport type HookWithProviderModuleDependencies<P extends HookParams, D extends any[], T> = (p: HookWithDeps<P, D>) => T;\n\nexport type HookWithDeps<P extends HookParams, D extends any[]> = P & {\n /** Array containing the resolved dependencies from the component context. */\n deps: D;\n};\n\ntype HookParams = Record<string, any> | void;\n","import { InjectionProviderModuleError } from '@adimm/x-injection';\n\nexport class InjectionHookFactoryError extends InjectionProviderModuleError {\n override name = InjectionHookFactoryError.name;\n}\n"],"mappings":"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","names":["AppModule","createContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useContext","useComponentModule","useContext","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","useInject","provider","options","componentModule","useComponentModule","get","isOptional","useInjectMany","deps","componentModule","useComponentModule","getMany","InjectionScope","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","originalIdentifier","hasContextualizedImports","initializedFromComponent","constructor","options","identifier","Symbol","description","contextualizeImports","markAsGlobal","contextualizedImportsCache","Map","undefined","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Singleton","imports","map","imp","module","ctxModule","_createContextualizedComponentInstance","set","toString","dynamicExports","_","exports","exp","cachedCtxModule","get","toNaked","clone","_options","clonedModule","isAppModule","isMarkedAsGlobal","replace","native","onReady","onDispose","importedProvidersMap","providers","registeredBindingSideEffects","parentIdentifier","React","InjectionProviderModuleError","useMemo","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContextualizedModule","originalModule","componentProps","ctxModule","useMemo","module","forwardedModule","inject","toNaked","isMarkedAsGlobal","InjectionProviderModuleError","_createContextualizedComponentInstance","sideEffectsOriginal","Map","registeredSideEffects","clear","forEach","provider","__unbind","moduleUtils","bindToContainer","defaultScope","native","registeredBindingSideEffects","useEffectOnce","dispose","isFunction","ComponentProviderModuleHelpers","forwardPropsWithModule","component","props","module","isReactElement","result","isFunction","type","ComponentRenderer","React","memo","_ComponentRenderer","provideModuleToComponent","module","component","componentProps","moduleCtx","useContextualizedModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","ComponentProviderModuleHelpers","forwardPropsWithModule","React","useMemo","ProvideModule","module","children","componentProps","props","moduleCtx","useContextualizedModule","component","useMemo","React","cloneElement","ComponentProviderModuleHelpers","forwardPropsWithModule","REACT_X_INJECTION_PROVIDER_MODULE_CONTEXT","Provider","value","useMemo","InjectionProviderModuleError","InjectionHookFactoryError","InjectionProviderModuleError","name","hookFactory","use","hook","inject","p","componentModule","useComponentModule","deps","useMemo","length","InjectionHookFactoryError","getMany"]}
|
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.
|
|
4
|
+
"version": "0.3.1",
|
|
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",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"v:bump-major": "npm version major -m \"chore: update lib major version %s\""
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@adimm/x-injection": "^0.
|
|
41
|
+
"@adimm/x-injection": "^0.8.0",
|
|
42
42
|
"react": ">=18.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|