#[cfg(not(target_family = "wasm"))]
pub(crate) mod native;
#[cfg(target_family = "wasm")]
pub(crate) mod wasm;
use crate::api::conn::Command;
use crate::api::conn::DbResponse;
use crate::api::Connect;
use crate::api::Result;
use crate::api::Surreal;
use crate::opt::IntoEndpoint;
use crate::value::Notification;
use async_channel::Sender;
use indexmap::IndexMap;
use std::collections::HashMap;
use std::io;
use std::marker::PhantomData;
use std::time::Duration;
use surrealdb_core::sql::Value as CoreValue;
use trice::Instant;
use uuid::Uuid;
pub(crate) const PATH: &str = "rpc";
const PING_INTERVAL: Duration = Duration::from_secs(5);
const REVISION_HEADER: &str = "revision";
enum RequestEffect {
Set {
key: String,
value: CoreValue,
},
Clear {
key: String,
},
Insert,
None,
}
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
enum ReplayMethod {
Use,
Signup,
Signin,
Invalidate,
Authenticate,
}
struct PendingRequest {
effect: RequestEffect,
response_channel: Sender<Result<DbResponse>>,
}
struct RouterState<Sink, Stream> {
vars: IndexMap<String, CoreValue>,
replay: IndexMap<ReplayMethod, Command>,
live_queries: HashMap<Uuid, async_channel::Sender<Result<Notification<CoreValue>>>>,
pending_requests: HashMap<i64, PendingRequest>,
last_activity: Instant,
sink: Sink,
stream: Stream,
}
impl<Sink, Stream> RouterState<Sink, Stream> {
pub fn new(sink: Sink, stream: Stream) -> Self {
RouterState {
vars: IndexMap::new(),
replay: IndexMap::new(),
live_queries: HashMap::new(),
pending_requests: HashMap::new(),
last_activity: Instant::now(),
sink,
stream,
}
}
async fn clear_pending_requests(&mut self) {
for (_id, request) in self.pending_requests.drain() {
let error = io::Error::from(io::ErrorKind::ConnectionReset);
let sender = request.response_channel;
sender.send(Err(crate::error::Db::from(error).into())).await.ok();
sender.close();
}
}
async fn clear_live_queries(&mut self) {
for (_id, sender) in self.live_queries.drain() {
let error = io::Error::from(io::ErrorKind::ConnectionReset);
sender.send(Err(crate::error::Db::from(error).into())).await.ok();
sender.close();
}
}
async fn reset(&mut self) {
self.clear_pending_requests().await;
self.clear_live_queries().await;
}
}
enum HandleResult {
Disconnected,
Ok,
}
#[derive(Debug)]
pub struct Ws;
#[derive(Debug)]
pub struct Wss;
#[derive(Debug, Clone)]
pub struct Client(());
impl Surreal<Client> {
pub fn connect<P>(
&self,
address: impl IntoEndpoint<P, Client = Client>,
) -> Connect<Client, ()> {
Connect {
surreal: self.inner.clone().into(),
#[expect(deprecated)]
address: address.into_endpoint(),
capacity: 0,
response_type: PhantomData,
}
}
}