1
1
import type { DatabaseConnection , Driver , QueryResult } from 'kysely'
2
- import type { BunWorkerDialectConfig , EventWithError , MainMsg , WorkerMsg } from './type'
2
+ import type { BunWorkerDialectConfig , EventWithError , MainToWorkerMsg , WorkerToMainMsg } from './type'
3
3
import { EventEmitter } from 'node:events'
4
4
import { CompiledQuery , SelectQueryNode } from 'kysely'
5
5
@@ -18,14 +18,14 @@ export class BunWorkerDriver implements Driver {
18
18
{ type : 'module' } ,
19
19
)
20
20
this . mitt = new EventEmitter ( )
21
- this . worker . onmessage = ( { data : [ type , data , err ] } : MessageEvent < WorkerMsg > ) => {
21
+ this . worker . onmessage = ( { data : [ type , data , err ] } : MessageEvent < WorkerToMainMsg > ) => {
22
22
this . mitt ?. emit ( type , data , err )
23
23
}
24
24
this . worker . postMessage ( [
25
25
0 , // init
26
26
this . config ?. url ,
27
27
this . config ?. cacheStatment ,
28
- ] satisfies MainMsg )
28
+ ] satisfies MainToWorkerMsg )
29
29
await new Promise < void > ( ( resolve , reject ) => {
30
30
this . mitt ?. once ( 0 /* init */ , ( _ , err ) => err ? reject ( err ) : resolve ( ) )
31
31
} )
@@ -61,7 +61,7 @@ export class BunWorkerDriver implements Driver {
61
61
if ( ! this . worker ) {
62
62
return
63
63
}
64
- this . worker . postMessage ( [ 2 ] satisfies MainMsg )
64
+ this . worker . postMessage ( [ 2 ] satisfies MainToWorkerMsg )
65
65
return new Promise < void > ( ( resolve , reject ) => {
66
66
this . mitt ?. once ( 2 /* close */ , ( _ , err ) => {
67
67
if ( err ) {
@@ -107,14 +107,54 @@ class BunWorkerConnection implements DatabaseConnection {
107
107
private mitt ?: EventEmitter < EventWithError > ,
108
108
) { }
109
109
110
- streamQuery < R > ( ) : AsyncIterableIterator < QueryResult < R > > {
111
- throw new Error ( 'Bun:sqlite-worker driver doesn\'t support streaming' )
110
+ async * streamQuery < R > ( compiledQuery : CompiledQuery ) : AsyncIterableIterator < QueryResult < R > > {
111
+ const { parameters, sql, query } = compiledQuery
112
+ if ( ! SelectQueryNode . is ( query ) ) {
113
+ throw new Error ( 'WaSqlite dialect only supported SELECT queries' )
114
+ }
115
+ this . worker . postMessage ( [ 3 , sql , parameters ] satisfies MainToWorkerMsg )
116
+ let resolver : ( ( value : IteratorResult < { rows : QueryResult < R > [ ] } > ) => void ) | null = null
117
+ let rejecter : ( ( reason : any ) => void ) | null = null
118
+
119
+ this . mitt ! . on ( 3 , ( data , err ) => {
120
+ if ( err && rejecter ) {
121
+ rejecter ( err )
122
+ }
123
+ if ( resolver ) {
124
+ resolver ( { value : { rows : data ! } , done : false } )
125
+ resolver = null
126
+ }
127
+ } )
128
+
129
+ this . mitt ! . on ( 4 , ( _ , err ) => {
130
+ if ( err && rejecter ) {
131
+ rejecter ( err )
132
+ }
133
+ if ( resolver ) {
134
+ resolver ( { value : undefined , done : true } )
135
+ }
136
+ } )
137
+
138
+ return {
139
+ [ Symbol . asyncIterator ] ( ) {
140
+ return this
141
+ } ,
142
+ async next ( ) {
143
+ return new Promise < IteratorResult < any > > ( ( resolve , reject ) => {
144
+ resolver = resolve
145
+ rejecter = reject
146
+ } )
147
+ } ,
148
+ async return ( ) {
149
+ return { value : undefined , done : true }
150
+ } ,
151
+ }
112
152
}
113
153
114
154
async executeQuery < R > ( compiledQuery : CompiledQuery < unknown > ) : Promise < QueryResult < R > > {
115
155
const { parameters, sql, query } = compiledQuery
116
156
const isSelect = SelectQueryNode . is ( query )
117
- this . worker . postMessage ( [ 1 /* run */ , isSelect , sql , parameters ] satisfies MainMsg )
157
+ this . worker . postMessage ( [ 1 /* run */ , isSelect , sql , parameters ] satisfies MainToWorkerMsg )
118
158
return new Promise ( ( resolve , reject ) => {
119
159
if ( ! this . mitt ) {
120
160
reject ( new Error ( 'kysely instance has been destroyed' ) )
0 commit comments