Define main embedded function script as a JavaScript module

This commit is contained in:
Tobie Morgan Hitchcock 2022-07-23 19:56:32 +01:00
parent 66946397ed
commit d647e40d49
2 changed files with 12 additions and 13 deletions

View file

@ -3,13 +3,16 @@ use super::executor::Executor;
use crate::ctx::Context; use crate::ctx::Context;
use crate::err::Error; use crate::err::Error;
use crate::sql::value::Value; use crate::sql::value::Value;
use js::Function;
use js::Promise; use js::Promise;
use js::Rest;
use js::This;
pub async fn run( pub async fn run(
ctx: &Context<'_>, ctx: &Context<'_>,
doc: Option<&Value>,
src: &str, src: &str,
arg: Vec<Value>, arg: Vec<Value>,
doc: Option<&Value>,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
// Check the context // Check the context
if ctx.is_done() { if ctx.is_done() {
@ -23,12 +26,8 @@ pub async fn run(
let ctx = js::Context::full(&run).unwrap(); let ctx = js::Context::full(&run).unwrap();
// Enable async code in the runtime // Enable async code in the runtime
run.spawn_executor(&exe).detach(); run.spawn_executor(&exe).detach();
// Convert the arguments to JavaScript
let args = Value::from(arg);
// Convert the current document to JavaScript
let this = doc.map_or(&Value::None, |v| v);
// Create the main function structure // Create the main function structure
let src = format!("(async function() {{ {} }}).apply(self, args)", src); let src = format!("export async function main() {{ {} }}", src);
// Attempt to execute the script // Attempt to execute the script
let res: Result<Promise<Value>, js::Error> = ctx.with(|ctx| { let res: Result<Promise<Value>, js::Error> = ctx.with(|ctx| {
// Get the context global object // Get the context global object
@ -39,12 +38,12 @@ pub async fn run(
global.init_def::<classes::Record>().unwrap(); global.init_def::<classes::Record>().unwrap();
// Register the Uuid type as a global class // Register the Uuid type as a global class
global.init_def::<classes::Uuid>().unwrap(); global.init_def::<classes::Uuid>().unwrap();
// Register the document as a global object // Attempt to compile the script
global.prop("self", this).unwrap(); let res = ctx.compile("script", src)?;
// Register the args as a global object // Attempt to fetch the main export
global.prop("args", args).unwrap(); let fnc = res.get::<_, Function>("main")?;
// Attempt to execute the script // Execute the main function
ctx.eval(src) fnc.call((This(doc), Rest(arg)))
}); });
// Return the script result // Return the script result
let res = match res { let res = match res {

View file

@ -138,7 +138,7 @@ impl Function {
for v in x { for v in x {
a.push(v.compute(ctx, opt, txn, doc).await?); a.push(v.compute(ctx, opt, txn, doc).await?);
} }
fnc::script::run(ctx, s, a, doc).await fnc::script::run(ctx, doc, s, a).await
} }
#[cfg(not(feature = "scripting"))] #[cfg(not(feature = "scripting"))]
{ {