@@ -6,8 +6,8 @@ use self::error::{
66use self :: ser:: serialize_to_js;
77use self :: string:: { str_from_ident, IntoJsString } ;
88use self :: syscall:: {
9- call_call_reducer, call_call_view, call_call_view_anon, call_describe_module, get_hooks, resolve_sys_module , FnRet ,
10- HookFunctions ,
9+ call_call_procedure , call_call_reducer, call_call_view, call_call_view_anon, call_describe_module, get_hooks,
10+ resolve_sys_module , FnRet , HookFunctions ,
1111} ;
1212use super :: module_common:: { build_common_module_from_raw, run_describer, ModuleCommon } ;
1313use super :: module_host:: { CallProcedureParams , CallReducerParams , Module , ModuleInfo , ModuleRuntime } ;
@@ -26,14 +26,17 @@ use crate::host::wasm_common::module_host_actor::{
2626 WasmInstance ,
2727} ;
2828use crate :: host:: wasm_common:: { RowIters , TimingSpanSet } ;
29- use crate :: host:: { ModuleHost , ReducerCallError , ReducerCallResult , Scheduler } ;
29+ use crate :: host:: {
30+ ModuleHost , ProcedureCallError , ProcedureCallResult , ReducerCallError , ReducerCallResult , Scheduler ,
31+ } ;
3032use crate :: module_host_context:: { ModuleCreationContext , ModuleCreationContextLimited } ;
3133use crate :: replica_context:: ReplicaContext ;
3234use crate :: util:: asyncify;
3335use anyhow:: Context as _;
3436use core:: any:: type_name;
3537use core:: str;
3638use enum_as_inner:: EnumAsInner ;
39+ use futures:: FutureExt ;
3740use itertools:: Either ;
3841use spacetimedb_auth:: identity:: ConnectionAuthCtx ;
3942use spacetimedb_client_api_messages:: energy:: FunctionBudget ;
@@ -381,10 +384,16 @@ impl JsInstance {
381384 }
382385
383386 pub async fn call_procedure (
384- & mut self ,
385- _params : CallProcedureParams ,
386- ) -> Result < super :: ProcedureCallResult , super :: ProcedureCallError > {
387- todo ! ( "JS/TS module procedure support" )
387+ self : Box < Self > ,
388+ params : CallProcedureParams ,
389+ ) -> ( Result < ProcedureCallResult , ProcedureCallError > , Box < Self > ) {
390+ let ( r, s) = self
391+ . send_recv (
392+ JsWorkerReply :: into_call_procedure,
393+ JsWorkerRequest :: CallProcedure { params } ,
394+ )
395+ . await ;
396+ ( * r, s)
388397 }
389398
390399 pub async fn call_view ( self : Box < Self > , tx : MutTxId , params : CallViewParams ) -> ( ViewCallResult , Box < Self > ) {
@@ -401,6 +410,7 @@ enum JsWorkerReply {
401410 UpdateDatabase ( anyhow:: Result < UpdateDatabaseResult > ) ,
402411 CallReducer ( ReducerCallResult ) ,
403412 CallView ( Box < ViewCallResult > ) ,
413+ CallProcedure ( Box < Result < ProcedureCallResult , ProcedureCallError > > ) ,
404414 ClearAllClients ( anyhow:: Result < ( ) > ) ,
405415 CallIdentityConnected ( Result < ( ) , ClientConnectedError > ) ,
406416 CallIdentityDisconnected ( Result < ( ) , ReducerCallError > ) ,
@@ -426,6 +436,8 @@ enum JsWorkerRequest {
426436 } ,
427437 /// See [`JsInstance::call_view`].
428438 CallView { tx : MutTxId , params : CallViewParams } ,
439+ /// See [`JsInstance::call_procedure`].
440+ CallProcedure { params : CallProcedureParams } ,
429441 /// See [`JsInstance::clear_all_clients`].
430442 ClearAllClients ,
431443 /// See [`JsInstance::call_identity_connected`].
@@ -579,6 +591,14 @@ fn spawn_instance_worker(
579591 let ( res, trapped) = instance_common. call_view_with_tx ( tx, params, & mut inst) ;
580592 reply ( "call_view" , JsWorkerReply :: CallView ( res. into ( ) ) , trapped) ;
581593 }
594+ JsWorkerRequest :: CallProcedure { params } => {
595+ let ( res, trapped) = instance_common
596+ . call_procedure ( params, & mut inst)
597+ . now_or_never ( )
598+ . expect ( "our call_procedure implementation is not actually async" ) ;
599+
600+ reply ( "call_procedure" , JsWorkerReply :: CallProcedure ( res. into ( ) ) , trapped) ;
601+ }
582602 JsWorkerRequest :: ClearAllClients => {
583603 let res = instance_common. clear_all_clients ( ) ;
584604 reply ( "clear_all_clients" , ClearAllClients ( res) , false ) ;
@@ -758,11 +778,10 @@ impl WasmInstance for V8Instance<'_, '_, '_> {
758778 }
759779
760780 fn call_reducer ( & mut self , op : ReducerOp < ' _ > , budget : FunctionBudget ) -> ReducerExecuteResult {
761- let ExecutionResult { stats , call_result } = common_call ( self . scope , budget, op, |scope, op| {
781+ common_call ( self . scope , budget, op, |scope, op| {
762782 Ok ( call_call_reducer ( scope, self . hooks , op) ?)
763- } ) ;
764- let call_result = call_result. and_then ( |res| res. map_err ( ExecutionError :: User ) ) ;
765- ExecutionResult { stats, call_result }
783+ } )
784+ . map_result ( |call_result| call_result. and_then ( |res| res. map_err ( ExecutionError :: User ) ) )
766785 }
767786
768787 fn call_view ( & mut self , op : ViewOp < ' _ > , budget : FunctionBudget ) -> ViewExecuteResult {
@@ -781,8 +800,16 @@ impl WasmInstance for V8Instance<'_, '_, '_> {
781800 log_traceback ( self . replica_ctx , func_type, func, trap)
782801 }
783802
784- async fn call_procedure ( & mut self , _op : ProcedureOp , _budget : FunctionBudget ) -> ProcedureExecuteResult {
785- todo ! ( "JS/TS module procedure support" )
803+ async fn call_procedure ( & mut self , op : ProcedureOp , budget : FunctionBudget ) -> ProcedureExecuteResult {
804+ common_call ( self . scope , budget, op, |scope, op| {
805+ call_call_procedure ( scope, self . hooks , op)
806+ } )
807+ . map_result ( |call_result| {
808+ call_result. map_err ( |e| match e {
809+ ExecutionError :: User ( e) => anyhow:: Error :: msg ( e) ,
810+ ExecutionError :: Recoverable ( e) | ExecutionError :: Trap ( e) => e,
811+ } )
812+ } )
786813 }
787814}
788815
0 commit comments