@@ -96,9 +96,20 @@ export async function* sha256(
9696 try {
9797 const poolSize = typeof opts ?. useWebWorker === "object" ? opts . useWebWorker . poolSize : undefined ;
9898 const worker = await getWorker ( poolSize ) ;
99- return yield * eventToGenerator < number , string > ( ( yieldCallback , returnCallback , rejectCallack ) => {
100- worker . addEventListener ( "message" , ( event ) => {
99+
100+ // Define handlers to allow removal
101+ let messageHandler : ( event : MessageEvent ) => void ;
102+ let errorHandler : ( event : ErrorEvent ) => void ;
103+
104+ const cleanup = ( ) => {
105+ worker . removeEventListener ( "message" , messageHandler ) ;
106+ worker . removeEventListener ( "error" , errorHandler ) ;
107+ } ;
108+
109+ return yield * eventToGenerator < number , string > ( ( yieldCallback , returnCallback , rejectCallback ) => {
110+ messageHandler = ( event : MessageEvent ) => {
101111 if ( event . data . sha256 ) {
112+ cleanup ( ) ;
102113 freeWorker ( worker , poolSize ) ;
103114 returnCallback ( event . data . sha256 ) ;
104115 } else if ( event . data . progress ) {
@@ -107,18 +118,47 @@ export async function* sha256(
107118 try {
108119 opts . abortSignal ?. throwIfAborted ( ) ;
109120 } catch ( err ) {
121+ cleanup ( ) ;
110122 destroyWorker ( worker ) ;
111- rejectCallack ( err ) ;
123+ rejectCallback ( err ) ;
112124 }
113125 } else {
126+ cleanup ( ) ;
114127 destroyWorker ( worker ) ;
115- rejectCallack ( event ) ;
128+ rejectCallback ( event ) ;
116129 }
117- } ) ;
118- worker . addEventListener ( "error" , ( event ) => {
130+ } ;
131+
132+ errorHandler = ( event : ErrorEvent ) => {
133+ cleanup ( ) ;
119134 destroyWorker ( worker ) ;
120- rejectCallack ( event . error ) ;
121- } ) ;
135+ rejectCallback ( event . error ) ;
136+ } ;
137+
138+ // Handle external abort signal if it aborts before any worker message
139+ if ( opts ?. abortSignal ) {
140+ try {
141+ opts . abortSignal ?. throwIfAborted ( ) ;
142+ } catch ( err ) {
143+ cleanup ( ) ;
144+ destroyWorker ( worker ) ;
145+ rejectCallback ( opts . abortSignal . reason ?? new DOMException ( "Aborted" , "AbortError" ) ) ;
146+ return ;
147+ }
148+
149+ const abortListener = ( ) => {
150+ cleanup ( ) ;
151+ destroyWorker ( worker ) ;
152+
153+ rejectCallback ( opts . abortSignal ?. reason ?? new DOMException ( "Aborted" , "AbortError" ) ) ;
154+ opts . abortSignal ?. removeEventListener ( "abort" , abortListener ) ;
155+ } ;
156+
157+ opts . abortSignal . addEventListener ( "abort" , abortListener ) ;
158+ }
159+
160+ worker . addEventListener ( "message" , messageHandler ) ;
161+ worker . addEventListener ( "error" , errorHandler ) ;
122162 worker . postMessage ( { file : buffer } ) ;
123163 } ) ;
124164 } catch ( err ) {
0 commit comments