feat(sync): add typed acknowledgement effect
req: sync/006
This commit is contained in:
+29
-5
@@ -1,4 +1,4 @@
|
||||
use hemx_core::{Effect, EffectBatch, IntoEffect};
|
||||
use hemx_core::{Atom, Effect, EffectBatch, IntoEffect};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
@@ -12,6 +12,7 @@ pub use hemx_sync_macros::presence;
|
||||
|
||||
pub const PATCH_SCHEMA_VERSION: u16 = 1;
|
||||
pub const PATCH_EVENT: &str = "hemx:sync-patch";
|
||||
pub const ACK_EVENT: &str = "hemx:sync-ack";
|
||||
const INTERACTION_ID: &str = "$hemx-interaction";
|
||||
pub const BROWSER_RUNTIME: &str = include_str!("../runtime/hemx-sync.js");
|
||||
|
||||
@@ -387,7 +388,7 @@ fn validate_key(key: &str) -> Result<(), PatchError> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct SyncEffect(Effect); // req: sync/002
|
||||
pub struct SyncEffect(Vec<Effect>); // req: sync/002
|
||||
|
||||
impl SyncEffect {
|
||||
// req: sync/004
|
||||
@@ -398,18 +399,29 @@ impl SyncEffect {
|
||||
}
|
||||
}
|
||||
|
||||
// req: sync/006
|
||||
pub fn ack<T>(atom: Atom<T>) -> Self {
|
||||
Self(vec![
|
||||
atom.set("acknowledged"),
|
||||
Effect::Emit {
|
||||
name: ACK_EVENT.to_owned(),
|
||||
payload: format!(r#"{{"atomId":{}}}"#, atom.id().id),
|
||||
},
|
||||
])
|
||||
}
|
||||
|
||||
pub fn send_patch(patch: FlatPatch) -> Self {
|
||||
patch.validate().expect("FlatPatch must remain valid");
|
||||
Self(Effect::Emit {
|
||||
Self(vec![Effect::Emit {
|
||||
name: PATCH_EVENT.to_owned(),
|
||||
payload: patch.payload(),
|
||||
})
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoEffect for SyncEffect {
|
||||
fn append_to(self, ops: &mut Vec<Effect>) {
|
||||
self.0.append_to(ops);
|
||||
ops.extend(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,6 +429,18 @@ impl IntoEffect for SyncEffect {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn acknowledgement_updates_atom_and_emits_queue_signal() {
|
||||
let atom = Atom::<String>::new(17);
|
||||
let batch = SyncEffect::ack(atom).into_batch(hemx_core::BuildFingerprint(3));
|
||||
assert!(
|
||||
matches!(&batch.ops[0], Effect::Put { target, payload: hemx_core::Payload::Text(payload) } if target.resource == atom.id() && payload == "acknowledged")
|
||||
);
|
||||
assert!(
|
||||
matches!(&batch.ops[1], Effect::Emit { name, payload } if name == ACK_EVENT && payload == r#"{"atomId":17}"#)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn presence_macro_projects_an_ordinary_effect_on_its_channel() {
|
||||
struct Signal(Channel);
|
||||
|
||||
Reference in New Issue
Block a user