diff --git a/js/react_renderer/src/renderer.tsx b/js/react_renderer/src/renderer.tsx index 63e73e0..fd78b10 100644 --- a/js/react_renderer/src/renderer.tsx +++ b/js/react_renderer/src/renderer.tsx @@ -52,10 +52,7 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): }, appendInitialChild: (parentInstance: Instance, child: Instance | TextInstance): void => { - Promise.all([parentInstance, child]) - .then(([resolvedParent, resolvedChild]) => { - InternalApi.op_react_append_child(resolvedParent, resolvedChild) - }) + InternalApi.op_react_append_child(parentInstance, child) }, finalizeInitialChildren: ( @@ -131,18 +128,12 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): appendChild(parentInstance: Instance, child: Instance | TextInstance): void { assertMutationMode(options.mode); - Promise.all([parentInstance, child]) - .then(([resolvedParent, resolvedChild]) => { - InternalApi.op_react_append_child(resolvedParent, resolvedChild) - }) + InternalApi.op_react_append_child(parentInstance, child) }, appendChildToContainer(container: Container, child: Instance | TextInstance): void { assertMutationMode(options.mode); - Promise.all([container, child]) - .then(([resolvedContainer, resolvedChild]) => { - InternalApi.op_react_append_child(resolvedContainer, resolvedChild) - }) + InternalApi.op_react_append_child(container, child) }, insertBefore( @@ -152,10 +143,7 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): ): void { assertMutationMode(options.mode); - Promise.all([parentInstance, child, beforeChild]) - .then(([resolvedParentInstance, resolvedChild, resolvedBeforeChild]) => { - InternalApi.op_react_insert_before(resolvedParentInstance, resolvedChild, resolvedBeforeChild) - }) + InternalApi.op_react_insert_before(parentInstance, child, beforeChild) }, insertInContainerBefore( container: Container, @@ -164,10 +152,7 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): ): void { assertMutationMode(options.mode); - Promise.all([container, child, beforeChild]) - .then(([resolvedContainer, resolvedChild, resolvedBeforeChild]) => { - InternalApi.op_react_insert_before(resolvedContainer, resolvedChild, resolvedBeforeChild) - }) + InternalApi.op_react_insert_before(container, child, beforeChild) }, removeChild( @@ -176,10 +161,7 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): ): void { assertMutationMode(options.mode); - Promise.all([parentInstance, child]) - .then(([resolvedParent, resolvedChild]) => { - InternalApi.op_react_remove_child(resolvedParent, resolvedChild) - }) + InternalApi.op_react_remove_child(parentInstance, child) }, removeChildFromContainer( container: Container, @@ -187,10 +169,7 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): ): void { assertMutationMode(options.mode); - Promise.all([container, child]) - .then(([resolvedContainer, resolvedChild]) => { - InternalApi.op_react_remove_child(resolvedContainer, resolvedChild) - }) + InternalApi.op_react_remove_child(container, child) }, @@ -201,13 +180,13 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): const props = Object.fromEntries( updatePayload.map(propName => [propName, nextProps[propName]]) ); - instance.then(value => InternalApi.op_react_set_properties(value, props)); + InternalApi.op_react_set_properties(instance, props); } }, commitTextUpdate(textInstance: TextInstance, oldText: string, newText: string): void { assertMutationMode(options.mode); - textInstance.then(value => InternalApi.op_react_set_text(value, newText)) + InternalApi.op_react_set_text(textInstance, newText) }, hideInstance(instance: Instance): void { @@ -268,10 +247,8 @@ export const createHostConfig = (options: { mode: "mutation" | "persistent" }): replaceContainerChildren(container: Container, newChildren: ChildSet): void { assertPersistentMode(options.mode); - Promise.all([container, ...newChildren]) - .then(([resolvedContainer, ...resolvedChild]) => { - InternalApi.op_react_replace_container_children(resolvedContainer, resolvedChild) - }) + + InternalApi.op_react_replace_container_children(container, newChildren) }, cloneHiddenInstance( diff --git a/js/typings/index.d.ts b/js/typings/index.d.ts index 957c491..542d333 100644 --- a/js/typings/index.d.ts +++ b/js/typings/index.d.ts @@ -18,23 +18,23 @@ declare interface Deno { declare type PluginEvent = ViewEvent | ViewCreated | ViewDestroyed | PluginCommand -declare type ViewEvent = { +declare type ViewEvent = { type: "ViewEvent" eventName: string - widget: InstanceSync + widget: Instance } -declare type ViewCreated = { +declare type ViewCreated = { type: "ViewCreated" reconcilerMode: string viewName: string } -declare type ViewDestroyed = { +declare type ViewDestroyed = { type: "ViewDestroyed" } -declare type PluginCommand = { +declare type PluginCommand = { type: "PluginCommand" commandType: "stop" } @@ -45,16 +45,14 @@ declare type Type = string; declare type Props = { children?: any } & { [key: string]: any }; declare type Container = Instance -declare type Instance = Promise -declare type TextInstance = Promise -declare type InstanceSync = UiWidget -declare type TextInstanceSync = UiWidget -declare type ChildSet = (InstanceSync | TextInstanceSync)[] +declare type Instance = UiWidget +declare type TextInstance = UiWidget +declare type ChildSet = (Instance | TextInstance)[] type SuspenseInstance = never; declare interface InternalApi { - op_react_call_event_listener(instance: InstanceSync, eventName: string): void; + op_react_call_event_listener(instance: Instance, eventName: string): void; op_react_get_container(): Container; @@ -62,25 +60,25 @@ declare interface InternalApi { op_react_create_text_instance(text: string): TextInstance; - op_react_append_child(parent: InstanceSync, child: InstanceSync | TextInstanceSync): void; + op_react_append_child(parent: Instance, child: Instance | TextInstance): void; - op_react_call_event_listener(instance: InstanceSync, eventName: string): void; + op_react_call_event_listener(instance: Instance, eventName: string): void; // mutation mode - op_react_remove_child(parent: InstanceSync, child: InstanceSync | TextInstanceSync): void; + op_react_remove_child(parent: Instance, child: Instance | TextInstance): void; op_react_insert_before( - parent: InstanceSync, - child: InstanceSync | TextInstanceSync | SuspenseInstance, - beforeChild: InstanceSync | TextInstanceSync | SuspenseInstance + parent: Instance, + child: Instance | TextInstance | SuspenseInstance, + beforeChild: Instance | TextInstance | SuspenseInstance ): void; - op_react_set_properties(instance: InstanceSync, properties: Props): void; + op_react_set_properties(instance: Instance, properties: Props): void; - op_react_set_text(instance: InstanceSync, text: string): void; + op_react_set_text(instance: Instance, text: string): void; // persistent mode op_react_clone_instance(type: Type, properties: Props): Instance; - op_react_replace_container_children(container: InstanceSync, newChildren: ChildSet): void; + op_react_replace_container_children(container: Instance, newChildren: ChildSet): void; } diff --git a/rust/server/src/lib.rs b/rust/server/src/lib.rs index ee3b011..f49eb65 100644 --- a/rust/server/src/lib.rs +++ b/rust/server/src/lib.rs @@ -9,7 +9,7 @@ pub(in crate) mod model; mod dirs; pub fn start_server() { - let runtime = tokio::runtime::Builder::new_current_thread() + let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap(); diff --git a/rust/server/src/plugins/js.rs b/rust/server/src/plugins/js.rs index c72ccbe..5d42462 100644 --- a/rust/server/src/plugins/js.rs +++ b/rust/server/src/plugins/js.rs @@ -7,6 +7,7 @@ use std::rc::Rc; use anyhow::anyhow; use deno_core::{FastString, futures, ModuleLoader, ModuleSource, ModuleSourceFuture, ModuleType, op, OpState, ResolutionKind, serde_v8, StaticModuleLoader, v8}; use deno_core::futures::{FutureExt, Stream, StreamExt}; +use deno_core::futures::executor::block_on; use deno_runtime::deno_core::ModuleSpecifier; use deno_runtime::permissions::PermissionsContainer; use deno_runtime::worker::MainWorker; @@ -369,10 +370,10 @@ deno_core::extension!( #[op] -async fn op_react_get_container(state: Rc>) -> anyhow::Result { +fn op_react_get_container(state: Rc>) -> anyhow::Result { println!("op_react_get_container"); - let container = match make_request_receive(&state, JsUiRequestData::GetContainer).await? { + let container = match make_request_receive(&state, JsUiRequestData::GetContainer)? { JsUiResponseData::GetContainer { container } => container, value @ _ => panic!("unsupported response type {:?}", value), }; @@ -383,7 +384,7 @@ async fn op_react_get_container(state: Rc>) -> anyhow::Result>, parent: JsUiWidget, child: JsUiWidget, @@ -395,7 +396,7 @@ async fn op_react_append_child( child, }; - match make_request_receive(&state, data).await? { + match make_request_receive(&state, data)? { JsUiResponseData::Nothing => { println!("op_react_append_child end"); Ok(()) @@ -405,7 +406,7 @@ async fn op_react_append_child( } #[op] -async fn op_react_remove_child( +fn op_react_remove_child( state: Rc>, parent: JsUiWidget, child: JsUiWidget, @@ -417,7 +418,7 @@ async fn op_react_remove_child( child: child.into(), }; - match make_request_receive(&state, data).await? { + match make_request_receive(&state, data)? { JsUiResponseData::Nothing => { println!("op_react_remove_child end"); Ok(()) @@ -427,7 +428,7 @@ async fn op_react_remove_child( } #[op] -async fn op_react_insert_before( +fn op_react_insert_before( state: Rc>, parent: JsUiWidget, child: JsUiWidget, @@ -441,7 +442,7 @@ async fn op_react_insert_before( before_child, }; - match make_request_receive(&state, data).await? { + match make_request_receive(&state, data)? { JsUiResponseData::Nothing => { println!("op_react_insert_before end"); Ok(()) @@ -456,7 +457,7 @@ fn op_react_create_instance<'a>( state: Rc>, widget_type: String, v8_properties: HashMap>, -) -> anyhow::Result> + 'static> { +) -> anyhow::Result { // TODO component model println!("op_react_create_instance"); @@ -475,20 +476,18 @@ fn op_react_create_instance<'a>( println!("op_react_create_instance end"); - Ok(async move { - let widget = match make_request_receive(&state, data).await? { - JsUiResponseData::CreateInstance { widget } => widget, - value @ _ => panic!("unsupported response type {:?}", value), - }; + let widget = match make_request_receive(&state, data)? { + JsUiResponseData::CreateInstance { widget } => widget, + value @ _ => panic!("unsupported response type {:?}", value), + }; - assign_event_listeners(&state, &widget, &conversion_properties); + assign_event_listeners(&state, &widget, &conversion_properties); - Ok(widget.into()) - }) + Ok(widget.into()) } #[op] -async fn op_react_create_text_instance( +fn op_react_create_text_instance( state: Rc>, text: String, ) -> anyhow::Result { @@ -496,7 +495,7 @@ async fn op_react_create_text_instance( let data = JsUiRequestData::CreateTextInstance { text }; - let widget = match make_request_receive(&state, data).await? { + let widget = match make_request_receive(&state, data)? { JsUiResponseData::CreateTextInstance { widget } => widget, value @ _ => panic!("unsupported response type {:?}", value), }; @@ -512,7 +511,7 @@ fn op_react_set_properties<'a>( state: Rc>, widget: JsUiWidget, v8_properties: HashMap>, -) -> anyhow::Result> + 'static> { +) -> anyhow::Result<()> { println!("op_react_set_properties"); let properties = convert_properties(scope, v8_properties)?; @@ -530,12 +529,12 @@ fn op_react_set_properties<'a>( println!("op_react_set_properties end"); - Ok(async move { - match make_request_receive(&state, data).await? { - JsUiResponseData::Nothing => Ok(()), - value @ _ => panic!("unsupported response type {:?}", value), - } - }) + match make_request_receive(&state, data)? { + JsUiResponseData::Nothing => { + Ok(()) + }, + value @ _ => panic!("unsupported response type {:?}", value), + } } #[op] @@ -579,7 +578,7 @@ fn op_react_call_event_listener( } #[op] -async fn op_react_set_text( +fn op_react_set_text( state: Rc>, widget: JsUiWidget, text: String, @@ -593,14 +592,14 @@ async fn op_react_set_text( println!("op_react_set_text end"); - match make_request_receive(&state, data).await? { + match make_request_receive(&state, data)? { JsUiResponseData::Nothing => Ok(()), value @ _ => panic!("unsupported response type {:?}", value), } } #[op] -async fn op_react_replace_container_children( +fn op_react_replace_container_children( state: Rc>, container: JsUiWidget, new_children: Vec, @@ -614,7 +613,7 @@ async fn op_react_replace_container_children( println!("op_react_replace_container_children end"); - match make_request_receive(&state, data).await? { + match make_request_receive(&state, data)? { JsUiResponseData::Nothing => Ok(()), value @ _ => panic!("unsupported response type {:?}", value), } @@ -626,7 +625,7 @@ fn op_react_clone_instance<'a>( state: Rc>, widget_type: String, v8_properties: HashMap>, -) -> anyhow::Result> + 'static> { +) -> anyhow::Result { // TODO component model @@ -643,28 +642,30 @@ fn op_react_clone_instance<'a>( properties, }; + let widget = match make_request_receive(&state, data)? { + JsUiResponseData::CloneInstance { widget } => widget, + value @ _ => panic!("unsupported response type {:?}", value), + }; + + assign_event_listeners(&state, &widget, &conversion_properties); + println!("op_react_clone_instance end"); - Ok(async move { - let widget = match make_request_receive(&state, data).await? { - JsUiResponseData::CloneInstance { widget } => widget, - value @ _ => panic!("unsupported response type {:?}", value), - }; - - assign_event_listeners(&state, &widget, &conversion_properties); - - Ok(widget.into()) - }) + Ok(widget.into()) } -async fn make_request_receive(state: &Rc>, data: JsUiRequestData) -> anyhow::Result { +fn make_request_receive(state: &Rc>, data: JsUiRequestData) -> anyhow::Result { let request_sender = { state.borrow() .borrow::() .clone() }; - request_sender.channel.send_receive(data).await? + tokio::task::block_in_place(move || { + block_on(async { + request_sender.channel.send_receive(data).await? + }) + }) } fn make_request(state: &Rc>, data: JsUiRequestData) -> anyhow::Result<()> { diff --git a/rust/server/src/plugins/mod.rs b/rust/server/src/plugins/mod.rs index 0f96b34..7c9bbd4 100644 --- a/rust/server/src/plugins/mod.rs +++ b/rust/server/src/plugins/mod.rs @@ -224,15 +224,12 @@ impl ApplicationManager { fn start_plugin_runtime(&mut self, data: PluginRuntimeData) { let run_status_guard = self.run_status_holder.start_block(data.id.clone()); - let handle = move || { - let _run_status_guard = run_status_guard; - let runtime = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap(); + let handle = tokio::runtime::Handle::current(); - let local_set = tokio::task::LocalSet::new(); - local_set.block_on(&runtime, tokio::task::unconstrained(async move { + let thread_fn = move || { + let _run_status_guard = run_status_guard; + + handle.block_on(tokio::task::unconstrained(async move { let result = start_plugin_runtime(data).await; println!("runtime execution failed {:?}", result) })) @@ -240,7 +237,7 @@ impl ApplicationManager { std::thread::Builder::new() .name("plugin-js-thread".into()) - .spawn(handle) + .spawn(thread_fn) .expect("failed to spawn plugin js thread"); }