@@ -139,21 +139,106 @@ export class CloudflareActorsActorDriver implements ActorDriver {
139139 return { state : state . ctx } ;
140140 }
141141
142- async readPersistedData ( actorId : string ) : Promise < Uint8Array | undefined > {
143- return await this . #getDOCtx( actorId ) . storage . get ( KEYS . PERSIST_DATA ) ;
144- }
145-
146- async writePersistedData ( actorId : string , data : Uint8Array ) : Promise < void > {
147- await this . #getDOCtx( actorId ) . storage . put ( KEYS . PERSIST_DATA , data ) ;
148- }
149-
150142 async setAlarm ( actor : AnyActorInstance , timestamp : number ) : Promise < void > {
151143 await this . #getDOCtx( actor . id ) . storage . setAlarm ( timestamp ) ;
152144 }
153145
154146 async getDatabase ( actorId : string ) : Promise < unknown | undefined > {
155147 return this . #getDOCtx( actorId ) . storage . sql ;
156148 }
149+
150+ // Batch KV operations - convert between Uint8Array and Cloudflare's string-based API
151+ async kvBatchPut (
152+ actorId : string ,
153+ entries : [ Uint8Array , Uint8Array ] [ ] ,
154+ ) : Promise < void > {
155+ const storage = this . #getDOCtx( actorId ) . storage ;
156+ const encoder = new TextDecoder ( ) ;
157+
158+ // Convert Uint8Array entries to object for Cloudflare batch put
159+ const storageObj : Record < string , Uint8Array > = { } ;
160+ for ( const [ key , value ] of entries ) {
161+ // Convert key from Uint8Array to string
162+ const keyStr = this . #uint8ArrayToKey( key ) ;
163+ storageObj [ keyStr ] = value ;
164+ }
165+
166+ await storage . put ( storageObj ) ;
167+ }
168+
169+ async kvBatchGet (
170+ actorId : string ,
171+ keys : Uint8Array [ ] ,
172+ ) : Promise < ( Uint8Array | null ) [ ] > {
173+ const storage = this . #getDOCtx( actorId ) . storage ;
174+
175+ // Convert keys to strings
176+ const keyStrs = keys . map ( ( k ) => this . #uint8ArrayToKey( k ) ) ;
177+
178+ // Get values from storage
179+ const results = await storage . get < Uint8Array > ( keyStrs ) ;
180+
181+ // Convert Map results to array in same order as input keys
182+ return keyStrs . map ( ( k ) => results . get ( k ) ?? null ) ;
183+ }
184+
185+ async kvBatchDelete ( actorId : string , keys : Uint8Array [ ] ) : Promise < void > {
186+ const storage = this . #getDOCtx( actorId ) . storage ;
187+
188+ // Convert keys to strings
189+ const keyStrs = keys . map ( ( k ) => this . #uint8ArrayToKey( k ) ) ;
190+
191+ await storage . delete ( keyStrs ) ;
192+ }
193+
194+ async kvListPrefix (
195+ actorId : string ,
196+ prefix : Uint8Array ,
197+ ) : Promise < [ Uint8Array , Uint8Array ] [ ] > {
198+ const storage = this . #getDOCtx( actorId ) . storage ;
199+
200+ // Convert prefix to string
201+ const prefixStr = this . #uint8ArrayToKey( prefix ) ;
202+
203+ // List with prefix
204+ const results = await storage . list < Uint8Array > ( { prefix : prefixStr } ) ;
205+
206+ // Convert Map to array of [key, value] tuples
207+ const entries : [ Uint8Array , Uint8Array ] [ ] = [ ] ;
208+ for ( const [ key , value ] of results ) {
209+ entries . push ( [ this . #keyToUint8Array( key ) , value ] ) ;
210+ }
211+
212+ return entries ;
213+ }
214+
215+ // Helper to convert Uint8Array key to string for Cloudflare storage
216+ #uint8ArrayToKey( key : Uint8Array ) : string {
217+ // Check if this is a connection key (starts with [2])
218+ if ( key . length > 0 && key [ 0 ] === 2 ) {
219+ // Connection key - extract connId
220+ const connId = new TextDecoder ( ) . decode ( key . slice ( 1 ) ) ;
221+ return `${ KEYS . CONN_PREFIX } ${ connId } ` ;
222+ }
223+ // Otherwise, treat as persist data key [1]
224+ return KEYS . PERSIST_DATA ;
225+ }
226+
227+ // Helper to convert string key back to Uint8Array
228+ #keyToUint8Array( key : string ) : Uint8Array {
229+ if ( key . startsWith ( KEYS . CONN_PREFIX ) ) {
230+ // Connection key
231+ const connId = key . slice ( KEYS . CONN_PREFIX . length ) ;
232+ const encoder = new TextEncoder ( ) ;
233+ const connIdBytes = encoder . encode ( connId ) ;
234+ const result = new Uint8Array ( 1 + connIdBytes . length ) ;
235+ result [ 0 ] = 2 ; // Connection prefix
236+ result . set ( connIdBytes , 1 ) ;
237+ return result ;
238+ }
239+ // Persist data key
240+ return Uint8Array . from ( [ 1 ] ) ;
241+ }
157242}
158243
159244export function createCloudflareActorsActorDriverBuilder (
0 commit comments