feat: Add OpenDAL based Remote Storage class (#2700)

* feat: Add OpenDAL based Remote Storage class

Signed-off-by: Xuanwo <github@xuanwo.io>

* Fix error logging

Signed-off-by: Xuanwo <github@xuanwo.io>

* fix(dependencies): update opendal version to ^0.47.11 and add platform-specific binaries

---------

Signed-off-by: Xuanwo <github@xuanwo.io>
Co-authored-by: suyao <sy20010504@gmail.com>
This commit is contained in:
Xuanwo
2025-05-08 03:09:40 +08:00
committed by GitHub
parent 80177458b1
commit 8b7bc0ff4e
3 changed files with 138 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
import Logger from 'electron-log'
import { Operator } from 'opendal'
export default class RemoteStorage {
public instance: Operator | undefined
/**
*
* @param scheme is the scheme for opendal services. Available value includes "azblob", "azdls", "cos", "gcs", "obs", "oss", "s3", "webdav", "webhdfs", "aliyun-drive", "alluxio", "azfile", "dropbox", "gdrive", "onedrive", "postgresql", "mysql", "redis", "swift", "mongodb", "alluxio", "b2", "seafile", "upyun", "koofr", "yandex-disk"
* @param options is the options for given opendal services. Valid options depend on the scheme. Checkout https://docs.rs/opendal/latest/opendal/services/index.html for all valid options.
*
* For example, use minio as remote storage:
*
* ```typescript
* const storage = new RemoteStorage('s3', {
* endpoint: 'http://localhost:9000',
* region: 'us-east-1',
* bucket: 'testbucket',
* access_key_id: 'user',
* secret_access_key: 'password',
* root: '/path/to/basepath',
* })
* ```
*/
constructor(scheme: string, options?: Record<string, string> | undefined | null) {
this.instance = new Operator(scheme, options)
this.putFileContents = this.putFileContents.bind(this)
this.getFileContents = this.getFileContents.bind(this)
}
public putFileContents = async (filename: string, data: string | Buffer) => {
if (!this.instance) {
return new Error('RemoteStorage client not initialized')
}
try {
return await this.instance.write(filename, data)
} catch (error) {
Logger.error('[RemoteStorage] Error putting file contents:', error)
throw error
}
}
public getFileContents = async (filename: string) => {
if (!this.instance) {
throw new Error('RemoteStorage client not initialized')
}
try {
return await this.instance.read(filename)
} catch (error) {
Logger.error('[RemoteStorage] Error getting file contents:', error)
throw error
}
}
}