This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 4c2b68f44 refactor(services/opfs): split opfs service into separate 
crate (#7021)
4c2b68f44 is described below

commit 4c2b68f44baa760314f1cad651406cf4cacef2ab
Author: Zhiqiang ZHOU <[email protected]>
AuthorDate: Tue Dec 16 19:48:44 2025 -0800

    refactor(services/opfs): split opfs service into separate crate (#7021)
    
    * refactor(services/opfs): split opfs service into separate crate
    
    Move OPFS service from core/src/services/opfs to services/opfs as a
    standalone crate. This follows the ongoing service extraction pattern
    to improve modularity and reduce core dependencies.
    
    Changes:
    - Create new services/opfs crate with its own Cargo.toml
    - Move all OPFS implementation files to services/opfs/src
    - Remove OPFS-specific dependencies from core/Cargo.toml
    - Update service feature flag to use opendal-service-opfs dependency
    - Re-export opfs module in src/lib.rs
    
    Co-Authored-By: Claude <[email protected]>
    
    * chore: apply taplo formatting
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude Opus 4.5 <[email protected]>
    
    * refactor(services/opfs): split opfs service into separate crate
    
    Update opfs service export to use opendal_service_opfs crate with
    appropriate target architecture constraints for wasm32.
    
    Co-Authored-By: Claude <[email protected]>
    
    * refactor(services/opfs): move dependency to wasm32 target-specific section
    
    The OPFS service only works in WebAssembly environments, so the
    dependency is now correctly placed under the wasm32 target-specific
    dependencies section instead of the main dependencies.
    
    Co-Authored-By: Claude <[email protected]>
    
    ---------
    
    Co-authored-by: Claude <[email protected]>
---
 core/Cargo.lock                                    | 18 ++++++--
 core/Cargo.toml                                    |  5 ++-
 core/core/Cargo.toml                               | 22 ----------
 core/core/src/services/mod.rs                      |  3 --
 core/services/opfs/Cargo.toml                      | 51 ++++++++++++++++++++++
 .../services/opfs => services/opfs/src}/backend.rs | 30 +++++++++++--
 .../services/opfs => services/opfs/src}/config.rs  | 20 ++++++++-
 .../services/opfs => services/opfs/src}/core.rs    |  5 +--
 .../services/opfs => services/opfs/src}/docs.md    |  0
 .../services/opfs => services/opfs/src}/error.rs   |  3 +-
 .../opfs/mod.rs => services/opfs/src/lib.rs}       | 10 +++++
 .../services/opfs => services/opfs/src}/utils.rs   | 12 ++---
 core/src/lib.rs                                    |  2 +
 13 files changed, 137 insertions(+), 44 deletions(-)

