@@ -103,16 +103,24 @@ export const layer = Layer.effect(
103103 }
104104 } [ keyof Hooks ] [ ] = [ ]
105105 const events = yield * EventV2 . Service
106- const scope = yield * Scope . Scope
107106 const locks = KeyedMutex . makeUnsafe < ID > ( )
107+ const scope = yield * Scope . make ( )
108+
109+ // One registry-owned scope lets shutdown remove every plugin transform in one batch.
110+ yield * Effect . addFinalizer ( ( exit ) =>
111+ Effect . gen ( function * ( ) {
112+ hooks = [ ]
113+ yield * State . batch ( Scope . close ( scope , exit ) )
114+ } ) ,
115+ )
108116
109117 const svc = Service . of ( {
110118 add : Effect . fn ( "Plugin.add" ) ( function * ( input ) {
111119 const id = ID . make ( input . id )
112120 yield * locks . withLock ( id ) (
113121 Effect . gen ( function * ( ) {
114122 const existing = hooks . find ( ( item ) => item . id === id )
115- if ( existing ) yield * Scope . close ( existing . scope , Exit . void ) . pipe ( Effect . ignore )
123+ if ( existing ) yield * State . batch ( Scope . close ( existing . scope , Exit . void ) ) . pipe ( Effect . ignore )
116124 const childScope = yield * Scope . fork ( scope )
117125 const result = yield * input . effect . pipe (
118126 Scope . provide ( childScope ) ,
@@ -181,7 +189,7 @@ export const layer = Layer.effect(
181189 Effect . gen ( function * ( ) {
182190 const existing = hooks . find ( ( item ) => item . id === id )
183191 hooks = hooks . filter ( ( item ) => item . id !== id )
184- if ( existing ) yield * Scope . close ( existing . scope , Exit . void ) . pipe ( Effect . ignore )
192+ if ( existing ) yield * State . batch ( Scope . close ( existing . scope , Exit . void ) ) . pipe ( Effect . ignore )
185193 } ) ,
186194 )
187195 } ) ,
0 commit comments