11use napi_derive:: napi;
22
3+ use crate :: type_aliases:: { UniqueArcMutex , WeakRefMutex } ;
4+
35use super :: { binding_output_asset:: BindingOutputAsset , binding_output_chunk:: BindingOutputChunk } ;
46
57/// The `BindingOutputs` owner `Vec<Output>` the mutable reference, it avoid `Clone` at call `writeBundle/generateBundle` hook, and make it mutable.
68#[ napi]
79pub struct BindingOutputs {
8- inner : & ' static mut Vec < rolldown_common:: Output > ,
10+ inner : WeakRefMutex < Vec < rolldown_common:: Output > > ,
911}
1012
1113#[ napi]
1214impl BindingOutputs {
13- pub fn new ( inner : & ' static mut Vec < rolldown_common:: Output > ) -> Self {
15+ pub fn new ( inner : WeakRefMutex < Vec < rolldown_common:: Output > > ) -> Self {
1416 Self { inner }
1517 }
1618
1719 #[ napi( getter) ]
1820 pub fn chunks ( & mut self ) -> Vec < BindingOutputChunk > {
1921 let mut chunks: Vec < BindingOutputChunk > = vec ! [ ] ;
20-
21- self . inner . iter_mut ( ) . for_each ( |o| match o {
22- rolldown_common:: Output :: Chunk ( chunk) => {
23- chunks. push ( BindingOutputChunk :: new ( unsafe { std:: mem:: transmute ( chunk. as_mut ( ) ) } ) ) ;
24- }
25- rolldown_common:: Output :: Asset ( _) => { }
22+ self . inner . with_inner ( |inner| {
23+ let mut inner = inner. lock ( ) . expect ( "PoisonError raised" ) ;
24+ inner. iter_mut ( ) . for_each ( |o| match o {
25+ rolldown_common:: Output :: Chunk ( chunk) => {
26+ chunks. push ( BindingOutputChunk :: new ( unsafe { std:: mem:: transmute ( chunk. as_mut ( ) ) } ) ) ;
27+ }
28+ rolldown_common:: Output :: Asset ( _) => { }
29+ } ) ;
2630 } ) ;
2731
2832 chunks
@@ -32,45 +36,53 @@ impl BindingOutputs {
3236 pub fn assets ( & mut self ) -> Vec < BindingOutputAsset > {
3337 let mut assets: Vec < BindingOutputAsset > = vec ! [ ] ;
3438
35- self . inner . iter_mut ( ) . for_each ( |o| match o {
36- rolldown_common:: Output :: Asset ( asset) => {
37- assets. push ( BindingOutputAsset :: new ( unsafe { std:: mem:: transmute ( asset. as_mut ( ) ) } ) ) ;
38- }
39- rolldown_common:: Output :: Chunk ( _) => { }
39+ self . inner . with_inner ( |inner| {
40+ let mut inner = inner. lock ( ) . expect ( "PoisonError raised" ) ;
41+ inner. iter_mut ( ) . for_each ( |o| match o {
42+ rolldown_common:: Output :: Asset ( asset) => {
43+ assets. push ( BindingOutputAsset :: new ( unsafe { std:: mem:: transmute ( asset. as_mut ( ) ) } ) ) ;
44+ }
45+ rolldown_common:: Output :: Chunk ( _) => { }
46+ } ) ;
4047 } ) ;
4148 assets
4249 }
4350
4451 #[ napi]
4552 pub fn delete ( & mut self , file_name : String ) {
46- if let Some ( index) = self . inner . iter ( ) . position ( |o| o. filename ( ) == file_name) {
47- self . inner . remove ( index) ;
48- }
53+ self . inner . with_inner ( |inner| {
54+ let mut inner = inner. lock ( ) . expect ( "PoisonError raised" ) ;
55+ if let Some ( index) = inner. iter ( ) . position ( |o| o. filename ( ) == file_name) {
56+ inner. remove ( index) ;
57+ }
58+ } ) ;
4959 }
5060}
5161
5262/// The `FinalBindingOutputs` is used at `write()` or `generate()`, it is similar to `BindingOutputs`, if using `BindingOutputs` has unexpected behavior.
5363/// TODO find a way to export it gracefully.
5464#[ napi]
5565pub struct FinalBindingOutputs {
56- inner : Vec < rolldown_common:: Output > ,
66+ inner : UniqueArcMutex < Vec < rolldown_common:: Output > > ,
5767}
5868
5969#[ napi]
6070impl FinalBindingOutputs {
6171 pub fn new ( inner : Vec < rolldown_common:: Output > ) -> Self {
62- Self { inner }
72+ Self { inner : UniqueArcMutex :: new ( inner . into ( ) ) }
6373 }
6474
6575 #[ napi( getter) ]
6676 pub fn chunks ( & mut self ) -> Vec < BindingOutputChunk > {
6777 let mut chunks: Vec < BindingOutputChunk > = vec ! [ ] ;
68-
69- self . inner . iter_mut ( ) . for_each ( |o| match o {
70- rolldown_common:: Output :: Chunk ( chunk) => {
71- chunks. push ( BindingOutputChunk :: new ( unsafe { std:: mem:: transmute ( chunk. as_mut ( ) ) } ) ) ;
72- }
73- rolldown_common:: Output :: Asset ( _) => { }
78+ self . inner . weak_ref ( ) . with_inner ( |inner| {
79+ let mut inner = inner. lock ( ) . expect ( "PoisonError raised" ) ;
80+ inner. iter_mut ( ) . for_each ( |o| match o {
81+ rolldown_common:: Output :: Chunk ( chunk) => {
82+ chunks. push ( BindingOutputChunk :: new ( unsafe { std:: mem:: transmute ( chunk. as_mut ( ) ) } ) ) ;
83+ }
84+ rolldown_common:: Output :: Asset ( _) => { }
85+ } ) ;
7486 } ) ;
7587
7688 chunks
@@ -80,11 +92,14 @@ impl FinalBindingOutputs {
8092 pub fn assets ( & mut self ) -> Vec < BindingOutputAsset > {
8193 let mut assets: Vec < BindingOutputAsset > = vec ! [ ] ;
8294
83- self . inner . iter_mut ( ) . for_each ( |o| match o {
84- rolldown_common:: Output :: Asset ( asset) => {
85- assets. push ( BindingOutputAsset :: new ( unsafe { std:: mem:: transmute ( asset. as_mut ( ) ) } ) ) ;
86- }
87- rolldown_common:: Output :: Chunk ( _) => { }
95+ self . inner . weak_ref ( ) . with_inner ( |inner| {
96+ let mut inner = inner. lock ( ) . expect ( "PoisonError raised" ) ;
97+ inner. iter_mut ( ) . for_each ( |o| match o {
98+ rolldown_common:: Output :: Asset ( asset) => {
99+ assets. push ( BindingOutputAsset :: new ( unsafe { std:: mem:: transmute ( asset. as_mut ( ) ) } ) ) ;
100+ }
101+ rolldown_common:: Output :: Chunk ( _) => { }
102+ } ) ;
88103 } ) ;
89104 assets
90105 }
0 commit comments