@@ -14,7 +14,8 @@ const {
14
14
toStat,
15
15
toMount,
16
16
fromMount,
17
- toDriveStats
17
+ toDriveStats,
18
+ toChunks
18
19
} = require ( 'hyperdrive-daemon-client/lib/common' )
19
20
const { rpc } = require ( 'hyperdrive-daemon-client' )
20
21
@@ -316,43 +317,63 @@ function createDriveHandlers (driveManager) {
316
317
return rsp
317
318
} ,
318
319
320
+ createReadStream : async ( call ) => {
321
+
322
+ } ,
323
+
319
324
readFile : async ( call ) => {
320
325
const id = call . request . getId ( )
321
326
const path = call . request . getPath ( )
322
327
323
328
if ( ! id ) throw new Error ( 'A readFile request must specify a session ID.' )
324
- if ( ! path ) throw new Error ( 'A writeFile request must specify a path.' )
329
+ if ( ! path ) throw new Error ( 'A readFile request must specify a path.' )
325
330
const drive = driveManager . driveForSession ( id )
326
331
327
- return new Promise ( ( resolve , reject ) => {
332
+ const content = await new Promise ( ( resolve , reject ) => {
328
333
drive . readFile ( path , ( err , content ) => {
329
334
if ( err ) return reject ( err )
330
-
331
- const rsp = new rpc . drive . messages . ReadFileResponse ( )
332
- rsp . setContent ( content )
333
-
334
- return resolve ( rsp )
335
+ return resolve ( content )
335
336
} )
336
337
} )
338
+
339
+ const chunks = toChunks ( content )
340
+ for ( const chunk of chunks ) {
341
+ const rsp = new rpc . drive . messages . ReadFileResponse ( )
342
+ rsp . setChunk ( chunk )
343
+ call . write ( rsp )
344
+ }
345
+ call . end ( )
337
346
} ,
338
347
339
- writeFile : async ( call ) => {
340
- const id = call . request . getId ( )
341
- const path = call . request . getPath ( )
342
- const contents = Buffer . from ( call . request . getContent ( ) )
348
+ createWriteStream : async ( call ) => {
343
349
344
- if ( ! id ) throw new Error ( 'A writeFile request must specify a session ID.' )
345
- if ( ! path ) throw new Error ( 'A writeFile request must specify a path.' )
346
- if ( ! contents ) throw new Error ( 'A writeFile request must specify contents.' )
347
- const drive = driveManager . driveForSession ( id )
350
+ } ,
348
351
352
+ writeFile : async ( call ) => {
349
353
return new Promise ( ( resolve , reject ) => {
350
- drive . writeFile ( path , contents , ( err ) => {
351
- if ( err ) return reject ( err )
352
- const rsp = new rpc . drive . messages . WriteFileResponse ( )
353
- return resolve ( rsp )
354
+ call . once ( 'data' , req => {
355
+ const id = req . getId ( )
356
+ const path = req . getPath ( )
357
+
358
+ if ( ! id ) throw new Error ( 'A writeFile request must specify a session ID.' )
359
+ if ( ! path ) throw new Error ( 'A writeFile request must specify a path.' )
360
+ const drive = driveManager . driveForSession ( id )
361
+
362
+ return loadContent ( resolve , reject , path , drive )
354
363
} )
355
364
} )
365
+
366
+ function loadContent ( resolve , reject , path , drive ) {
367
+ return collectStream ( call , ( err , reqs ) => {
368
+ if ( err ) return reject ( err )
369
+ const chunks = reqs . map ( req => Buffer . from ( req . getChunk ( ) ) )
370
+ return drive . writeFile ( path , Buffer . concat ( chunks ) , err => {
371
+ if ( err ) return reject ( err )
372
+ const rsp = new rpc . drive . messages . WriteFileResponse ( )
373
+ return resolve ( rsp )
374
+ } )
375
+ } )
376
+ }
356
377
} ,
357
378
358
379
stat : async ( call ) => {
@@ -454,8 +475,10 @@ function createDriveHandlers (driveManager) {
454
475
455
476
mount : async ( call ) => {
456
477
const id = call . request . getId ( )
457
- const path = call . request . getPath ( )
458
- const opts = fromMount ( call . request . getOpts ( ) )
478
+ const mountInfo = call . request . getInfo ( )
479
+
480
+ const path = mountInfo . getPath ( )
481
+ const opts = fromMount ( mountInfo . getOpts ( ) )
459
482
460
483
if ( ! id ) throw new Error ( 'A mount request must specify a session ID.' )
461
484
if ( ! path ) throw new Error ( 'A mount request must specify a path.' )
@@ -471,6 +494,23 @@ function createDriveHandlers (driveManager) {
471
494
} )
472
495
} ,
473
496
497
+ unmount : async ( call ) => {
498
+ const id = call . request . getId ( )
499
+ const path = call . request . getPath ( )
500
+
501
+ if ( ! id ) throw new Error ( 'An unmount request must specify a session ID.' )
502
+ if ( ! path ) throw new Error ( 'An unmount request must specify a path.' )
503
+ const drive = driveManager . driveForSession ( id )
504
+
505
+ return new Promise ( ( resolve , reject ) => {
506
+ drive . unmount ( path , err => {
507
+ if ( err ) return reject ( err )
508
+ const rsp = new rpc . drive . messages . UnmountDriveResponse ( )
509
+ return resolve ( rsp )
510
+ } )
511
+ } )
512
+ } ,
513
+
474
514
watch : async ( call ) => {
475
515
const id = call . request . getId ( )
476
516
var path = call . request . getPath ( )
@@ -487,7 +527,11 @@ function createDriveHandlers (driveManager) {
487
527
call . on ( 'finish' , onclose )
488
528
call . on ( 'error' , onclose )
489
529
530
+ var closed = false
490
531
function onclose ( err ) {
532
+ if ( closed ) return
533
+ closed = true
534
+
491
535
watcher . destroy ( )
492
536
log . debug ( { id, path } , 'unregistering watcher' )
493
537
if ( err && ! call . destroyed ) call . destroy ( err )
0 commit comments