Skip to content

Commit ef6fcf8

Browse files
committed
v8: expose in client-api & cli & standalone
cli/publish: expose --js-path to publish js module
1 parent 689cea4 commit ef6fcf8

File tree

6 files changed

+50
-11
lines changed

6 files changed

+50
-11
lines changed

crates/cli/src/subcommands/publish.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,19 @@ pub fn cli() -> clap::Command {
4646
.short('b')
4747
.conflicts_with("project_path")
4848
.conflicts_with("build_options")
49+
.conflicts_with("js_file")
4950
.help("The system path (absolute or relative) to the compiled wasm binary we should publish, instead of building the project."),
5051
)
52+
.arg(
53+
Arg::new("js_file")
54+
.value_parser(clap::value_parser!(PathBuf))
55+
.long("js-path")
56+
.short('j')
57+
.conflicts_with("project_path")
58+
.conflicts_with("build_options")
59+
.conflicts_with("wasm_file")
60+
.help("UNSTABLE: The system path (absolute or relative) to the javascript file we should publish, instead of building the project."),
61+
)
5162
.arg(
5263
Arg::new("num_replicas")
5364
.value_parser(clap::value_parser!(u8))
@@ -90,6 +101,7 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
90101
let force = args.get_flag("force");
91102
let anon_identity = args.get_flag("anon_identity");
92103
let wasm_file = args.get_one::<PathBuf>("wasm_file");
104+
let js_file = args.get_one::<PathBuf>("js_file");
93105
let database_host = config.get_host_url(server)?;
94106
let build_options = args.get_one::<String>("build_options").unwrap();
95107
let num_replicas = args.get_one::<u8>("num_replicas");
@@ -108,13 +120,19 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
108120
));
109121
}
110122

111-
let path_to_wasm = if let Some(path) = wasm_file {
112-
println!("Skipping build. Instead we are publishing {}", path.display());
113-
path.clone()
123+
// Decide program file path and read program.
124+
// Optionally build the program.
125+
let (path_to_program, host_type) = if let Some(path) = wasm_file {
126+
println!("(WASM) Skipping build. Instead we are publishing {}", path.display());
127+
(path.clone(), "Wasm")
128+
} else if let Some(path) = js_file {
129+
println!("(JS) Skipping build. Instead we are publishing {}", path.display());
130+
(path.clone(), "Js")
114131
} else {
115-
build::exec_with_argstring(config.clone(), path_to_project, build_options).await?
132+
let path = build::exec_with_argstring(config.clone(), path_to_project, build_options).await?;
133+
(path, "Wasm")
116134
};
117-
let program_bytes = fs::read(path_to_wasm)?;
135+
let program_bytes = fs::read(path_to_program)?;
118136

119137
let server_address = {
120138
let url = Url::parse(&database_host)?;
@@ -191,6 +209,9 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
191209

192210
builder = add_auth_header_opt(builder, &auth_header);
193211

212+
// Set the host type.
213+
builder = builder.query(&[("host_type", host_type)]);
214+
194215
let res = builder.body(program_bytes).send().await?;
195216
if res.status() == StatusCode::UNAUTHORIZED && !anon_identity {
196217
// If we're not in the `anon_identity` case, then we have already forced the user to log in above (using `get_auth_header`), so this should be safe to unwrap.

crates/client-api/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ toml.workspace = true
6464

6565
[lints]
6666
workspace = true
67+
68+
[features]
69+
unstable = []

crates/client-api/src/routes/database.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ pub struct PublishDatabaseQueryParams {
500500
token: Option<spacetimedb_lib::Hash>,
501501
#[serde(default)]
502502
policy: MigrationPolicy,
503+
#[serde(default)]
504+
host_type: HostType,
503505
}
504506

505507
use spacetimedb_client_api_messages::http::SqlStmtResult;
@@ -537,10 +539,23 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate>(
537539
num_replicas,
538540
token,
539541
policy,
542+
host_type,
540543
}): Query<PublishDatabaseQueryParams>,
541544
Extension(auth): Extension<SpacetimeAuth>,
542545
body: Bytes,
543546
) -> axum::response::Result<axum::Json<PublishResult>> {
547+
// Feature gate V8 modules.
548+
// The host must've been compiled with the `unstable` feature.
549+
// TODO(v8): ungate this when V8 is ready to ship.
550+
#[cfg(not(feature = "unstable"))]
551+
if host_type == HostType::Js {
552+
return Err((
553+
StatusCode::BAD_REQUEST,
554+
"JS host type requires a host with unstable features",
555+
)
556+
.into());
557+
}
558+
544559
// You should not be able to publish to a database that you do not own
545560
// so, unless you are the owner, this will fail.
546561

@@ -645,7 +660,7 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate>(
645660
database_identity,
646661
program_bytes: body.into(),
647662
num_replicas,
648-
host_type: HostType::Wasm,
663+
host_type,
649664
},
650665
policy,
651666
)

crates/core/src/host/v8/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ impl ModuleRuntime for V8RuntimeInner {
9797
mcc.program.hash,
9898
);
9999

100-
if true {
101-
return Err::<JsModule, _>(anyhow::anyhow!("v8_todo"));
102-
}
103-
104100
// TODO(v8): determine min required ABI by module and check that it's supported?
105101

106102
// TODO(v8): validate function signatures like in WASM? Is that possible with V8?

crates/core/src/messages/control_db.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ pub struct NodeStatus {
7575
/// SEE: <https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeStatus>
7676
pub state: String,
7777
}
78-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
78+
#[derive(
79+
Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize, serde::Deserialize,
80+
)]
7981
#[repr(i32)]
8082
pub enum HostType {
83+
#[default]
8184
Wasm = 0,
8285
Js = 1,
8386
}

crates/standalone/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ required-features = [] # Features required to build this target (N/A for lib)
1919
[features]
2020
# Perfmaps for profiling modules
2121
perfmap = ["spacetimedb-core/perfmap"]
22+
unstable = ["spacetimedb-client-api/unstable"]
2223

2324
[dependencies]
2425
spacetimedb-client-api-messages.workspace = true

0 commit comments

Comments
 (0)