diff --git a/Cargo.toml b/Cargo.toml index 3e8b93e626..6b21db199d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -618,6 +618,10 @@ members = [ path = "engine/packages/depot-client-types" version = "=2.3.3-rc.2" + [workspace.dependencies.rivetkit] + path = "rivetkit-rust/packages/rivetkit" + version = "=2.3.3-rc.2" + [workspace.dependencies.rivetkit-core] path = "rivetkit-rust/packages/rivetkit-core" version = "=2.3.3-rc.2" diff --git a/rivetkit-rust/packages/rivetkit/src/actor.rs b/rivetkit-rust/packages/rivetkit/src/actor.rs index 00a9cc298b..a18047c878 100644 --- a/rivetkit-rust/packages/rivetkit/src/actor.rs +++ b/rivetkit-rust/packages/rivetkit/src/actor.rs @@ -14,7 +14,7 @@ use crate::queue::QueueSet; #[async_trait] pub trait Actor: Send + Sync + Sized + 'static { type State: Serialize + DeserializeOwned + Send + Sync + 'static; - type Input: DeserializeOwned + Send + 'static; + type Input: DeserializeOwned + Default + Send + 'static; type Actions: ActionSet; type Events: EventSet; type Queue: QueueSet; diff --git a/rivetkit-rust/packages/rivetkit/src/lib.rs b/rivetkit-rust/packages/rivetkit/src/lib.rs index 792bfe1295..d72d8033fa 100644 --- a/rivetkit-rust/packages/rivetkit/src/lib.rs +++ b/rivetkit-rust/packages/rivetkit/src/lib.rs @@ -29,6 +29,7 @@ pub use rivetkit_core::metrics_endpoint::RenderedMetrics; pub use rivetkit_core::serverless::{ CoreServerlessRuntime, ServerlessRequest, ServerlessResponse, ServerlessStreamError, }; +pub use rivetkit_core::serverless_http; pub use rivetkit_core::{ ActorConfig, ActorKey, ActorKeySegment, CanHibernateWebSocket, CompletableQueueMessage, ConnHandle, ConnId, EngineSpawnMode, EnqueueAndWaitOpts, KeepAwakeRegion, Kv, ListOpts, diff --git a/rivetkit-rust/packages/rivetkit/src/start.rs b/rivetkit-rust/packages/rivetkit/src/start.rs index 4415267ef5..964a48ad6f 100644 --- a/rivetkit-rust/packages/rivetkit/src/start.rs +++ b/rivetkit-rust/packages/rivetkit/src/start.rs @@ -191,7 +191,9 @@ pub async fn run_actor(start: Start) -> Result<()> { let state = match snapshot.decode()? { Some(state) => state, - None => A::create_state(&ctx, input.decode()?).await?, + // Absent input falls back to the input type's default, matching + // rivetkit-typescript where createState receives undefined input. + None => A::create_state(&ctx, input.decode_or_default()?).await?, }; ctx.set_state(state); ctx.clear_state_dirty(); @@ -647,7 +649,7 @@ mod tests { } } - #[derive(Debug, PartialEq, Eq, Serialize, serde::Deserialize)] + #[derive(Debug, Default, PartialEq, Eq, Serialize, serde::Deserialize)] struct LifecycleInput { count: u32, } @@ -658,7 +660,7 @@ mod tests { log: Vec, } - #[derive(Debug, PartialEq, Eq, Serialize, serde::Deserialize)] + #[derive(Debug, Default, PartialEq, Eq, Serialize, serde::Deserialize)] struct UnitInput; #[derive(Debug, Default, PartialEq, Eq, Serialize, serde::Deserialize)] @@ -1638,13 +1640,18 @@ mod tests { "local", )); + let is_new = snapshot.is_none(); let start = Start { ctx: ctx.clone(), input: Input { bytes: input, _p: PhantomData, }, - snapshot: Snapshot { bytes: snapshot }, + is_new, + snapshot: Snapshot { + is_new, + bytes: snapshot, + }, hibernated: Vec::new(), events: Events { ctx: ctx.clone(), @@ -1669,13 +1676,18 @@ mod tests { "local", )); + let is_new = snapshot.is_none(); Start { ctx: ctx.clone(), input: Input { bytes: input, _p: PhantomData, }, - snapshot: Snapshot { bytes: snapshot }, + is_new, + snapshot: Snapshot { + is_new, + bytes: snapshot, + }, hibernated: Vec::new(), events: Events { ctx, @@ -1700,7 +1712,11 @@ mod tests { bytes: None, _p: PhantomData, }, - snapshot: Snapshot { bytes: None }, + is_new: true, + snapshot: Snapshot { + is_new: true, + bytes: None, + }, hibernated: Vec::new(), events: Events { ctx, @@ -1726,7 +1742,11 @@ mod tests { bytes: None, _p: PhantomData, }, - snapshot: Snapshot { bytes: None }, + is_new: true, + snapshot: Snapshot { + is_new: true, + bytes: None, + }, hibernated: Vec::new(), events: Events { ctx,