char/avril

(wip) why'd you have to go and make things so complicaaaaated?

git clone https://git.t4t.associates/char/avril

Charlotte Somport process extension to typescriptb2fc926

main
3.4 KiB121 linesraw
1use std::cell::RefCell;
2use std::convert::Infallible;
3use std::io;
4use std::rc::Rc;
5use std::sync::Arc;
6
7use avril_caps::Capabilities;
8use avril_core::serde_v8::JsBuffer;
9use avril_core::{Extension, Op};
10use avril_host::environment::Environment;
11use tokio::runtime::Handle;
12
13use avril_ext_file::Files;
14use avril_host::io::response;
15
16pub struct Tree;
17#[allow(dead_code)]
18impl Tree {
19    pub fn global() -> Arc<Self> {
20        Arc::new(Self)
21    }
22    pub(crate) fn stop_live_processes(&self) {}
23    pub fn force_live_processes(&self) {}
24    pub fn stop_sync_processes(&self) {}
25    pub fn claim_term(
26        &self,
27        runtime: &Handle,
28        owner: Arc<dyn Fn() + Send + Sync>,
29    ) -> io::Result<()> {
30        #[cfg(unix)]
31        {
32            let _enter = runtime.enter();
33            let mut termination =
34                tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())?;
35            runtime.spawn(async move {
36                while termination.recv().await.is_some() {
37                    owner();
38                }
39            });
40        }
41        #[cfg(not(unix))]
42        let _ = (runtime, owner);
43        Ok(())
44    }
45}
46
47pub fn init(
48    runtime: Handle,
49    _caps: Arc<Capabilities>,
50    _environment: Rc<RefCell<Environment>>,
51    _files: Arc<Files>,
52    _owner: tokio_util::sync::CancellationToken,
53    worker: bool,
54    _signal: super::SignalMode,
55) -> Extension {
56    let unavailable = || {
57        response(Err::<(), _>(io::Error::new(
58            io::ErrorKind::Unsupported,
59            "Subprocess execution is not supported on this platform",
60        )))
61    };
62    let mut ops = vec![
63        Op::new("op_process_spawn", move |_options: serde_json::Value| {
64            Ok::<_, Infallible>(unavailable())
65        }),
66        Op::new(
67            "op_process_run_sync",
68            move |_options: (serde_json::Value, Option<JsBuffer>)| {
69                Ok::<_, Infallible>(unavailable())
70            },
71        ),
72        Op::new("op_process_release", |_id: u64| Ok::<_, Infallible>(())),
73    ];
74    for name in [
75        "op_process_cancel_read",
76        "op_process_ref",
77        "op_process_kill",
78        "op_process_stop",
79        "op_process_resize",
80    ] {
81        ops.push(Op::new(name, move |_args: serde_json::Value| {
82            Ok::<_, Infallible>(unavailable())
83        }));
84    }
85    for name in [
86        "op_process_read",
87        "op_process_write",
88        "op_process_end",
89        "op_process_wait",
90    ] {
91        ops.push(Op::asynchronous_unreferenced(
92            name,
93            move |_args: serde_json::Value| async move { Ok::<_, Infallible>(unavailable()) },
94        ));
95    }
96    ops.push(Op::asynchronous(
97        "op_process_keepalive",
98        move |_args: serde_json::Value| async move { Ok::<_, Infallible>(unavailable()) },
99    ));
100    // Signal listeners report NotSupported through the shared ops, like the
101    // file operations map Unsupported.
102    ops.extend(super::signals::ops(&super::signals::State::create(
103        runtime, worker,
104    )));
105    Extension {
106        name: "ext:process",
107        dependencies: &["ext:encoding", "ext:file", "ext:web", "ext:webstreams"],
108        ops,
109        modules: &[
110            (
111                "ext:process/main.js",
112                include_str!(concat!(env!("OUT_DIR"), "/process.js")),
113            ),
114            (
115                "ext:process/signals.js",
116                include_str!(concat!(env!("OUT_DIR"), "/signals.js")),
117            ),
118        ],
119        entry_point: None,
120    }
121}