modrpc_codegen/codegen/js/
mod.rs1use genco::prelude::*;
2use mproto_codegen::codegen::{
3 name_util::snake_to_camel_case,
4 js::js_type_param_list,
5};
6
7use crate::{
8 ast::Interface,
9 Database,
10};
11
12pub use project::{js_project_gen, js_proto_package_gen};
13
14pub mod project;
15
16pub fn js_wit_object_class(
17 db: &Database,
18 object_interface: &Interface,
19 object_role_name: &String,
20) -> js::Tokens {
21 let mproto_cx = &mproto_codegen::codegen::CodegenCx::new_with_type_params(
22 db.mproto_db(), Some("./proto"), true, &object_interface.type_params,
23 );
24
25 let mut method_fields: js::Tokens = quote! { };
26 let mut method_args: js::Tokens = quote! { };
27 let mut method_set_fields: js::Tokens = quote! { };
28 let mut methods: js::Tokens = quote! { };
29
30 for methods_list in &object_interface.methods {
31 if !methods_list.roles.contains(object_role_name) { continue; }
32
33 for method in &methods_list.methods {
34 let input_type =
35 mproto_codegen::codegen::js::js_type_tokens(mproto_cx, &method.input_ty);
36 let output_type =
37 mproto_codegen::codegen::js::js_type_tokens(mproto_cx, &method.output_ty);
38
39 let input_encoder =
40 mproto_codegen::codegen::js::js_type_encoder(mproto_cx, &method.input_ty);
41 let output_encoder =
42 mproto_codegen::codegen::js::js_type_encoder(mproto_cx, &method.output_ty);
43
44 let method_name_camel = &snake_to_camel_case(&method.name);
45
46 if method.is_async {
47 method_fields = quote! {
48 $method_fields
49 private $(method_name_camel)Wasm: (input: Uint8Array) => any;
50 private $(method_name_camel)Resolvers: { [id: number] : (r: any) => void };
51 };
52
53 method_args = quote! {
54 $method_args
55 $(method_name_camel)Wasm: (input: Uint8Array) => any,
56 $(method_name_camel)Resolvers: { [id: number] : (r: any) => void },
57 };
58
59 method_set_fields = quote! {
60 $method_set_fields
61 this.$(method_name_camel)Wasm = $(method_name_camel)Wasm;
62 this.$(method_name_camel)Resolvers = $(method_name_camel)Resolvers;
63 };
64
65 methods = quote! {
66 $methods
67
68 public async $method_name_camel(input: $input_type): Promise<$output_type> {
69 const inputBuf = new Uint8Array(mproto.encodeValue($input_encoder, input));
70
71 const id = this.$(method_name_camel)Wasm(inputBuf);
72 const promise: Promise<any> = new Promise(resolve => {
73 this.$(method_name_camel)Resolvers[id] = resolve;
74 });
75
76 const outputBuf = await promise;
77 return mproto.decodeValue($output_encoder, outputBuf.buffer);
78 }
79 };
80 }
81 }
82 }
83
84 let mut type_param_encoder_fields: js::Tokens = quote! { };
85 let mut type_param_encoder_args: js::Tokens = quote! { };
86 let mut type_param_encoder_set_fields: js::Tokens = quote! { };
87
88 for type_param in &object_interface.type_params {
89 let type_param_name = type_param;
90 type_param_encoder_fields = quote! {
91 $type_param_encoder_fields
92 private $(type_param_name)Encoder: mproto.EncoderDecoder<$(type_param_name)>;
93 };
94 type_param_encoder_args = quote! {
95 $type_param_encoder_args
96 $(type_param_name)Encoder: mproto.EncoderDecoder<$(type_param_name)>,
97 };
98 type_param_encoder_set_fields = quote! {
99 $type_param_encoder_set_fields
100 this.$(type_param_name)Encoder = $(type_param_name)Encoder;
101 };
102 }
103
104 let object_interface_role_name = &format!("{}{}", object_interface.name, object_role_name);
105 let type_params_list = js_type_param_list(
106 &object_interface.type_params,
107 );
108
109 quote! {
110 class $object_interface_role_name$(type_params_list) {
111 $type_param_encoder_fields
112 $method_fields
113
114 constructor(
115 $type_param_encoder_args
116 $method_args
117 ) {
118 $type_param_encoder_set_fields
119 $method_set_fields
120 }
121
122 $methods
123 }
124 }
125}
126
127pub fn js_interface_init_state_tokens(
128 db: &mut Database,
129 interface: &Interface,
130) -> js::Tokens {
131 let init_state_struct = crate::codegen::interface_init_state(db, interface);
132 let init_state_struct_id = db.mproto_db_mut().local_mut().new_type_def(init_state_struct);
133
134 quote! {
135 $(mproto_codegen::codegen::js::js_type_def(
136 &mproto_codegen::codegen::CodegenCx::new(db.mproto_db(), None, true),
137 db.mproto_db().local().type_def(init_state_struct_id)
138 ))
139 }
140}