spacetimedb/host/v8/
mod.rs

1use super::module_host::CallReducerParams;
2use crate::{
3    host::{
4        module_common::{build_common_module_from_raw, ModuleCommon},
5        module_host::{DynModule, Module, ModuleInfo, ModuleInstance, ModuleRuntime},
6        Scheduler,
7    },
8    module_host_context::ModuleCreationContext,
9    replica_context::ReplicaContext,
10};
11use anyhow::anyhow;
12use spacetimedb_datastore::locking_tx_datastore::MutTxId;
13use std::sync::{Arc, LazyLock};
14
15mod error;
16mod from_value;
17mod to_value;
18
19/// The V8 runtime, for modules written in e.g., JS or TypeScript.
20#[derive(Default)]
21pub struct V8Runtime {
22    _priv: (),
23}
24
25impl ModuleRuntime for V8Runtime {
26    fn make_actor(&self, mcc: ModuleCreationContext<'_>) -> anyhow::Result<impl Module> {
27        V8_RUNTIME_GLOBAL.make_actor(mcc)
28    }
29}
30
31#[cfg(test)]
32impl V8Runtime {
33    fn init_for_test() {
34        LazyLock::force(&V8_RUNTIME_GLOBAL);
35    }
36}
37
38static V8_RUNTIME_GLOBAL: LazyLock<V8RuntimeInner> = LazyLock::new(V8RuntimeInner::init);
39
40/// The actual V8 runtime, with initialization of V8.
41struct V8RuntimeInner {
42    _priv: (),
43}
44
45impl V8RuntimeInner {
46    fn init() -> Self {
47        // Our current configuration:
48        // - will pick a number of worker threads for background jobs based on the num CPUs.
49        // - does not allow idle tasks
50        let platform = v8::new_default_platform(0, false).make_shared();
51        // Initialize V8. Internally, this uses a global lock so it's safe that we don't.
52        v8::V8::initialize_platform(platform);
53        v8::V8::initialize();
54
55        Self { _priv: () }
56    }
57
58    fn make_actor(&self, mcc: ModuleCreationContext<'_>) -> anyhow::Result<impl Module> {
59        #![allow(unreachable_code, unused_variables)]
60
61        log::trace!(
62            "Making new V8 module host actor for database {} with module {}",
63            mcc.replica_ctx.database_identity,
64            mcc.program.hash,
65        );
66
67        if true {
68            return Err::<JsModule, _>(anyhow!("v8_todo"));
69        }
70
71        let desc = todo!();
72        // Validate and create a common module rom the raw definition.
73        let common = build_common_module_from_raw(mcc, desc)?;
74
75        Ok(JsModule { common })
76    }
77}
78
79#[derive(Clone)]
80struct JsModule {
81    common: ModuleCommon,
82}
83
84impl DynModule for JsModule {
85    fn replica_ctx(&self) -> &Arc<ReplicaContext> {
86        self.common.replica_ctx()
87    }
88
89    fn scheduler(&self) -> &Scheduler {
90        self.common.scheduler()
91    }
92}
93
94impl Module for JsModule {
95    type Instance = JsInstance;
96
97    type InitialInstances<'a> = std::iter::Empty<JsInstance>;
98
99    fn initial_instances(&mut self) -> Self::InitialInstances<'_> {
100        std::iter::empty()
101    }
102
103    fn info(&self) -> Arc<ModuleInfo> {
104        todo!()
105    }
106
107    fn create_instance(&self) -> Self::Instance {
108        todo!()
109    }
110}
111
112struct JsInstance;
113
114impl ModuleInstance for JsInstance {
115    fn trapped(&self) -> bool {
116        todo!()
117    }
118
119    fn update_database(
120        &mut self,
121        _program: spacetimedb_datastore::traits::Program,
122        _old_module_info: Arc<ModuleInfo>,
123    ) -> anyhow::Result<super::UpdateDatabaseResult> {
124        todo!()
125    }
126
127    fn call_reducer(&mut self, _tx: Option<MutTxId>, _params: CallReducerParams) -> super::ReducerCallResult {
128        todo!()
129    }
130}