@adimm/x-injection-reactjs 0.1.0 → 0.1.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 CHANGED
@@ -113,13 +113,18 @@ export const RandomNumberComponentModule = new ComponentProviderModule({
113
113
  });
114
114
 
115
115
  export function RandomNumberComponent(props: RandomNumberComponentProps) {
116
- // This hook is necessary in order to expose the component instance
117
- // context up to the parent component
118
- useExposeComponentModuleContext();
119
-
120
- const service = useInject(RandomNumberService);
121
-
122
- return <h1>A random number: {service.generate()}</h1>;
116
+ <ModuleProvider
117
+ module={RandomNumberComponentModule}
118
+ render={() => {
119
+ // This hook is necessary in order to expose the component instance
120
+ // context up to the parent component
121
+ useExposeComponentModuleContext();
122
+
123
+ const service = useInject(RandomNumberService);
124
+
125
+ return <h1>A random number: {service.generate()}</h1>;
126
+ }}
127
+ />;
123
128
  }
124
129
 
125
130
  ////////////////////////////////////////
@@ -139,39 +144,46 @@ export const ParentServiceComponentModule = new ComponentProviderModule({
139
144
  });
140
145
 
141
146
  export function ParentComponent(props: ParentComponentProps) {
142
- const service = useInject(ParentService);
143
-
144
147
  return (
145
- <>
146
- <TapIntoComponent
147
- // By using the fluid syntax
148
- contextInstance={() => ({
149
- // If one of the children did expose the `RandomNumberComponentModule`
150
- // module, we'll be able to access its instance.
151
- tryGet: RandomNumberComponentModule,
152
- thenDo: (ctx) => {
153
- const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
154
-
155
- service.injectRandomNumberService(randomNumberService_FromComponentInstance);
156
- },
157
- })}>
158
- <RandomNumberComponent />
159
- </TapIntoComponent>
160
-
161
- <TapIntoComponent
162
- // By accessing the entire underlying context map which may contain even more
163
- // modules exposed by more children down the tree.
164
- contextInstance={(ctxMap) => {
165
- const ctx = ctxMap.get(RandomNumberComponentModule.toString());
166
- if (!ctx) return;
167
-
168
- const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
169
-
170
- service.injectRandomNumberService(randomNumberService_FromComponentInstance);
171
- }}>
172
- <RandomNumberComponent />
173
- </TapIntoComponent>
174
- </>
148
+ <ModuleProvider
149
+ module={ParentServiceComponentModule}
150
+ render={() => {
151
+ const service = useInject(ParentService);
152
+
153
+ return (
154
+ <>
155
+ <TapIntoComponent
156
+ // By using the fluid syntax
157
+ contextInstance={() => ({
158
+ // If one of the children did expose the `RandomNumberComponentModule`
159
+ // module, we'll be able to access its instance.
160
+ tryGet: RandomNumberComponentModule,
161
+ thenDo: (ctx) => {
162
+ const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
163
+
164
+ service.injectRandomNumberService(randomNumberService_FromComponentInstance);
165
+ },
166
+ })}>
167
+ <RandomNumberComponent />
168
+ </TapIntoComponent>
169
+
170
+ <TapIntoComponent
171
+ // By accessing the entire underlying context map which may contain even more
172
+ // modules exposed by more children down the tree.
173
+ contextInstance={(ctxMap) => {
174
+ const ctx = ctxMap.get(RandomNumberComponentModule.toString());
175
+ if (!ctx) return;
176
+
177
+ const randomNumberService_FromComponentInstance = ctx.get(RandomNumberComponentModule);
178
+
179
+ service.injectRandomNumberService(randomNumberService_FromComponentInstance);
180
+ }}>
181
+ <RandomNumberComponent />
182
+ </TapIntoComponent>
183
+ </>
184
+ );
185
+ }}
186
+ />
175
187
  );
176
188
  }
177
189
  ```
@@ -183,32 +195,57 @@ or introduce unknown bugs, please use it carefully and with diligence!
183
195
 
184
196
  ```tsx
