Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the LiveSocket and LiveChannel api into one central object. #289

Merged
merged 57 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
68646b1
checkpoint
mobile-bungalow Jan 3, 2025
f0912a3
more stubs
mobile-bungalow Jan 6, 2025
fd8f856
filling in connection stubs
mobile-bungalow Jan 6, 2025
5c3b320
remove swiftpm cruft
mobile-bungalow Jan 6, 2025
9f863d3
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Jan 6, 2025
de2ccaa
fill in all stubs
mobile-bungalow Jan 7, 2025
bc65287
reorganize
mobile-bungalow Jan 7, 2025
86eb33a
and now on to testing
mobile-bungalow Jan 7, 2025
3315b2a
check
mobile-bungalow Jan 8, 2025
1f0a740
clippy
mobile-bungalow Jan 8, 2025
8d4d372
lints
mobile-bungalow Jan 8, 2025
c9fe5a8
wasm build fix
mobile-bungalow Jan 8, 2025
efbcee4
fmt needs nightly now.
mobile-bungalow Jan 8, 2025
0406c0c
nightly fmt
mobile-bungalow Jan 8, 2025
36323e3
failing swift tests
mobile-bungalow Jan 8, 2025
3898005
get the cookies from static memory
mobile-bungalow Jan 8, 2025
9156946
feature flag socket errors
mobile-bungalow Jan 8, 2025
a964ea7
move constructor to callbacks
mobile-bungalow Jan 8, 2025
e8a812a
missing modules
mobile-bungalow Jan 8, 2025
5fedf85
move more callbacks into callbacks module
mobile-bungalow Jan 9, 2025
682979f
reexports
mobile-bungalow Jan 9, 2025
514c322
move dom parser into dom module
mobile-bungalow Jan 9, 2025
7064cb5
first passing tests
mobile-bungalow Jan 9, 2025
46f9fde
use swiftui everywhere
mobile-bungalow Jan 9, 2025
07be329
use swiftui everywhere
mobile-bungalow Jan 9, 2025
a62e5c9
advanced navigation
mobile-bungalow Jan 9, 2025
13f3f24
uploads
mobile-bungalow Jan 9, 2025
9225032
ready for further testing
mobile-bungalow Jan 12, 2025
b88afab
playback test
mobile-bungalow Jan 13, 2025
368fca3
merge resolve
mobile-bungalow Jan 13, 2025
9e6409b
add swift unit tests
mobile-bungalow Jan 13, 2025
fe71f17
update interfaces
mobile-bungalow Jan 13, 2025
1ac8d92
less agressive dead render printing, oslogs
mobile-bungalow Jan 13, 2025
2e90044
complex platform conditionals for testing
mobile-bungalow Jan 13, 2025
4638b7b
give navigatio interface more parameter control
mobile-bungalow Jan 13, 2025
6f72b1d
clippy, expose more places to add headers, event inspection
mobile-bungalow Jan 13, 2025
c462eba
move connection opts onto each nav call
mobile-bungalow Jan 15, 2025
6414ac2
clippy, typos
mobile-bungalow Jan 15, 2025
e3d1e6a
upload single file
mobile-bungalow Jan 17, 2025
92f6a30
first draft handle live reload
mobile-bungalow Jan 20, 2025
81b3ce7
lints
mobile-bungalow Jan 20, 2025
7e93033
Merge branch 'main' into centralize_core
mobile-bungalow Jan 21, 2025
d806ca2
added socket status
mobile-bungalow Jan 24, 2025
f6cedb6
added socket status
mobile-bungalow Jan 24, 2025
62bb16a
swift support
mobile-bungalow Jan 25, 2025
e8eee72
Merge branch 'centralize_core' of github.com:mobile-bungalow/liveview…
mobile-bungalow Jan 25, 2025
f1c86b6
Merge branch 'main' into centralize_core
mobile-bungalow Jan 25, 2025
30b1a06
Merge branch 'centralize_core' of github.com:mobile-bungalow/liveview…
mobile-bungalow Jan 26, 2025
6a90426
wasm
mobile-bungalow Jan 26, 2025
f64be71
kotlin
mobile-bungalow Jan 26, 2025
101fa2a
payload
mobile-bungalow Jan 27, 2025
a80419a
tweaks for production
mobile-bungalow Jan 29, 2025
ad03783
add all event handlers and testing for patche and redirects
mobile-bungalow Feb 1, 2025
d822732
typos
mobile-bungalow Feb 1, 2025
a8cd206
clean up
mobile-bungalow Feb 2, 2025
2ec8157
aggressive persistence
mobile-bungalow Feb 2, 2025
8eea5cb
version diagnostics and no panic
mobile-bungalow Feb 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:

- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.CARGO_MAKE_TOOLCHAIN }}
toolchain: nightly
components: rustfmt

- name: Cargo fmt
Expand Down
21 changes: 18 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/core", "crates/uniffi-bindgen", "crates/wasm"]

[workspace.package]
version = "0.4.0-rc-4"
version = "0.4.0"
rust-version = "1.64"
authors = [
"Paul Schoenfelder <[email protected]>",
Expand All @@ -23,7 +23,7 @@ edition = "2021"
publish = false

[workspace.dependencies]
uniffi = "0.28.0"
uniffi = "0.28.3"

[profile.dev]
split-debuginfo = "unpacked"
Expand Down
18 changes: 15 additions & 3 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ name = "liveview_native_core"

[features]
default = ["liveview-channels-tls"]
liveview-channels = ["phoenix_channels_client", "reqwest", "uniffi/tokio"]
liveview-channels = [
"phoenix_channels_client",
"reqwest",
"uniffi/tokio",
"cookie_store",
"reqwest_cookie_store",
"tokio",
]
liveview-channels-tls = [
"liveview-channels",
"reqwest/native-tls-vendored",
Expand All @@ -37,6 +44,7 @@ browser = [
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde_urlencoded = "0.7.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be a optional dependency that's enabled with the liveview-channels feature.

cranelift-entity = { version = "0.115" }
fixedbitset = { version = "0.5" }
fxhash = { version = "0.2" }
Expand All @@ -54,7 +62,13 @@ log = "0.4"
reqwest = { version = "0.12.3", default-features = false, optional = true, features = [
"cookies",
] }

cookie_store = { version = "0.21.1", default-features = false, optional = true }
reqwest_cookie_store = { version = "0.8.0", default-features = false, optional = true }
env_logger = "0.11.1"
uniffi = { workspace = true }

tokio = { version = "1.42", features = ["full"], optional = true }
phoenix_channels_client = { git = "https://github.com/liveview-native/phoenix-channels-client.git", branch = "main", optional = true, default-features = false }
# This is for wasm support on phoenix-channels-client
#phoenix_channels_client = { git = "https://github.com/liveview-native/phoenix-channels-client.git", branch = "simlay/webassembly-support", optional = true, default-features = false }
Expand All @@ -67,8 +81,6 @@ paste = { version = "1.0" }
pretty_assertions = { version = "1.4.0" }
text-diff = { version = "0.4.0" }
uniffi = { workspace = true, features = ["bindgen-tests", "tokio"] }
tokio = { version = "1.42", features = ["full"] }
env_logger = "0.11.1"

# For image generation for tests
image = "0.25.1"
Expand Down
152 changes: 152 additions & 0 deletions crates/core/src/callbacks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use std::sync::Arc;

use crate::dom::{NodeData, NodeRef};

/// Provides secure persistent storage for session data like cookies.
/// Implementations should handle platform-specific storage (e.g. NSUserDefaults on iOS)
/// and ensure data is stored securely as some of it may be session tokens.
#[uniffi::export(callback_interface)]
pub trait SecurePersistentStore: Send + Sync {
/// Removes the entry for the given key
fn remove_entry(&self, key: String);

/// Gets the value for the given key, or None if not found
fn get(&self, key: String) -> Option<Vec<u8>>;

/// Sets the value for the given key
fn set(&self, key: String, value: Vec<u8>);
}

#[uniffi::export(callback_interface)]
pub trait NavEventHandler: Send + Sync {
/// This callback instruments events that occur when your user navigates to a
/// new view. You can add serialized metadata to these events as a byte buffer
/// through the [NavOptions] object.
fn handle_event(&self, event: NavEvent) -> HandlerResponse;
}

/// Unique id in the history stack
pub type HistoryId = u64;

/// User emitted response from [NavEventHandler::handle_event].
/// Determines whether or not the default navigation action is taken.
#[derive(uniffi::Enum, Clone, Debug, PartialEq, Default)]
pub enum HandlerResponse {
#[default]
/// Return this to proceed as normal.
Default,
/// Return this to cancel the navigation before it occurs.
PreventDefault,
}

#[derive(uniffi::Enum, Clone, Debug, PartialEq)]
pub enum NavEventType {
/// Pushing a new event onto the history stack
Push,
/// Replacing the most recent event on the history stack
Replace,
/// Reloading the view in place
Reload,
/// Skipping multiple items on the history stack, leaving them in tact.
Traverse,
}

#[derive(uniffi::Record, Clone, Debug, PartialEq)]
pub struct NavHistoryEntry {
/// The target url.
pub url: String,
/// Unique id for this piece of nav entry state.
pub id: HistoryId,
/// state passed in by the user, to be passed in to the navigation event callback.
pub state: Option<Vec<u8>>,
}

impl NavHistoryEntry {
/// Create a new navigation history entry
pub fn new(url: String, id: HistoryId, state: Option<Vec<u8>>) -> Self {
Self { url, id, state }
}
}

/// An event emitted when the user navigates between views.
#[derive(uniffi::Record, Clone, Debug, PartialEq)]
pub struct NavEvent {
/// The type of event being emitted.
pub event: NavEventType,
/// True if from and to point to the same path.
pub same_document: bool,
/// The previous location of the page, if there was one.
pub from: Option<NavHistoryEntry>,
/// Destination URL.
pub to: NavHistoryEntry,
/// Additional user provided metadata handed to the event handler.
pub info: Option<Vec<u8>>,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, uniffi::Enum)]
pub enum LiveChannelStatus {
/// [Channel] is waiting for the [Socket](crate::Socket) to
/// [Socket::connect](crate::Socket::connect) or automatically reconnect.
WaitingForSocketToConnect,
/// [Socket::status](crate::Socket::status) is
/// [SocketStatus::Connected](crate::SocketStatus::Connected) and [Channel] is waiting for
/// [Channel::join] to be called.
WaitingToJoin,
/// [Channel::join] was called and awaiting response from server.
Joining,
/// [Channel::join] was called previously, but the [Socket](crate::Socket) was disconnected and
/// reconnected.
WaitingToRejoin,
/// [Channel::join] was called and the server responded that the [Channel::topic] was joined
/// using [Channel::payload].
Joined,
/// [Channel::leave] was called and awaiting response from server.
Leaving,
/// [Channel::leave] was called and the server responded that the [Channel::topic] was left.
Left,
/// [Channel::shutdown] was called, but the async task hasn't exited yet.
ShuttingDown,
/// The async task has exited.
ShutDown,
}

#[repr(C)]
#[derive(Copy, Clone, uniffi::Enum)]
pub enum ChangeType {
Change = 0,
Add = 1,
Remove = 2,
Replace = 3,
}

#[derive(Copy, Clone, uniffi::Enum)]
pub enum EventType {
Changed, // { change: ChangeType },
}

#[derive(Clone, uniffi::Enum)]
pub enum ControlFlow {
ExitOk,
ExitErr(String),
ContinueListening,
}

/// Implements the change handling logic for inbound virtual dom
/// changes. Your logic for handling document patches should go here.
#[uniffi::export(callback_interface)]
pub trait DocumentChangeHandler: Send + Sync {
/// This callback should implement your dom manipulation logic
/// after receiving patches from LVN.
fn handle_document_change(
&self,
change_type: ChangeType,
node_ref: Arc<NodeRef>,
node_data: NodeData,
parent: Option<Arc<NodeRef>>,
);

/// Called when the channel status changes. Background operations like [LiveChannel::merge_diffs]
/// will exit with a status based on the return [ControlFlow] of this callback.
/// TODO: this should be deprecated after core takes responsibility for channel clean up
fn handle_channel_status(&self, channel_status: LiveChannelStatus) -> ControlFlow;
}
Loading
Loading