@@ -4,14 +4,18 @@ import {
44 injected ,
55} from 'brandi'
66import deepmerge from 'deepmerge'
7+ import { inject } from 'vue'
78
89import type {
910 Token ,
1011 TokenType ,
1112 TokenValue ,
1213 RequiredToken ,
1314 OptionalToken ,
15+ Container ,
1416} from 'brandi'
17+ import type { InjectionKey } from 'vue'
18+
1519
1620export {
1721 token ,
@@ -49,14 +53,51 @@ export type ServiceConfigurator<T = Record<string, Token>> = ($: T) => ServiceDe
4953export type Alias < T extends ( ...args : never [ ] ) => unknown > = ( ...rest : Parameters < T > ) => ReturnType < T >
5054export type Decorator < T extends TokenValue > = TokenType < T >
5155export type ReturnDecorated < T extends TokenValue > = ( ) => TokenType < T >
52- export let container = createContainer ( )
53- let labelMap = new WeakMap ( )
5456
5557//
5658export const merge = ( ...definitions : Array < ServiceDefinition [ ] > ) : ServiceDefinition [ ] => {
5759 return [ ...new Map ( [ ...definitions . flat ( ) ] ) . entries ( ) ]
5860}
59- const decorate = ( entries : ServiceDefinition [ ] ) => {
61+ export type Getter = < T extends TokenValue > ( t : T ) => TokenType < T >
62+
63+ export const injectionKey = Symbol ( ) as InjectionKey < Getter >
64+
65+ export const createBuilder = ( ) => {
66+ const container = createContainer ( )
67+ const labelMap = new WeakMap ( )
68+ return {
69+ build : ( ...entries : Array < ServiceDefinition [ ] > ) => {
70+ const get = < T extends TokenValue > ( token : T ) => {
71+ try {
72+ return container . get ( token )
73+ } catch ( e ) {
74+ console . error ( `error resolving ${ token . __d } ` )
75+ throw e
76+ }
77+ }
78+ const merged = decorate ( merge ( ...entries ) , get )
79+ merged . forEach ( ( [ t , config ] ) => service ( t , config , container , labelMap ) )
80+ return get
81+ } ,
82+ destroy : ( ) => { } ,
83+ injectionKey,
84+ container,
85+ }
86+
87+ }
88+
89+ export const createInjections = < T extends TokenValue [ ] > ( ...tokens : T ) : InjectionHooks < T > => {
90+ return tokens . map ( ( token ) => ( ) => {
91+ const get = inject ( injectionKey )
92+ if ( typeof get !== 'undefined' ) {
93+ return get ( token )
94+ }
95+ throw new Error ( `Unable to find container for ${ token . __d } ` )
96+ } ) as InjectionHooks < T >
97+ }
98+
99+
100+ const decorate = ( entries : ServiceDefinition [ ] , get : Getter ) => {
60101 const map = new Map ( entries )
61102 entries . forEach ( ( [ _token , definition ] ) => {
62103 if ( typeof definition . decorates !== 'undefined' ) {
@@ -94,29 +135,8 @@ const decorate = (entries: ServiceDefinition[]) => {
94135 } )
95136 return [ ...map . entries ( ) ]
96137}
97- export const get = < T extends TokenValue > ( token : T ) : TokenType < T > => {
98- try {
99- return container . get ( token )
100- } catch ( e ) {
101- console . error ( `error resolving ${ token . __d } ` )
102- throw e
103- }
104- }
105- export const build = ( ...entries : Array < ServiceDefinition [ ] > ) : typeof get => {
106- container = createContainer ( )
107- labelMap = new WeakMap ( )
108- const merged = decorate ( merge ( ...entries ) )
109- merged . forEach ( item => service ( ...item ) )
110- return get
111- }
112-
113- export const createInjections = < T extends TokenValue [ ] > (
114- ...tokens : T
115- ) : InjectionHooks < T > =>
116- tokens . map ( ( token ) => ( ) => get ( token ) ) as InjectionHooks < T >
117- //
118138
119- export const service = ( t : Token , config : DependencyDefinition ) : void => {
139+ const service = ( t : Token , config : DependencyDefinition , container : Container , labelMap : WeakMap < Token , Token [ ] > ) : void => {
120140 const bound = container . bind ( t )
121141 switch ( true ) {
122142 case 'constant' in config :
@@ -134,27 +154,33 @@ export const service = (t: Token, config: DependencyDefinition): void => {
134154 config . labels . forEach ( ( label : Token ) => {
135155 if ( ! labelMap . has ( label ) ) {
136156 labelMap . set ( label , [ ] )
137- service ( label , {
138- service : ( ) => {
139- return labelMap . get ( label ) . reduce ( ( prev : unknown [ ] , TOKEN : Token ) => {
140- try {
141- const service = get ( TOKEN )
142- if ( Array . isArray ( service ) ) {
143- return prev . concat ( service )
144- } else if ( service instanceof Object ) {
145- return deepmerge ( prev , service )
146- } else {
147- return prev
157+ service (
158+ label ,
159+ {
160+ service : ( ) => {
161+ // @ts -ignore
162+ return labelMap . get ( label ) ! . reduce ( ( prev : Token [ ] , TOKEN ) => {
163+ try {
164+ const service = container . get ( TOKEN )
165+ if ( Array . isArray ( service ) ) {
166+ return prev . concat ( service )
167+ } else if ( service instanceof Object ) {
168+ return deepmerge ( prev , service )
169+ } else {
170+ return prev
171+ }
172+ } catch ( e ) {
173+ console . error ( e )
174+ throw e
148175 }
149- } catch ( e ) {
150- console . error ( e )
151- throw e
152- }
153- } , [ ] )
176+ } , [ ] as Token [ ] )
177+ } ,
154178 } ,
155- } )
179+ container ,
180+ labelMap ,
181+ )
156182 }
157- const tokens = labelMap . get ( label )
183+ const tokens = labelMap . get ( label ) !
158184 tokens . push ( t )
159185 } )
160186 }
@@ -167,9 +193,3 @@ export const service = (t: Token, config: DependencyDefinition): void => {
167193 injected ( ...( [ config . service , ...config . arguments ] as Parameters < typeof injected > ) )
168194 }
169195}
170- export const constant = < T > ( func : T , config : { description : string } ) : Token < T > => {
171- const t = token < T > ( config . description )
172- const bound = container . bind ( t )
173- bound . toConstant ( func as Parameters < typeof bound . toConstant > [ 0 ] )
174- return t as Token < T >
175- }
0 commit comments