185
197
  export function ParentComponent(props: ParentComponentProps) {
186
- // By using this hook, the component will always re-render whenever
187
- // a child using a ProviderModule which is also imported into the parent ProviderModule,
188
- // has mounted and rendered!
189
- useRerenderOnChildrenModuleContextLoaded();
190
-
191
- // We should use the `useInjectOnRender` instead of the default `useInject`
192
- // hook which re-uses the same instance of the injected dependency
193
- // between re-renders.
194
- //
195
- // Note: It may still work with the `useInject` hook too, but it may not be predictable.
196
- const service = useInjectOnRender(ParentService);
197
-
198
- // At this point the `service.randomNumberService` instance should be the one
199
- // from the `RandomNumberComponent` below.
200
- //
201
- // Note: Expect during the 1st render cycle to not be the same instance as the one used by the child component!
202
- // The `xInjection` container will still supply the correct provider to the
203
- // constructor parameter, but it'll be a new transient instance.
204
- console.log(service.randomNumberService.generate());
205
-
206
- // As we are now using the `useRerenderOnChildrenModuleContextLoaded` hook
207
- // there's no need anymore for the `TapIntoComponent` wrapper.
208
- return <RandomNumberComponent />;
198
+ return (
199
+ <ModuleProvder
200
+ module={ParentServiceComponentModule}
201
+ render={() => {
202
+ // By using this hook, the component will always re-render whenever
203
+ // a child using a ProviderModule which is also imported into the parent ProviderModule,
204
+ // has mounted and rendered!
205
+ useRerenderOnChildrenModuleContextLoaded();
206
+
207
+ // We should use the `useInjectOnRender` instead of the default `useInject`
208
+ // hook which re-uses the same instance of the injected dependency
209
+ // between re-renders.
210
+ //
211
+ // Note: It may still work with the `useInject` hook too, but it may not be predictable.
212
+ const service = useInjectOnRender(ParentService);
213
+
214
+ // At this point the `service.randomNumberService` instance should be the one
215
+ // from the `RandomNumberComponent` below.
216
+ //
217
+ // Note: Expect during the 1st render cycle to not be the same instance as the one used by the child component!
218
+ // The `xInjection` container will still supply the correct provider to the
219
+ // constructor parameter, but it'll be a new transient instance.
220
+ console.log(service.randomNumberService.generate());
221
+
222
+ // As we are now using the `useRerenderOnChildrenModuleContextLoaded` hook
223
+ // there's no need anymore for the `TapIntoComponent` wrapper.
224
+ return <RandomNumberComponent />;
225
+ }}
226
+ />
227
+ );
209
228
  }