diff --git a/core/Cargo.lock b/core/Cargo.lock
index 6173f05e6..e03ff0760 100644
--- a/core/Cargo.lock
+++ b/core/Cargo.lock
@@ -5574,6 +5574,7 @@ dependencies = [
  "opendal-service-moka",
  "opendal-service-mysql",
  "opendal-service-obs",
+ "opendal-service-opfs",
  "opendal-service-oss",
  "opendal-service-persy",
  "opendal-service-postgresql",
@@ -5648,7 +5649,6 @@ dependencies = [
  "http 1.4.0",
  "http-body 1.0.1",
  "jiff",
- "js-sys",
  "libtest-mimic",
  "log",
  "md-5",
@@ -5680,9 +5680,6 @@ dependencies = [
  "tracing-subscriber",
  "url",
  "uuid",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
  "web-time",
 ]
 
@@ -6215,6 +6212,19 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "opendal-service-opfs"
+version = "0.55.0"
+dependencies = [
+ "ctor",
+ "js-sys",
+ "opendal-core",
+ "serde",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
 [[package]]
 name = "opendal-service-oss"
 version = "0.55.0"
diff --git a/core/Cargo.toml b/core/Cargo.toml
index b17ae5ea3..e6231e25f 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -141,7 +141,7 @@ services-monoiofs = ["opendal-core/services-monoiofs"]
 services-mysql = ["dep:opendal-service-mysql"]
 services-obs = ["dep:opendal-service-obs"]
 services-onedrive = ["opendal-core/services-onedrive"]
-services-opfs = ["opendal-core/services-opfs"]
+services-opfs = ["dep:opendal-service-opfs"]
 services-oss = ["dep:opendal-service-oss"]
 services-pcloud = ["opendal-core/services-pcloud"]
 services-persy = ["dep:opendal-service-persy"]
@@ -266,3 +266,6 @@ tracing-subscriber = { version = "0.3", features = [
   "tracing-log",
 ] }
 uuid = { workspace = true, features = ["serde", "v4"] }
+
+[target.'cfg(target_arch = "wasm32")'.dependencies]
+opendal-service-opfs = { path = "services/opfs", version = "0.55.0", optional 
= true, default-features = false }
diff --git a/core/core/Cargo.toml b/core/core/Cargo.toml
index 298db1678..edfaefc7d 100644
--- a/core/core/Cargo.toml
+++ b/core/core/Cargo.toml
@@ -74,13 +74,6 @@ services-memory = []
 services-mongodb = ["dep:mongodb", "dep:mongodb-internal-macros"]
 services-monoiofs = ["dep:monoio", "dep:flume"]
 services-onedrive = []
-services-opfs = [
-  "dep:js-sys",
-  "dep:wasm-bindgen",
-  "dep:wasm-bindgen-futures",
-  "dep:web-sys",
-]
-
 services-pcloud = []
 services-redis = ["dep:redis", "dep:fastpool", "redis?/tokio-rustls-comp"]
 services-redis-native-tls = ["services-redis", "redis?/tokio-native-tls-comp"]
@@ -187,21 +180,6 @@ monoio = { version = "0.2.4", optional = true, features = [
   "unlinkat",
   "renameat",
 ] }
-# for service-opfs
-js-sys = { version = "0.3.77", optional = true }
-wasm-bindgen = { version = "0.2.100", optional = true }
-wasm-bindgen-futures = { version = "0.4.50", optional = true }
-web-sys = { version = "0.3.77", optional = true, features = [
-  "Window",
-  "File",
-  "FileSystemDirectoryHandle",
-  "FileSystemFileHandle",
-  "FileSystemGetDirectoryOptions",
-  "FileSystemGetFileOptions",
-  "FileSystemWritableFileStream",
-  "Navigator",
-  "StorageManager",
-] }
 
 # Layers
 # for layers-dtrace
diff --git a/core/core/src/services/mod.rs b/core/core/src/services/mod.rs
index e89d1a6d9..e1553e71d 100644
--- a/core/core/src/services/mod.rs
+++ b/core/core/src/services/mod.rs
@@ -163,6 +163,3 @@ pub use webhdfs::*;
 mod yandex_disk;
 #[cfg(feature = "services-yandex-disk")]
 pub use yandex_disk::*;
-
-#[cfg(all(target_arch = "wasm32", feature = "services-opfs"))]
-mod opfs;
diff --git a/core/services/opfs/Cargo.toml b/core/services/opfs/Cargo.toml
new file mode 100644
index 000000000..336b2e422
--- /dev/null
+++ b/core/services/opfs/Cargo.toml
@@ -0,0 +1,51 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL OPFS service implementation"
+name = "opendal-service-opfs"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+
+ctor = { workspace = true }
+js-sys = "0.3.77"
+serde = { workspace = true, features = ["derive"] }
+wasm-bindgen = "0.2.100"
+wasm-bindgen-futures = "0.4.50"
+web-sys = { version = "0.3.77", features = [
+  "Window",
+  "File",
+  "FileSystemDirectoryHandle",
+  "FileSystemFileHandle",
+  "FileSystemGetDirectoryOptions",
+  "FileSystemGetFileOptions",
+  "FileSystemWritableFileStream",
+  "Navigator",
+  "StorageManager",
+] }
diff --git a/core/core/src/services/opfs/backend.rs 
b/core/services/opfs/src/backend.rs
similarity index 68%
rename from core/core/src/services/opfs/backend.rs
rename to core/services/opfs/src/backend.rs
index c7c6db0b6..9e28868a5 100644
--- a/core/core/src/services/opfs/backend.rs
+++ b/core/services/opfs/src/backend.rs
@@ -20,9 +20,25 @@ use std::sync::Arc;
 
 use web_sys::FileSystemGetDirectoryOptions;
 
+use super::OPFS_SCHEME;
+use super::config::OpfsConfig;
 use super::utils::*;
-use crate::raw::*;
-use crate::*;
+use opendal_core::raw::*;
+use opendal_core::*;
+
+#[doc = include_str!("docs.md")]
+#[derive(Default, Debug)]
+pub struct OpfsBuilder {
+    pub(super) config: OpfsConfig,
+}
+
+impl Builder for OpfsBuilder {
+    type Config = OpfsConfig;
+
+    fn build(self) -> Result<impl Access> {
+        Ok(OpfsBackend {})
+    }
+}
 
 /// OPFS Service backend
 #[derive(Default, Debug, Clone)]
@@ -38,7 +54,15 @@ impl Access for OpfsBackend {
     type Deleter = ();
 
     fn info(&self) -> Arc<AccessorInfo> {
-        Arc::new(AccessorInfo::default())
+        let info = AccessorInfo::default();
+        info.set_scheme(OPFS_SCHEME);
+        info.set_name("opfs");
+        info.set_root("/");
+        info.set_native_capability(Capability {
+            create_dir: true,
+            ..Default::default()
+        });
+        Arc::new(info)
     }
 
     async fn create_dir(&self, path: &str, _: OpCreateDir) -> 
Result<RpCreateDir> {
diff --git a/core/core/src/services/opfs/config.rs 
b/core/services/opfs/src/config.rs
similarity index 69%
rename from core/core/src/services/opfs/config.rs
rename to core/services/opfs/src/config.rs
index 7bf938233..38bd72c21 100644
--- a/core/core/src/services/opfs/config.rs
+++ b/core/services/opfs/src/config.rs
@@ -15,11 +15,29 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::fmt::Debug;
+
 use serde::Deserialize;
 use serde::Serialize;
 
+use super::backend::OpfsBuilder;
+
 /// Config for OPFS.
 #[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
 #[serde(default)]
 #[non_exhaustive]
-pub struct OPFSConfig {}
+pub struct OpfsConfig {}
+
+impl Debug for OpfsConfig {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("OpfsConfig").finish_non_exhaustive()
+    }
+}
+
+impl opendal_core::Configurator for OpfsConfig {
+    type Builder = OpfsBuilder;
+
+    fn into_builder(self) -> Self::Builder {
+        OpfsBuilder { config: self }
+    }
+}
diff --git a/core/core/src/services/opfs/core.rs 
b/core/services/opfs/src/core.rs
similarity index 96%
rename from core/core/src/services/opfs/core.rs
rename to core/services/opfs/src/core.rs
index 643af84bd..10cd1da91 100644
--- a/core/core/src/services/opfs/core.rs
+++ b/core/services/opfs/src/core.rs
@@ -22,8 +22,8 @@ use wasm_bindgen_futures::JsFuture;
 use web_sys::File;
 use web_sys::FileSystemWritableFileStream;
 
-use crate::Error;
-use crate::Result;
+use opendal_core::Error;
+use opendal_core::Result;
 
 use super::error::*;
 use super::utils::*;
@@ -41,7 +41,6 @@ impl OpfsCore {
             .and_then(JsCast::dyn_into)
             .map_err(parse_js_error)?;
 
-        // QuotaExceeded or NotAllowed
         JsFuture::from(
             writable
                 .write_with_u8_array(content)
diff --git a/core/core/src/services/opfs/docs.md 
b/core/services/opfs/src/docs.md
similarity index 100%
rename from core/core/src/services/opfs/docs.md
rename to core/services/opfs/src/docs.md
diff --git a/core/core/src/services/opfs/error.rs 
b/core/services/opfs/src/error.rs
similarity index 94%
rename from core/core/src/services/opfs/error.rs
rename to core/services/opfs/src/error.rs
index 1f7d5cb87..5f2a1a0fe 100644
--- a/core/core/src/services/opfs/error.rs
+++ b/core/services/opfs/src/error.rs
@@ -17,7 +17,8 @@
 
 use wasm_bindgen::JsValue;
 
-use crate::{Error, ErrorKind};
+use opendal_core::Error;
+use opendal_core::ErrorKind;
 
 pub(crate) fn parse_js_error(msg: JsValue) -> Error {
     Error::new(
diff --git a/core/core/src/services/opfs/mod.rs b/core/services/opfs/src/lib.rs
similarity index 80%
rename from core/core/src/services/opfs/mod.rs
rename to core/services/opfs/src/lib.rs
index dd1b80048..0c391e162 100644
--- a/core/core/src/services/opfs/mod.rs
+++ b/core/services/opfs/src/lib.rs
@@ -18,8 +18,18 @@
 /// Default scheme for opfs service.
 pub const OPFS_SCHEME: &str = "opfs";
 
+use opendal_core::DEFAULT_OPERATOR_REGISTRY;
+
 mod backend;
 mod config;
 mod core;
 mod error;
 mod utils;
+
+pub use backend::OpfsBuilder as Opfs;
+pub use config::OpfsConfig;
+
+#[ctor::ctor]
+fn register_opfs_service() {
+    DEFAULT_OPERATOR_REGISTRY.register::<Opfs>(OPFS_SCHEME);
+}
diff --git a/core/core/src/services/opfs/utils.rs 
b/core/services/opfs/src/utils.rs
similarity index 91%
rename from core/core/src/services/opfs/utils.rs
rename to core/services/opfs/src/utils.rs
index 9cc3bd25e..4c2997a73 100644
--- a/core/core/src/services/opfs/utils.rs
+++ b/core/services/opfs/src/utils.rs
@@ -15,13 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::Result;
+use opendal_core::Result;
 use wasm_bindgen::JsCast;
 use wasm_bindgen_futures::JsFuture;
-use web_sys::{
-    FileSystemDirectoryHandle, FileSystemFileHandle, 
FileSystemGetDirectoryOptions,
-    FileSystemGetFileOptions, window,
-};
+use web_sys::FileSystemDirectoryHandle;
+use web_sys::FileSystemFileHandle;
+use web_sys::FileSystemGetDirectoryOptions;
+use web_sys::FileSystemGetFileOptions;
+use web_sys::window;
 
 use super::error::*;
 
@@ -59,7 +60,6 @@ pub(crate) async fn get_handle_by_filename(filename: &str) -> 
Result<FileSystemF
         .and_then(JsCast::dyn_into)
         .map_err(parse_js_error)?;
 
-    // maybe the option should be exposed?
     let opt = FileSystemGetFileOptions::new();
     opt.set_create(true);
 
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 34edce71d..055936fe5 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -76,6 +76,8 @@ pub mod services {
     pub use opendal_service_mysql::*;
     #[cfg(feature = "services-obs")]
     pub use opendal_service_obs::*;
+    #[cfg(all(target_arch = "wasm32", feature = "services-opfs"))]
+    pub use opendal_service_opfs::*;
     #[cfg(feature = "services-oss")]
     pub use opendal_service_oss::*;
     #[cfg(feature = "services-persy")]

Reply via email to