diff --git a/packages/injectable/core/index.d.ts b/packages/injectable/core/index.d.ts index 85e084d8..1dd4cd16 100644 --- a/packages/injectable/core/index.d.ts +++ b/packages/injectable/core/index.d.ts @@ -189,19 +189,29 @@ export const lifecycleEnum: { }; }; -type Decorator = InjectionToken< - { decorate: (toBeDecorated: unknown) => typeof toBeDecorated }, - unknown ->; - type RegistrationCallback = (injectable: Injectable) => void; -type TargetableDecorator = Decorator & { - target?: Injectable | InjectionToken; +export type InjectionTargetDecorator = { + decorate: (instance: InjectionInstance) => InjectionInstance; +}; + +export type InstantiationTargetDecorator< + InjectionInstance extends InjectionTokenInstance, + InjectionTokenInstance = InjectionInstance, + InstantiationParam = void, +> = { + decorate: (instantiate: Instantiate) => Instantiate; + target: InjectionToken | Injectable; }; -export const injectionDecoratorToken: TargetableDecorator; -export const instantiationDecoratorToken: TargetableDecorator; +export const createInstantiationTargetDecorator: < + InjectionInstance extends InjectionTokenInstance, + InjectionTokenInstance = InjectionInstance, + InstantiationParam = void, +>(desc: InstantiationTargetDecorator) => InstantiationTargetDecorator; + +export const injectionDecoratorToken: InjectionToken, void>; +export const instantiationDecoratorToken: InjectionToken, void>; export const registrationCallbackToken: RegistrationCallback; export const deregistrationCallbackToken: RegistrationCallback; export const isInjectable: (thing: any) => boolean; diff --git a/packages/injectable/core/index.js b/packages/injectable/core/index.js index 66ce9abe..3bfe5f2d 100644 --- a/packages/injectable/core/index.js +++ b/packages/injectable/core/index.js @@ -7,21 +7,18 @@ import createContainer from './src/dependency-injection-container/createContaine import isInjectable from './src/getInjectable/isInjectable'; import isInjectionToken from './src/getInjectionToken/isInjectionToken'; -import { + +export { deregistrationCallbackToken, injectionDecoratorToken, + createInstantiationTargetDecorator, instantiationDecoratorToken, registrationCallbackToken, } from './src/dependency-injection-container/tokens'; - export { createContainer, getInjectable, getInjectionToken, - injectionDecoratorToken, - instantiationDecoratorToken, - registrationCallbackToken, - deregistrationCallbackToken, isInjectable, isInjectionToken, lifecycleEnum, diff --git a/packages/injectable/core/index.test-d.ts b/packages/injectable/core/index.test-d.ts index f3b3cb4d..889912ea 100644 --- a/packages/injectable/core/index.test-d.ts +++ b/packages/injectable/core/index.test-d.ts @@ -6,11 +6,35 @@ import { DiContainerForInjection, getInjectable, getInjectionToken, + instantiationDecoratorToken, + createInstantiationTargetDecorator, lifecycleEnum, } from '.'; const di = createContainer('some-container'); +const someGetNumberInjectionToken = getInjectionToken<() => number>({ + id: "some-get-number-token", +}); + +const decorateSomeGetNumberInjectable = getInjectable({ + id: "decorate-some-get-number", + decorable: false, + instantiate: () => createInstantiationTargetDecorator({ + target: someGetNumberInjectionToken, + decorate: (someGetNumberInstantiate) => (di) => { + const someGetNumber = someGetNumberInstantiate(di); + + return () => { + console.log("some other thing"); + + return someGetNumber(); + } + }, + }), + injectionToken: instantiationDecoratorToken, +}) + // given injectable with unspecified type for instantiation parameter, argument typing is OK const someInjectableForTypingOfInstantiate = getInjectable({ id: 'some-injectable', diff --git a/packages/injectable/core/src/dependency-injection-container/tokens.js b/packages/injectable/core/src/dependency-injection-container/tokens.js index d9b48ffe..ed10c2be 100644 --- a/packages/injectable/core/src/dependency-injection-container/tokens.js +++ b/packages/injectable/core/src/dependency-injection-container/tokens.js @@ -10,6 +10,8 @@ export const deregistrationCallbackToken = getInjectionToken({ decorable: false, }); +export const createInstantiationTargetDecorator = desc => desc; + export const instantiationDecoratorToken = getInjectionToken({ id: 'instantiate-decorator-token', decorable: false, diff --git a/packages/injectable/extension-for-dependency-graphing/src/__snapshots__/dependency-graphing.test.js.snap b/packages/injectable/extension-for-dependency-graphing/src/__snapshots__/dependency-graphing.test.js.snap index add35d00..5b0b0277 100644 --- a/packages/injectable/extension-for-dependency-graphing/src/__snapshots__/dependency-graphing.test.js.snap +++ b/packages/injectable/extension-for-dependency-graphing/src/__snapshots__/dependency-graphing.test.js.snap @@ -3,19 +3,19 @@ exports[`createContainer.dependency-graph given dependency graphing, dependencies and injected, creates Plant-UML graph 1`] = ` "@startuml hide members -class "some-token-injectable" as someTokenInjectable << (S,lightGreen) >> $some-token-injectable $some-container $some-parent-injectable $some-sync-child-injectable $some-injection-token #line:darkRed -class "some-customizable-sync-injectable" as someCustomizableSyncInjectable << (S,lightGreen) >> $some-customizable-sync-injectable $some-container $some-parent-injectable $some-sync-child-injectable $some-injection-token #line:darkRed -class "some-injection-token" as someInjectionToken << (X,orange) >> $some-injection-token $some-container $some-parent-injectable $some-sync-child-injectable #line:green -class "some-sync-child-injectable" as someSyncChildInjectable << (T,orchid) >> $some-sync-child-injectable $some-container $some-parent-injectable #line:darkRed -class "some-customizable-async-injectable" as someCustomizableAsyncInjectable << (S,lightGreen) >> $some-customizable-async-injectable $some-container $some-parent-injectable $some-async-child-injectable #line:darkRed -class "some-async-child-injectable" as someAsyncChildInjectable << (S,lightGreen) >> $some-async-child-injectable $some-container $some-parent-injectable #line:darkRed -class "some-parent-injectable" as someParentInjectable << (S,lightGreen) >> $some-parent-injectable $some-container #line:darkRed -class "some-keyed-injectable" as someKeyedInjectable << (K,pink) >> $some-keyed-injectable $some-container $some-parent-injectable #line:darkRed +class \\"some-token-injectable\\" as someTokenInjectable << (S,lightGreen) >> $some-token-injectable $some-container $some-parent-injectable $some-sync-child-injectable $some-injection-token #line:darkRed +class \\"some-customizable-sync-injectable\\" as someCustomizableSyncInjectable << (S,lightGreen) >> $some-customizable-sync-injectable $some-container $some-parent-injectable $some-sync-child-injectable $some-injection-token #line:darkRed +class \\"some-injection-token\\" as someInjectionToken << (X,orange) >> $some-injection-token $some-container $some-parent-injectable $some-sync-child-injectable #line:green +class \\"some-sync-child-injectable\\" as someSyncChildInjectable << (T,orchid) >> $some-sync-child-injectable $some-container $some-parent-injectable #line:darkRed +class \\"some-customizable-async-injectable\\" as someCustomizableAsyncInjectable << (S,lightGreen) >> $some-customizable-async-injectable $some-container $some-parent-injectable $some-async-child-injectable #line:darkRed +class \\"some-async-child-injectable\\" as someAsyncChildInjectable << (S,lightGreen) >> $some-async-child-injectable $some-container $some-parent-injectable #line:darkRed +class \\"some-parent-injectable\\" as someParentInjectable << (S,lightGreen) >> $some-parent-injectable $some-container #line:darkRed +class \\"some-keyed-injectable\\" as someKeyedInjectable << (K,pink) >> $some-keyed-injectable $some-container $some-parent-injectable #line:darkRed someInjectionToken --[#black,plain,thickness=1]up* someTokenInjectable #text:black someInjectionToken --[#orange,plain,thickness=1]up* someCustomizableSyncInjectable #text:green : some-custom-link-info someSyncChildInjectable --[#black,plain,thickness=1]up* someInjectionToken #text:black someParentInjectable --[#black,plain,thickness=1]up* someSyncChildInjectable #text:black -someAsyncChildInjectable --[#orange,plain,thickness=4]up* someCustomizableAsyncInjectable #text:green : Async\\nsome-custom-link-info +someAsyncChildInjectable --[#orange,plain,thickness=4]up* someCustomizableAsyncInjectable #text:green : Async\\\\nsome-custom-link-info someParentInjectable --[#black,plain,thickness=4]up* someAsyncChildInjectable #text:black : Async someContainer --[#black,plain,thickness=4]up* someParentInjectable #text:black : Async someParentInjectable --[#black,plain,thickness=1]up* someKeyedInjectable #text:black