210
229
  ```
211
230
 
231
+ The `ModuleProvider` component also accepts the `children` prop, this means you can also use it like this:
232
+
233
+ ```tsx
234
+ export function Component() {
235
+ return <h1>Hello World!</h1>;
236
+ }
237
+
238
+ function MyApp() {
239
+ return (
240
+ <ModuleProvider module={ComponentModule}>
241
+ <Component />
242
+ </ModuleProvider>
243
+ );
244
+ }
245
+ ```
246
+
247
+ > **Note:** You don't have to wrap your entire application with a `ModuleProvider` which provides the `AppModule`, the global container is already available to use and all your `ComponentProviderModule` know ouf-of-the-box how to access it when you provide them with providers registered into the `AppModule`.
248
+
212
249
  ## Documentation
213
250
 
214
251
  Comprehensive, auto-generated documentation is available at:
package/dist/index.cjs CHANGED
@@ -62,21 +62,21 @@ C.createContext)(p.AppModule), f = (0, C.createContext)(new Map), O = (0, C.crea
62
62
  r: 0
63
63
  }), x = require("react");
64
64
 
65
- function M({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUnmount: o}) {
66
- const r = t.toNaked().isAppModule, i = {
67
- ctx: (0, x.useMemo)((() => r ? t : t.toNaked()._convertToContextualizedComponentInstance()), [ e, t, n, o ])
65
+ function M({children: e, render: t, module: n, tryReInitModuleOnMount: o, disposeModuleOnUnmount: r}) {
66
+ const i = n.toNaked().isAppModule, u = (0, x.useCallback)((() => t?.()), []), s = {
67
+ ctx: i ? n : n.toNaked()._convertToContextualizedComponentInstance()
68
68
  };
69
69
  return React.createElement(m.Provider, {
70
- value: i
70
+ value: s
71
71
  }, React.createElement(O.Provider, {
72
72
  value: {
73
73
  r: 0
74
74
  }
75
75
  }, React.createElement(_, {
76
- children: e,
77
- module: i,
78
- tryReInitModuleOnMount: n,
79
- disposeModuleOnUnmount: o
76
+ children: e ?? React.createElement(u, null),
77
+ module: s,
78
+ tryReInitModuleOnMount: o,
79
+ disposeModuleOnUnmount: r
80
80
  })));
81
81
  }
82
82
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["export * from './core';\nexport type * from './types';\n","import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useContext, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n\n const moduleCtxReference = {\n ctx: useMemo(() => {\n return isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance();\n }, [children, module, tryReInitModuleOnMount, disposeModuleOnUnmount]),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["useOnce","fn","ref","useRef","current","value","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","import_react","import_react","REACT_X_INJECTION_CONTEXT","createContext","AppModule","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","import_react","ModuleProvider","children","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","moduleCtxReference","ctx","useMemo","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","import_react","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","import_react","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","import_react","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","import_x_injection","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","import_react","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["export * from './core';\nexport type * from './types';\n","import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useCallback, useContext } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n render,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n const Renderer = useCallback(() => render?.(), []);\n\n const moduleCtxReference = {\n ctx: isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance(),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children ?? <Renderer />}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["useOnce","fn","ref","useRef","current","value","import_react","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","import_react","import_react","REACT_X_INJECTION_CONTEXT","createContext","AppModule","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","import_react","ModuleProvider","children","render","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","Renderer","useCallback","moduleCtxReference","ctx","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","import_react","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","import_react","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","import_react","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","import_x_injection","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","import_react","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
package/dist/index.d.cts CHANGED
@@ -124,7 +124,8 @@ declare const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE: react.
124
124
  }>;
125
125
 
126
126
  interface ModuleProviderProps {
127
- children: React.ReactNode;
127
+ children?: React.ReactNode;
128
+ render?: () => React.ReactNode;
128
129
  /** The {@link IComponentProviderModule | ComponentProviderModule} instance which must be accessible by this component. */
129
130
  module: IComponentProviderModule;
130
131
  /**
@@ -150,7 +151,7 @@ interface ModuleProviderProps {
150
151
  disposeModuleOnUnmount?: boolean;
151
152
  }
152
153
 
153
- declare function ModuleProvider({ children, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
154
+ declare function ModuleProvider({ children, render, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
154
155
 
155
156
  /** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
156
157
  declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
package/dist/index.d.ts CHANGED
@@ -124,7 +124,8 @@ declare const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE: react.
124
124
  }>;
125
125
 
126
126
  interface ModuleProviderProps {
127
- children: React.ReactNode;
127
+ children?: React.ReactNode;
128
+ render?: () => React.ReactNode;
128
129
  /** The {@link IComponentProviderModule | ComponentProviderModule} instance which must be accessible by this component. */
129
130
  module: IComponentProviderModule;
130
131
  /**
@@ -150,7 +151,7 @@ interface ModuleProviderProps {
150
151
  disposeModuleOnUnmount?: boolean;
151
152
  }
152
153
 
153
- declare function ModuleProvider({ children, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
154
+ declare function ModuleProvider({ children, render, module, tryReInitModuleOnMount, disposeModuleOnUnmount, }: ModuleProviderProps): react_jsx_runtime.JSX.Element;
154
155
 
155
156
  /** A superset of the {@link ProviderModule} used to integrate within a `React` component. */
156
157
  declare class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {
package/dist/index.js CHANGED
@@ -32,32 +32,32 @@ import { AppModule as a } from "@adimm/x-injection";
32
32
 
33
33
  import { createContext as d } from "react";
34
34
 
35
- var p = d(a), l = d(new Map), m = d({
35
+ var l = d(a), p = d(new Map), m = d({
36
36
  r: 0
37
37
  });
38
38
 
39
- import { useContext as f, useMemo as x } from "react";
39
+ import { useCallback as f, useContext as x } from "react";
40
40
 
41
- function C({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUnmount: o}) {
42
- const r = t.toNaked().isAppModule, i = {
43
- ctx: x((() => r ? t : t.toNaked()._convertToContextualizedComponentInstance()), [ e, t, n, o ])
41
+ function C({children: e, render: t, module: n, tryReInitModuleOnMount: o, disposeModuleOnUnmount: r}) {
42
+ const i = n.toNaked().isAppModule, s = f((() => t?.()), []), c = {
43
+ ctx: i ? n : n.toNaked()._convertToContextualizedComponentInstance()
44
44
  };
45
- return React.createElement(p.Provider, {
46
- value: i
45
+ return React.createElement(l.Provider, {
46
+ value: c
47
47
  }, React.createElement(m.Provider, {
48
48
  value: {
49
49
  r: 0
50
50
  }
51
51
  }, React.createElement(v, {
52
- children: e,
53
- module: i,
54
- tryReInitModuleOnMount: n,
55
- disposeModuleOnUnmount: o
52
+ children: e ?? React.createElement(s, null),
53
+ module: c,
54
+ tryReInitModuleOnMount: o,
55
+ disposeModuleOnUnmount: r
56
56
  })));
57
57
  }
58
58
 
59
59
  function v({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUnmount: o = !1}) {
60
- const r = f(l), i = f(m);
60
+ const r = x(p), i = x(m);
61
61
  return c((() => {
62
62
  const e = t.ctx.toNaked();
63
63
  if (r) {
@@ -74,7 +74,7 @@ function v({children: e, module: t, tryReInitModuleOnMount: n, disposeModuleOnUn
74
74
  }
75
75
 
76
76
  function M(e, t) {
77
- return u(p).ctx.get(e, t?.isOptional);
77
+ return u(l).ctx.get(e, t?.isOptional);
78
78
  }
79
79
 
80
80
  function h(e, t) {
@@ -87,7 +87,7 @@ t(h, "useInject");
87
87
  import { useContext as I } from "react";
88
88
 
89
89
  function O({deps: e}) {
90
- return I(p).ctx.getMany(...e);
90
+ return I(l).ctx.getMany(...e);
91
91
  }
92
92
 
93
93
  function g({deps: e, options: t}) {
@@ -99,14 +99,14 @@ function g({deps: e, options: t}) {
99
99
 
100
100
  t(O, "useInjectManyOnRender"), t(g, "useInjectMany");
101
101
 
102
- import { useContext as _ } from "react";
102
+ import { useContext as R } from "react";
103
103
 
104
- function R() {
105
- const e = _(p);
106
- _(l).set(e.ctx.toString(), e.ctx);
104
+ function _() {
105
+ const e = R(l);
106
+ R(p).set(e.ctx.toString(), e.ctx);
107
107
  }
108
108
 
109
- t(R, "useExposeComponentModuleContext");
109
+ t(_, "useExposeComponentModuleContext");
110
110
 
111
111
  import { useContext as S, useEffect as y, useState as E } from "react";
112
112
 
@@ -164,7 +164,7 @@ import { useContext as T, useEffect as w, useMemo as F } from "react";
164
164
 
165
165
  function U({children: e, contextInstance: t}) {
166
166
  const n = F((() => new Map), []);
167
- return React.createElement(l.Provider, {
167
+ return React.createElement(p.Provider, {
168
168
  value: n
169
169
  }, React.createElement(A, {
170
170
  contextInstance: t
@@ -172,7 +172,7 @@ function U({children: e, contextInstance: t}) {
172
172
  }
173
173
 
174
174
  function A({contextInstance: e}) {
175
- const t = T(l);
175
+ const t = T(p);
176
176
  return w((() => {
177
177
  const n = e?.(t);
178
178
  if (!n) return;
@@ -183,4 +183,4 @@ function A({contextInstance: e}) {
183
183
 
184
184
  t(U, "TapIntoComponent"), t(A, "CtxExposer");
185
185
 
186
- export { D as ComponentProviderModule, C as ModuleProvider, p as REACT_X_INJECTION_CONTEXT, l as REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT, m as REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE, U as TapIntoComponent, R as useExposeComponentModuleContext, h as useInject, g as useInjectMany, O as useInjectManyOnRender, M as useInjectOnRender, j as useRerenderOnChildrenModuleContextLoaded };//# sourceMappingURL=index.js.map
186
+ export { D as ComponentProviderModule, C as ModuleProvider, l as REACT_X_INJECTION_CONTEXT, p as REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT, m as REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE, U as TapIntoComponent, _ as useExposeComponentModuleContext, h as useInject, g as useInjectMany, O as useInjectManyOnRender, M as useInjectOnRender, j as useRerenderOnChildrenModuleContextLoaded };//# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useContext, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n\n const moduleCtxReference = {\n ctx: useMemo(() => {\n return isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance();\n }, [children, module, tryReInitModuleOnMount, disposeModuleOnUnmount]),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["useRef","useOnce","fn","ref","useRef","current","value","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContext","AppModule","createContext","REACT_X_INJECTION_CONTEXT","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","useContext","useMemo","ModuleProvider","children","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","moduleCtxReference","ctx","useMemo","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","useContext","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","useContext","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","useContext","useEffect","useState","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","InjectionScope","isClass","isClassOrFunction","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","useContext","useEffect","useMemo","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
1
+ {"version":3,"sources":["../src/helpers/hooks/use-once.ts","../src/helpers/hooks/use-effect-once.ts","../src/core/hooks/use-inject-on-render.ts","../src/core/providers/module-provider/react-context.ts","../src/core/providers/module-provider/module.provider.tsx","../src/core/hooks/use-inject.ts","../src/core/hooks/use-inject-many-on-render.ts","../src/core/hooks/use-inject-many.ts","../src/core/hooks/use-expose-component-module-context.ts","../src/core/hooks/use-rerender-on-children-module-context-loaded.ts","../src/core/component-provider-module.ts","../src/core/utils/tap-into-component-context/tap-into-component-context.tsx"],"sourcesContent":["import { useRef } from 'react';\n\nexport function useOnce<T>(fn: () => T): T {\n const ref = useRef<OnceValue<T> | null>(null);\n\n if (ref.current === null) {\n ref.current = { value: fn() };\n }\n\n return ref.current?.value;\n}\n\ntype OnceValue<T> = { value: T };\n","import { useEffect, useRef, useState } from 'react';\n\n// Credits: https://stackoverflow.com/a/74000921\n\n/** Custom {@link useEffect} hook which will be run once. _(In `StrictMode` as well)_ */\nexport function useEffectOnce(effect: () => React.EffectCallback) {\n const destroyFunc = useRef<React.EffectCallback>(undefined);\n const effectCalled = useRef(false);\n const renderAfterCalled = useRef(false);\n const [, forceRerender] = useState(0);\n\n if (effectCalled.current) renderAfterCalled.current = true;\n\n useEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect();\n effectCalled.current = true;\n }\n\n // this forces one render after the effect is run\n forceRerender((x) => x + 1);\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) return;\n\n destroyFunc.current?.();\n };\n }, []);\n}\n","import type { ProviderToken } from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected on each re-render process._\n * _If you need to inject the dependency only once, you must use the `useInject` hook._\n * _It basically acts like a `Transient` scope, ensuring that a new dependency is injected on each re-render._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInjectOnRender<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.get(provider, options?.isOptional);\n}\n\nexport type UseInjectOptions = UseInjectSharedOptions & {\n /** When set to `false` _(default)_ an exception will be thrown when the `providerOrIdentifier` isn't bound. */\n isOptional?: boolean;\n};\n","import { AppModule } from '@adimm/x-injection';\nimport { createContext } from 'react';\n\nimport type { IComponentProviderModule } from '../../../types';\n\n/**\n * The `React.Context` value to be provided to a `React.Provider`.\n *\n * Its default value is a reference to the {@link AppModule}.\n */\nexport const REACT_X_INJECTION_CONTEXT = createContext<{ ctx: IComponentProviderModule }>(AppModule as any);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT = createContext<Map<string, IComponentProviderModule>>(\n new Map()\n);\n\nexport const REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE = createContext<{ r: number }>({ r: 0 });\n","import { useCallback, useContext } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { useEffectOnce } from '../../../helpers';\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../../../types';\nimport type { ModuleProviderProps } from './models';\nimport {\n REACT_X_INJECTION_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT,\n REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE,\n} from './react-context';\n\nexport function ModuleProvider({\n children,\n render,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount,\n}: ModuleProviderProps) {\n const isAppModule = module.toNaked().isAppModule;\n const Renderer = useCallback(() => render?.(), []);\n\n const moduleCtxReference = {\n ctx: isAppModule ? module : module.toNaked()._convertToContextualizedComponentInstance(),\n };\n\n return (\n <REACT_X_INJECTION_CONTEXT.Provider value={moduleCtxReference}>\n <REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider value={{ r: 0 }}>\n <XInjectionChildrenRenderer\n children={children ?? <Renderer />}\n module={moduleCtxReference}\n tryReInitModuleOnMount={tryReInitModuleOnMount}\n disposeModuleOnUnmount={disposeModuleOnUnmount}\n />\n </REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE.Provider>\n </REACT_X_INJECTION_CONTEXT.Provider>\n );\n}\n\nfunction XInjectionChildrenRenderer({\n children,\n module,\n tryReInitModuleOnMount,\n disposeModuleOnUnmount = false,\n}: Except<ModuleProviderProps, 'module'> & { module: { ctx: IComponentProviderModule } }) {\n const componentModuleInstance = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n\n // We use the `useEffectOnce` custom hook in order\n // to make sure that if the developer is providing the\n // `tryReInitModuleOnMount` and/or `disposeModuleOnUnmount` options\n // we do not early dispose the module when React double re-renders the\n // component while StrictMode is enabled.\n // This hook guarantees that the same behavior is expected with or without StrictMode.\n //\n // https://react.dev/reference/react/StrictMode\n useEffectOnce(() => {\n // ON MOUNT\n\n const moduleNaked = module.ctx.toNaked();\n\n if (componentModuleInstance) {\n const contextualizedImportedModules = module.ctx.toNaked().imports.map((importedModule) => {\n const shouldReplaceImportedModuleWithContextualized =\n componentModuleInstance.get(importedModule.toString())?.toString() === importedModule.toString();\n\n /* istanbul ignore next */\n if (!shouldReplaceImportedModuleWithContextualized)\n return importedModule as unknown as IComponentProviderModuleNaked;\n\n return componentModuleInstance.get(importedModule.toString()) as IComponentProviderModuleNaked;\n });\n\n if (contextualizedImportedModules.length > 0) {\n module.ctx.toNaked()._lazyInit({\n ...module.ctx.toNaked()._initialOptions,\n imports: contextualizedImportedModules,\n });\n\n // This will force the parent to re-render when using the `useRerenderOnChildrenModuleContextLoaded` hook.\n rerenderParentCtx.r++;\n }\n }\n\n /* istanbul ignore next */\n if (moduleNaked.isDisposed && tryReInitModuleOnMount) {\n /* istanbul ignore next */\n moduleNaked._lazyInit(tryReInitModuleOnMount);\n }\n\n return () => {\n // ON UNMOUNT\n\n if (!disposeModuleOnUnmount || moduleNaked.isDisposed) return;\n\n moduleNaked._dispose();\n };\n });\n\n return children;\n}\n","import type { ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport { useInjectOnRender, type UseInjectOptions } from './use-inject-on-render';\n\n/**\n * React `hook` which can be used inside a component to inject the required {@link provider | dependency}.\n *\n * **Note:** _By using this hook, the dependency will be injected only once after the first component mount process._\n * _If you need to re-inject the dependency on each re-render, you must use the `useInjectOnRender` hook._\n * _It basically acts like a `Request` scope, ensuring that even a `Transient` dependency does not mutate during re-renders._\n *\n * @param provider The {@link ProviderToken}.\n * @param options See {@link UseInjectSharedOptions}.\n * @returns Either the {@link T | dependency} or `undefined` if {@link isOptional} is set to `true`.\n */\nexport function useInject<T>(provider: ProviderToken<T>, options?: UseInjectOptions): T {\n return useOnce(() => useInjectOnRender(provider, options));\n}\n","import type {\n ProviderModuleGetManyParam,\n ProviderModuleGetManySignature,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ProviderToken,\n} from '@adimm/x-injection';\nimport { useContext } from 'react';\n\nimport type { UseInjectSharedOptions } from '../../types';\nimport { REACT_X_INJECTION_CONTEXT } from '../providers';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected on each re-render process._\n * _If you need to inject the dependencies only once, you must use the `useInjectMany` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectManyOnRender<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n\n return componentModule.ctx.getMany(...deps);\n}\n","import type { ProviderModuleGetManyParam, ProviderModuleGetManySignature, ProviderToken } from '@adimm/x-injection';\n\nimport { useOnce } from '../../helpers';\nimport type { UseInjectSharedOptions } from '../../types';\nimport { useInjectManyOnRender } from './use-inject-many-on-render';\n\n/**\n * Can be used to retrieve many resolved `dependencies` from the module container at once.\n *\n * **Note:** _By using this hook, the dependencies will be injected only once after the first component mount process._\n * _If you need to re-inject the dependencies on each re-render, you must use the `useInjectManyOnRender` hook._\n *\n * @param options See {@link UseInjectSharedOptions}.\n * @param deps Either one or more {@link ProviderToken}.\n * @returns Tuple containing the {@link D | dependencies}.\n */\nexport function useInjectMany<D extends (ProviderModuleGetManyParam<any> | ProviderToken)[]>({\n deps,\n options,\n}: {\n deps: [...(D | unknown[])];\n options?: UseInjectSharedOptions;\n}): ProviderModuleGetManySignature<D> {\n return useOnce(() => useInjectManyOnRender({ options, deps }));\n}\n","import { useContext } from 'react';\n\nimport { REACT_X_INJECTION_CONTEXT, REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../providers';\n\nexport function useExposeComponentModuleContext(): void {\n const componentModule = useContext(REACT_X_INJECTION_CONTEXT);\n const exposed = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n exposed.set(componentModule.ctx.toString(), componentModule.ctx);\n}\n","import { useContext, useEffect, useState } from 'react';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE } from '../providers';\n\n/**\n * This is an **experimental** hook which can be used to make sure that a component will re-render when a children\n * exposes its internal context module.\n *\n * It works best with the `useInjectOnRender` hook, as it'll re-resolve all the required dependencies\n * of the injected ProviderToken.\n *\n * **Use it carefully as it may lead to unnecessary re-render cycles or it may even not work as expected!**\n * **It's safer to use the `TapIntoComponent` wrapper component with the `contextInstance` to manually inject the**\n * **contextualized dependencies of the children into a parent component service!**\n *\n * @experimental\n */\nexport function useRerenderOnChildrenModuleContextLoaded(): void {\n const rerenderParentCtx = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE);\n const [, setRerender] = useState(0);\n\n useEffect(() => {\n setRerender((x) => x + 1);\n }, [rerenderParentCtx.r]);\n}\n","import {\n InjectionScope,\n isClass,\n isClassOrFunction,\n ProviderModule,\n ProviderModuleHelpers,\n type DependencyProvider,\n type IProviderModuleNaked,\n type ProviderClassToken,\n type ProviderModuleOptions,\n type ProviderValueToken,\n} from '@adimm/x-injection';\n\nimport type { IComponentProviderModule, IComponentProviderModuleNaked } from '../types';\n\n/** A superset of the {@link ProviderModule} used to integrate within a `React` component. */\nexport class ComponentProviderModule extends ProviderModule implements IComponentProviderModule {\n protected readonly _initializedFromComponent: IComponentProviderModuleNaked['_initializedFromComponent'];\n protected readonly _initialOptions: IComponentProviderModuleNaked['_initialOptions'];\n\n constructor(options: ProviderModuleOptions) {\n super(\n ProviderModuleHelpers.buildInternalConstructorParams({\n ...options,\n // By default components should have all their providers\n // defined as transient because a component may have more than one instance of itself.\n defaultScope: options.defaultScope ?? InjectionScope.Transient,\n identifier: Symbol(`Component${options.identifier.description}`),\n })\n );\n\n this._initializedFromComponent = false;\n this._initialOptions = options;\n }\n\n override toNaked(): IComponentProviderModuleNaked & IProviderModuleNaked {\n return this as any;\n }\n\n /* istanbul ignore next */\n dispose(): void {\n this._dispose();\n }\n\n /**\n * **Publicly visible when the instance is casted to {@link IComponentProviderModuleNaked}.**\n *\n * See {@link IComponentProviderModuleNaked._convertToContextualizedComponentInstance}.\n */\n /* istanbul ignore next */\n protected _convertToContextualizedComponentInstance(): IComponentProviderModule {\n if (this.isAppModule || this.isDisposed) return this;\n\n const contextualizedProviders = this._getProviders().map((provider) => {\n if (!isClassOrFunction(provider)) {\n return {\n ...provider,\n scope: InjectionScope.Singleton,\n } as DependencyProvider;\n }\n\n if (isClass(provider)) {\n return {\n scope: InjectionScope.Singleton,\n provide: provider,\n useClass: provider,\n } as ProviderClassToken<any>;\n }\n\n return {\n provide: provider,\n useValue: provider,\n } as ProviderValueToken<any>;\n });\n\n const componentModule = new ComponentProviderModule({\n ...this._initialOptions,\n providers: contextualizedProviders,\n });\n\n //@ts-expect-error Read-only property.\n componentModule._initializedFromComponent = true;\n\n return componentModule;\n }\n}\n","import { useContext, useEffect, useMemo } from 'react';\nimport type { Except } from 'type-fest';\n\nimport { REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT } from '../../providers';\nimport type { TapIntoComponentContextProps } from './interfaces';\n\n/**\n * This component is the standard way to \"tap into\" an instance of the component\n * in order to get access to its scoped module container and its _(exposed)_ dependencies _instances_.\n *\n * @param contextInstance See {@link TapIntoComponentContextProps.contextInstance}.\n * @param exposed See {@link TapIntoComponentContextProps.exposed}.\n */\nexport function TapIntoComponent({ children, contextInstance }: TapIntoComponentContextProps) {\n const moduleContextMap = useMemo(() => new Map(), []);\n\n return (\n <REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider value={moduleContextMap}>\n <CtxExposer contextInstance={contextInstance} />\n {children}\n </REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT.Provider>\n );\n}\n\nfunction CtxExposer({ contextInstance }: Except<TapIntoComponentContextProps, 'children'>) {\n const ctxMap = useContext(REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT);\n\n useEffect(() => {\n const fluidSyntax = contextInstance?.(ctxMap);\n if (!fluidSyntax) return;\n\n const moduleCtx = ctxMap.get(fluidSyntax.tryGet.toString());\n /* istanbul ignore next */\n if (!moduleCtx) return;\n\n fluidSyntax.thenDo(moduleCtx);\n }, [ctxMap]);\n\n return null;\n}\n"],"mappings":"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","names":["useRef","useOnce","fn","ref","useRef","current","value","useEffect","useRef","useState","useEffectOnce","effect","destroyFunc","useRef","undefined","effectCalled","renderAfterCalled","forceRerender","useState","current","useEffect","x","useContext","AppModule","createContext","REACT_X_INJECTION_CONTEXT","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","useCallback","useContext","ModuleProvider","children","render","module","tryReInitModuleOnMount","disposeModuleOnUnmount","isAppModule","toNaked","Renderer","useCallback","moduleCtxReference","ctx","_convertToContextualizedComponentInstance","REACT_X_INJECTION_CONTEXT","Provider","value","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","r","XInjectionChildrenRenderer","componentModuleInstance","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","rerenderParentCtx","useEffectOnce","moduleNaked","contextualizedImportedModules","imports","map","importedModule","shouldReplaceImportedModuleWithContextualized","get","toString","length","_lazyInit","_initialOptions","isDisposed","_dispose","useInjectOnRender","provider","options","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","get","isOptional","useInject","provider","options","useOnce","useInjectOnRender","useContext","useInjectManyOnRender","deps","componentModule","useContext","REACT_X_INJECTION_CONTEXT","ctx","getMany","useInjectMany","deps","options","useOnce","useInjectManyOnRender","useContext","useExposeComponentModuleContext","componentModule","useContext","REACT_X_INJECTION_CONTEXT","exposed","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","set","ctx","toString","useContext","useEffect","useState","useRerenderOnChildrenModuleContextLoaded","rerenderParentCtx","useContext","REACT_X_INJECTION_EXPOSED_COMPONENT_RERENDER_ON_CTX_CHANGE","setRerender","useState","useEffect","x","r","InjectionScope","isClass","isClassOrFunction","ProviderModule","ProviderModuleHelpers","ComponentProviderModule","ProviderModule","_initializedFromComponent","_initialOptions","constructor","options","ProviderModuleHelpers","buildInternalConstructorParams","defaultScope","InjectionScope","Transient","identifier","Symbol","description","toNaked","dispose","_dispose","_convertToContextualizedComponentInstance","isAppModule","isDisposed","contextualizedProviders","_getProviders","map","provider","isClassOrFunction","scope","Singleton","isClass","provide","useClass","useValue","componentModule","providers","useContext","useEffect","useMemo","TapIntoComponent","children","contextInstance","moduleContextMap","useMemo","Map","REACT_X_INJECTION_EXPOSED_COMPONENT_MODULE_CONTEXT","Provider","value","CtxExposer","ctxMap","useContext","useEffect","fluidSyntax","moduleCtx","get","tryGet","toString","thenDo"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adimm/x-injection-reactjs",
3
3
  "description": "ReactJS integration of the `xInjection` library.",
4
- "version": "0.1.0",
4
+ "version": "0.1.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",