Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

download to disk in wasm #1348

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
//====== THIS IS AUTOGENERATED FILE. DO NOT MODIFY ========

package version
const VERSIONSTR = "v1.10.0-141-gf81a4b84"
const VERSIONSTR = "v1.11-3-gad762e49"

18 changes: 14 additions & 4 deletions wasmsdk/blobber.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,16 +368,26 @@ func multiDownload(allocationID, jsonMultiDownloadOptions, authTicket, callbackF
fileName := strings.Replace(path.Base(option.RemotePath), "/", "-", -1)
localPath := allocationID + "_" + fileName
option.LocalPath = localPath
statusBar := &StatusBar{wg: wg, localPath: localPath}
statusBar := &StatusBar{wg: wg}
allStatusBar[ind] = statusBar
if useCallback {
callback := js.Global().Get(callbackFuncName)
statusBar.callback = func(totalBytes, completedBytes int, filename, objURL, err string) {
callback.Invoke(totalBytes, completedBytes, filename, objURL, err)
}
}
fs, _ := sys.Files.Open(localPath)
mf, _ := fs.(*sys.MemFile)
var mf sys.File
if option.DownloadToDisk {
mf, err = jsbridge.NewFileWriter(fileName)
if err != nil {
PrintError(err.Error())
return "", err
}
} else {
statusBar.localPath = localPath
fs, _ := sys.Files.Open(localPath)
mf, _ = fs.(*sys.MemFile)
}

var downloader sdk.Downloader
if option.DownloadOp == 1 {
Expand Down Expand Up @@ -467,6 +477,7 @@ type MultiDownloadOption struct {
NumBlocks int `json:"numBlocks"`
RemoteFileName string `json:"remoteFileName"` //Required only for file download with auth ticket
RemoteLookupHash string `json:"remoteLookupHash,omitempty"` //Required only for file download with auth ticket
DownloadToDisk bool `json:"downloadToDisk"`
}

// MultiOperation - do copy, move, delete and createdir operation together
Expand Down Expand Up @@ -677,7 +688,6 @@ func uploadWithJsFuncs(allocationID, remotePath string, readChunkFuncName string
}
wg.Add(1)


fileReader := jsbridge.NewFileReader(readChunkFuncName, fileSize)

mimeType, err := zboxutil.GetFileContentType(fileReader)
Expand Down
5 changes: 3 additions & 2 deletions wasmsdk/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<!-- for zcn.wasm-->
<script src="https://cdn.jsdelivr.net/gh/herumi/bls-wasm@v1.0.0/browser/bls.js"></script>
<script src="https://cdn.jsdelivr.net/gh/golang/go@go1.21.0/misc/wasm/wasm_exec.js"></script>
<script src="https://cdn.jsdelivr.net/gh/golang/go@go1.21.5/misc/wasm/wasm_exec.js"></script>
<script src="zcn.js"></script>


Expand Down Expand Up @@ -211,7 +211,7 @@ <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/lates

let network = query.get('network')
if (!network || network == 'undefined') {
network = "dev.zus.network"
network = "test.zus.network"
}

const blockWorker = 'https://' + network + '/dns';
Expand Down Expand Up @@ -802,6 +802,7 @@ <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/lates
remotePath: path,
downloadOp: 1,
numBlocks: 0,
downloadToDisk: true,
})
let stringifiedArray = JSON.stringify(objects);

Expand Down
88 changes: 88 additions & 0 deletions wasmsdk/jsbridge/file_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//go:build js && wasm
// +build js,wasm

package jsbridge

import (
"errors"
"io/fs"
"sync"
"syscall/js"
)

var jsFileWriterMutex sync.Mutex

type FileWriter struct {
writableStream js.Value
}

func (w *FileWriter) Write(p []byte) (int, error) {
//js.Value doesn't work in parallel invoke
jsFileWriterMutex.Lock()
defer jsFileWriterMutex.Unlock()

uint8Array := js.Global().Get("Uint8Array").New(len(p))
js.CopyBytesToJS(uint8Array, p)
_, err := Await(w.writableStream.Call("write", uint8Array))
if len(err) > 0 && !err[0].IsNull() {
return 0, errors.New("file_writer: " + err[0].String())
}
return len(p), nil
}

func (w *FileWriter) Close() error {
_, err := Await(w.writableStream.Call("close"))
if len(err) > 0 && !err[0].IsNull() {
return errors.New("file_writer: " + err[0].String())
}
return nil
}

func (w *FileWriter) Read(p []byte) (int, error) {
return 0, errors.New("file_writer: not supported")
}

func (w *FileWriter) Seek(offset int64, whence int) (int64, error) {
return 0, nil
}

func (w *FileWriter) Sync() error {
return nil
}

func (w *FileWriter) Stat() (fs.FileInfo, error) {
return nil, nil
}

func NewFileWriter(filename string) (*FileWriter, error) {
// writableStream := js.Global().Get("writableStream")
// stream, err := Await(writableStream.Call("create", filename))
// if len(err) > 0 && !err[0].IsNull() {
// return nil, errors.New("file_writer: " + err[0].String())
// }
// return &FileWriter{
// writableStream: stream[0],
// }, nil
if !js.Global().Get("window").Get("showSaveFilePicker").Truthy() || !js.Global().Get("window").Get("WritableStream").Truthy() {
return nil, errors.New("file_writer: not supported")
}

showSaveFilePicker := js.Global().Get("window").Get("showSaveFilePicker")
//create options with suggested name
options := js.Global().Get("Object").New()
options.Set("suggestedName", filename)

//request a file handle
fileHandle, err := Await(showSaveFilePicker.Invoke(options))
if len(err) > 0 && !err[0].IsNull() {
return nil, errors.New("file_writer: " + err[0].String())
}
//create a writable stream
writableStream, err := Await(fileHandle[0].Call("createWritable"))
if len(err) > 0 && !err[0].IsNull() {
return nil, errors.New("file_writer: " + err[0].String())
}
return &FileWriter{
writableStream: writableStream[0],
}, nil
}
9 changes: 6 additions & 3 deletions zboxcore/sdk/downloadworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -830,9 +830,12 @@ func (req *DownloadRequest) calculateShardsParams(
if err != nil {
return 0, err
}
_, err = req.Seek(info.Size(), io.SeekStart)
if err != nil {
return 0, err
// Can be nil when using file writer in wasm
if info != nil {
_, err = req.Seek(info.Size(), io.SeekStart)
if err != nil {
return 0, err
}
}

effectiveChunkSize := effectiveBlockSize * int64(req.datashards)
Expand Down
Loading