@@ -40,7 +40,7 @@ export class GenericSqliteWorkerDriver<
4040 this . worker . postMessage ( [ initEvent , exec . data || ( { } as any ) ] satisfies InitMsg < R > )
4141
4242 await new Promise < void > ( ( resolve , reject ) => {
43- this . mitt ! . once ( initEvent , ( _ , err ) => ( err ? reject ( err ) : resolve ( ) ) )
43+ this . mitt ! . once ( initEvent , ( _qid , _data , err ) => ( err ? reject ( err ) : resolve ( ) ) )
4444 } )
4545
4646 this . conn = new GenericSqliteWorkerConnection ( this . worker , this . mitt )
@@ -54,7 +54,7 @@ export class GenericSqliteWorkerDriver<
5454 }
5555 this . worker . postMessage ( [ closeEvent ] satisfies CloseMsg )
5656 return new Promise < void > ( ( resolve , reject ) =>
57- this . mitt ?. once ( closeEvent , ( _ , err ) => ( err ? reject ( err ) : resolve ( ) ) ) ,
57+ this . mitt ?. once ( closeEvent , ( _qid , _data , err ) => ( err ? reject ( err ) : resolve ( ) ) ) ,
5858 ) . finally ( ( ) => {
5959 this . worker ?. terminate ( )
6060 this . mitt ?. off ( )
@@ -64,13 +64,71 @@ export class GenericSqliteWorkerDriver<
6464}
6565
6666class GenericSqliteWorkerConnection implements DatabaseConnection {
67+ private pendingRuns = new Map <
68+ string ,
69+ { resolve : ( data : any ) => void ; reject : ( err : any ) => void }
70+ > ( )
71+ private pendingStreams = new Map <
72+ string ,
73+ { resolve : ( data : any ) => void ; reject : ( err : any ) => void }
74+ > ( )
75+
6776 constructor (
6877 readonly worker : IGenericWorker ,
6978 readonly mitt : IGenericEventEmitter ,
70- ) { }
79+ ) {
80+ // Central dispatcher — register once, route by queryId
81+ this . mitt . on ( runEvent , ( queryId : string | undefined , data : any , err : unknown ) => {
82+ if ( ! queryId ) {
83+ return
84+ }
85+ const pending = this . pendingRuns . get ( queryId )
86+ if ( ! pending ) {
87+ return
88+ }
89+ this . pendingRuns . delete ( queryId )
90+ if ( err ) {
91+ pending . reject ( err )
92+ } else {
93+ pending . resolve ( data )
94+ }
95+ } )
96+
97+ this . mitt . on ( dataEvent , ( queryId : string | undefined , data : any , err : unknown ) => {
98+ if ( ! queryId ) {
99+ return
100+ }
101+ const state = this . pendingStreams . get ( queryId )
102+ if ( ! state ) {
103+ return
104+ }
105+ if ( err ) {
106+ this . pendingStreams . delete ( queryId )
107+ state . reject ( err )
108+ } else {
109+ state . resolve ( [ { rows : [ data ] } , false ] )
110+ }
111+ } )
112+
113+ this . mitt . on ( endEvent , ( queryId : string | undefined , _data : any , err : unknown ) => {
114+ if ( ! queryId ) {
115+ return
116+ }
117+ const state = this . pendingStreams . get ( queryId )
118+ if ( ! state ) {
119+ return
120+ }
121+ this . pendingStreams . delete ( queryId )
122+ if ( err ) {
123+ state . reject ( err )
124+ } else {
125+ state . resolve ( [ undefined , true ] )
126+ }
127+ } )
128+ }
71129
72130 async * streamQuery < R > (
73- { parameters, sql, query } : CompiledQuery ,
131+ { parameters, sql, query, queryId } : CompiledQuery ,
74132 chunkSize ?: number ,
75133 options ?: AbortableOperationOptions ,
76134 ) : AsyncIterableIterator < QueryResult < R > > {
@@ -80,40 +138,31 @@ class GenericSqliteWorkerConnection implements DatabaseConnection {
80138
81139 this . worker . postMessage ( [
82140 dataEvent ,
141+ queryId . queryId ,
83142 SelectQueryNode . is ( query ) ,
84143 sql ,
85144 parameters ,
86145 chunkSize ,
87146 ] satisfies StreamMsg )
88147 type ResolveData = [ data : QueryResult < R > | undefined , done : boolean ]
89148 let done = false
90- let resolveFn : ( value : ResolveData ) => void
91149 let rejectFn : ( reason ?: any ) => void
92150
93151 const onAbort = ( ) : void => rejectFn ( new Error ( 'Query aborted' ) )
94152 options ?. signal ?. addEventListener ( 'abort' , onAbort , { once : true } )
95153
96- this . mitt ! . on ( dataEvent , ( data , err ) : void => {
97- if ( err ) {
98- rejectFn ( err )
99- } else {
100- resolveFn ( [ { rows : [ data ] } , false ] )
101- }
102- } )
103-
104- this . mitt ! . on ( endEvent , ( _ , err ) : void => {
105- if ( err ) {
106- rejectFn ( err )
107- } else {
108- resolveFn ( [ undefined , true ] )
109- }
110- } )
154+ const streamState : { resolve : ( data : any ) => void ; reject : ( err : any ) => void } = {
155+ resolve : undefined ! ,
156+ reject : undefined ! ,
157+ }
158+ this . pendingStreams . set ( queryId . queryId , streamState )
111159
112160 try {
113161 while ( ! done ) {
114162 const [ data , isDone ] = await new Promise < ResolveData > ( ( res , rej ) => {
115- resolveFn = res
116163 rejectFn = rej
164+ streamState . resolve = res
165+ streamState . reject = rej
117166 } )
118167
119168 if ( isDone ) {
@@ -124,20 +173,22 @@ class GenericSqliteWorkerConnection implements DatabaseConnection {
124173 }
125174 } finally {
126175 options ?. signal ?. removeEventListener ( 'abort' , onAbort )
127- this . mitt ?. off ( dataEvent )
128- this . mitt ?. off ( endEvent )
176+ this . pendingStreams . delete ( queryId . queryId )
129177 }
130178 }
131179
132180 async executeQuery < R > ( compiledQuery : CompiledQuery < unknown > ) : Promise < QueryResult < R > > {
133- const { parameters, sql, query } = compiledQuery
134- this . worker . postMessage ( [ runEvent , SelectQueryNode . is ( query ) , sql , parameters ] satisfies RunMsg )
135- return await new Promise ( ( resolve , reject ) => {
136- if ( ! this . mitt ) {
137- reject ( new Error ( 'kysely instance has been destroyed' ) )
138- }
181+ const { parameters, sql, query, queryId } = compiledQuery
182+ this . worker . postMessage ( [
183+ runEvent ,
184+ queryId . queryId ,
185+ SelectQueryNode . is ( query ) ,
186+ sql ,
187+ parameters ,
188+ ] satisfies RunMsg )
139189
140- this . mitt ! . once ( runEvent , ( data , err ) => ( ! err && data ? resolve ( data ) : reject ( err ) ) )
190+ return new Promise ( ( resolve , reject ) => {
191+ this . pendingRuns . set ( queryId . queryId , { resolve, reject } )
141192 } )
142193 }
143194}
0 commit comments