-
|
I want to construct an object in a boa_module from data. However, when I use from_data I get an error: This is how the module is registerred: pub fn new() -> Self {
let module_loader = Rc::new(AfxSimpleModuleLoader::new()); // Pretty much SimpleModuleLoader, just without path restrictions
let mut context = ContextBuilder::default()
.job_executor(Rc::new(AfxSimpleJobExecutor::new()));
.module_loader(module_loader.clone())
.build()
.unwrap();
let console = Console::init_with_logger(AfxLogger, &mut context);
context
.register_global_property(Console::NAME, console, Attribute::all())
.expect("the console builtin shouldn't exist");
interval::register(&mut context).unwrap();
let module_advancedfx_fs = advancedfx::js::fs::module(None, &mut context);
module_loader.insert("/advancedfx/fs.mjs".into(), module_advancedfx_fs.clone());
// ...
}This is approximately what my code looks like: use crate::advancedfx::js::errors;
use boa_engine::Finalize;
use boa_engine::JsData;
use boa_engine::JsError;
use boa_engine::JsObject;
use boa_engine::JsResult;
use boa_engine::Trace;
use boa_engine::boa_class;
use boa_engine::boa_module;
use boa_engine::class::Class;
use boa_engine::context::Context;
use boa_engine::error::JsNativeError;
use boa_engine::module::Module;
use boa_engine::realm::Realm;
#[derive(Trace, Finalize, JsData)]
struct DirEntry {
#[unsafe_ignore_trace]
dir_entry: std::fs::DirEntry
}
#[boa_class]
impl DirEntry {
#[boa(constructor)]
fn new() -> JsResult<Self> {
Err(JsError::from_native(errors::error_not_implemented()))
}
fn path(&self) -> String {
self.dir_entry.path().to_string_lossy().to_string()
}
}
#[derive(Trace, Finalize, JsData)]
struct ReadDir {
#[unsafe_ignore_trace]
read_dir: std::fs::ReadDir
}
#[boa_class]
impl ReadDir {
#[boa(constructor)]
fn new() -> JsResult<Self> {
Err(JsError::from_native(errors::error_not_implemented()))
}
fn next(&mut self, context: &mut Context) -> JsResult<Option<JsObject>> {
if let Some(dir_entry_result) = self.read_dir.next() {
let dir_entry = dir_entry_result.map_err(|e| JsError::from_native(JsNativeError::error().with_message(e.to_string())))?;
let data = DirEntry{dir_entry};
let object = DirEntry::from_data(data, context)?;
return Ok(Some(object));
}
Ok(None)
}
}
#[boa_module]
mod fs {
use boa_engine::JsError;
use boa_engine::JsObject;
use boa_engine::JsResult;
use boa_engine::class::Class;
use boa_engine::context::Context;
use boa_engine::error::JsNativeError;
type DirEntry = super::DirEntry;
type ReadDir = super::ReadDir;
fn read_dir(path: String, context: &mut Context) -> JsResult<JsObject> {
let read_dir = std::fs::read_dir(path).map_err(|e| JsError::from_native(JsNativeError::error().with_message(e.to_string())))?;
let data = self::ReadDir{read_dir};
self::ReadDir::from_data(data, context)
}
fn main_path_separator() -> String {
std::path::MAIN_SEPARATOR_STR.to_string()
}
}
pub fn module(realm: Option<Realm>, context: &mut Context) -> Module {
fs::boa_module(realm, context)
}This is the test module: import * as fs from '/advancedfx/fs.mjs';
console.log(fs.readDir('.').next().path())I also tested this on current latest main commit: 7ce9cae |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
With For example, change your wrapper to return a pub fn module(realm: Option<Realm>, context: &mut Context) -> JsResult<Module> {
fs::boa_register(realm.clone(), context)?;
Ok(fs::boa_module(realm, context))
}Then adjust the call site accordingly: let module_advancedfx_fs = advancedfx::js::fs::module(None, &mut context)?;
module_loader.insert("/advancedfx/fs.mjs".into(), module_advancedfx_fs);Or register the classes manually before any context.register_global_class::<ReadDir>()?;
context.register_global_class::<DirEntry>()?;
|
Beta Was this translation helpful? Give feedback.
from_datadoes not register the native class. It only creates an object using the prototype from the registered-class map, and this error is raised when that class is missing from the current realm.With
#[boa_module], the generatedboa_module(...)exports the constructors from the synthetic module. ForClass::from_data(...), you also need to register the classes, either through the generatedboa_register(...)helper or manually.For example, change your wrapper to return a
JsResult<Module>and register before returning the module: