mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-03-03 06:47:31 +00:00
fix liveview mounted event
This commit is contained in:
parent
06ca8c53d8
commit
c9612a085e
10 changed files with 195 additions and 176 deletions
packages
desktop
interpreter
liveview
|
@ -12,7 +12,7 @@ keywords = ["dom", "ui", "gui", "react"]
|
|||
[dependencies]
|
||||
dioxus-core = { workspace = true, features = ["serialize"] }
|
||||
dioxus-html = { workspace = true, features = ["serialize", "native-bind"] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["sledgehammer"]}
|
||||
dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] }
|
||||
dioxus-hot-reload = { workspace = true, optional = true }
|
||||
|
||||
serde = "1.0.136"
|
||||
|
@ -74,7 +74,7 @@ exitcode = "1.1.2"
|
|||
scraper = "0.16.0"
|
||||
|
||||
[build-dependencies]
|
||||
dioxus-interpreter-js = { workspace = true, features = ["sledgehammer"] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] }
|
||||
minify-js = "0.5.6"
|
||||
|
||||
# These tests need to be run on the main thread, so they cannot use rust's test harness.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use dioxus_interpreter_js::SLEDGEHAMMER_JS;
|
||||
use dioxus_interpreter_js::binary_protocol::SLEDGEHAMMER_JS;
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use dioxus_core::ScopeState;
|
|||
use dioxus_core::VirtualDom;
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
use dioxus_hot_reload::HotReloadMsg;
|
||||
use dioxus_interpreter_js::Channel;
|
||||
use dioxus_interpreter_js::binary_protocol::Channel;
|
||||
use rustc_hash::FxHashMap;
|
||||
use slab::Slab;
|
||||
use std::cell::RefCell;
|
||||
|
|
|
@ -14,7 +14,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
|
|||
wasm-bindgen = { workspace = true, optional = true }
|
||||
js-sys = { version = "0.3.56", optional = true }
|
||||
web-sys = { version = "0.3.56", optional = true, features = ["Element", "Node"] }
|
||||
sledgehammer_bindgen = { path = "/Users/evanalmloff/Desktop/Github/sledgehammer_bindgen", default-features = false, optional = true }
|
||||
sledgehammer_bindgen = { git = "https://github.com/ealmloff/sledgehammer_bindgen", default-features = false, optional = true }
|
||||
sledgehammer_utils = { version = "0.2", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
|
||||
|
@ -23,4 +23,5 @@ default = []
|
|||
serialize = ["serde"]
|
||||
sledgehammer = ["sledgehammer_bindgen", "sledgehammer_utils"]
|
||||
web = ["sledgehammer", "wasm-bindgen", "js-sys", "web-sys", "sledgehammer_bindgen/web"]
|
||||
binary-protocol = ["sledgehammer"]
|
||||
minimal_bindings = []
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#[cfg(feature = "web")]
|
||||
use js_sys::Function;
|
||||
#[cfg(feature = "web")]
|
||||
use sledgehammer_bindgen::bindgen;
|
||||
#[cfg(feature = "web")]
|
||||
use web_sys::Node;
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
pub const SLEDGEHAMMER_JS: &str = GENERATED_JS;
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
#[bindgen(module)]
|
||||
mod js {
|
||||
|
@ -285,152 +288,157 @@ mod js {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "web"))]
|
||||
#[bindgen]
|
||||
mod js {
|
||||
const JS_FILE: &str = "./packages/interpreter/src/interpreter.js";
|
||||
#[cfg(feature = "binary-protocol")]
|
||||
pub mod binary_protocol {
|
||||
use sledgehammer_bindgen::bindgen;
|
||||
pub const SLEDGEHAMMER_JS: &str = GENERATED_JS;
|
||||
|
||||
fn mount_to_root() {
|
||||
"{AppendChildren(root, stack.length-1);}"
|
||||
}
|
||||
fn push_root(root: u32) {
|
||||
"{stack.push(nodes[$root$]);}"
|
||||
}
|
||||
fn append_children(id: u32, many: u16) {
|
||||
"{AppendChildren($id$, $many$);}"
|
||||
}
|
||||
fn append_children_to_top(many: u16) {
|
||||
"{
|
||||
root = stack[stack.length-many-1];
|
||||
els = stack.splice(stack.length-many);
|
||||
for (k = 0; k < many; k++) {
|
||||
root.appendChild(els[k]);
|
||||
}
|
||||
}"
|
||||
}
|
||||
fn pop_root() {
|
||||
"{stack.pop();}"
|
||||
}
|
||||
fn replace_with(id: u32, n: u16) {
|
||||
"{root = nodes[$id$]; els = stack.splice(stack.length-$n$); if (root.listening) { listeners.removeAllNonBubbling(root); } root.replaceWith(...els);}"
|
||||
}
|
||||
fn insert_after(id: u32, n: u16) {
|
||||
"{nodes[$id$].after(...stack.splice(stack.length-$n$));}"
|
||||
}
|
||||
fn insert_before(id: u32, n: u16) {
|
||||
"{nodes[$id$].before(...stack.splice(stack.length-$n$));}"
|
||||
}
|
||||
fn remove(id: u32) {
|
||||
"{node = nodes[$id$]; if (node !== undefined) { if (node.listening) { listeners.removeAllNonBubbling(node); } node.remove(); }}"
|
||||
}
|
||||
fn create_raw_text(text: &str) {
|
||||
"{stack.push(document.createTextNode($text$));}"
|
||||
}
|
||||
fn create_text_node(text: &str, id: u32) {
|
||||
"{node = document.createTextNode($text$); nodes[$id$] = node; stack.push(node);}"
|
||||
}
|
||||
fn create_element(element: &'static str<u8, el>) {
|
||||
"{stack.push(document.createElement($element$))}"
|
||||
}
|
||||
fn create_element_ns(element: &'static str<u8, el>, ns: &'static str<u8, namespace>) {
|
||||
"{stack.push(document.createElementNS($ns$, $element$))}"
|
||||
}
|
||||
fn create_placeholder(id: u32) {
|
||||
"{node = document.createElement('pre'); node.hidden = true; stack.push(node); nodes[$id$] = node;}"
|
||||
}
|
||||
fn add_placeholder() {
|
||||
"{node = document.createElement('pre'); node.hidden = true; stack.push(node);}"
|
||||
}
|
||||
fn new_event_listener(event_name: &str<u8, evt>, id: u32, bubbles: u8) {
|
||||
r#"
|
||||
bubbles = bubbles == 1;
|
||||
node = nodes[id];
|
||||
if(node.listening){
|
||||
node.listening += 1;
|
||||
} else {
|
||||
node.listening = 1;
|
||||
#[bindgen]
|
||||
mod protocol_js {
|
||||
const JS_FILE: &str = "./packages/interpreter/src/interpreter.js";
|
||||
|
||||
fn mount_to_root() {
|
||||
"{AppendChildren(root, stack.length-1);}"
|
||||
}
|
||||
node.setAttribute('data-dioxus-id', `\${id}`);
|
||||
|
||||
// if this is a mounted listener, we send the event immediately
|
||||
if (event_name === "mounted") {
|
||||
window.ipc.postMessage(
|
||||
serializeIpcMessage("user_event", {
|
||||
name: event_name,
|
||||
element: edit.id,
|
||||
data: null,
|
||||
bubbles,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
listeners.create(event_name, node, bubbles, (event) => {
|
||||
handler(event, event_name, bubbles, config);
|
||||
});
|
||||
}"#
|
||||
}
|
||||
fn remove_event_listener(event_name: &str<u8, evt>, id: u32, bubbles: u8) {
|
||||
"{node = nodes[$id$]; node.listening -= 1; node.removeAttribute('data-dioxus-id'); listeners.remove(node, $event_name$, $bubbles$);}"
|
||||
}
|
||||
fn set_text(id: u32, text: &str) {
|
||||
"{nodes[$id$].textContent = $text$;}"
|
||||
}
|
||||
fn set_attribute(id: u32, field: &str<u8, attr>, value: &str, ns: &str<u8, ns_cache>) {
|
||||
"{node = nodes[$id$]; SetAttributeInner(node, $field$, $value$, $ns$);}"
|
||||
}
|
||||
fn set_top_attribute(field: &str<u8, attr>, value: &str, ns: &str<u8, ns_cache>) {
|
||||
"{SetAttributeInner(stack[stack.length-1], $field$, $value$, $ns$);}"
|
||||
}
|
||||
fn remove_attribute(id: u32, field: &str<u8, attr>, ns: &str<u8, ns_cache>) {
|
||||
r#"{
|
||||
node = nodes[$id$];
|
||||
if (!ns) {
|
||||
switch (field) {
|
||||
case "value":
|
||||
node.value = "";
|
||||
break;
|
||||
case "checked":
|
||||
node.checked = false;
|
||||
break;
|
||||
case "selected":
|
||||
node.selected = false;
|
||||
break;
|
||||
case "dangerous_inner_html":
|
||||
node.innerHTML = "";
|
||||
break;
|
||||
default:
|
||||
node.removeAttribute(field);
|
||||
break;
|
||||
fn push_root(root: u32) {
|
||||
"{stack.push(nodes[$root$]);}"
|
||||
}
|
||||
fn append_children(id: u32, many: u16) {
|
||||
"{AppendChildren($id$, $many$);}"
|
||||
}
|
||||
fn append_children_to_top(many: u16) {
|
||||
"{
|
||||
root = stack[stack.length-many-1];
|
||||
els = stack.splice(stack.length-many);
|
||||
for (k = 0; k < many; k++) {
|
||||
root.appendChild(els[k]);
|
||||
}
|
||||
} else if (ns == "style") {
|
||||
node.style.removeProperty(name);
|
||||
}"
|
||||
}
|
||||
fn pop_root() {
|
||||
"{stack.pop();}"
|
||||
}
|
||||
fn replace_with(id: u32, n: u16) {
|
||||
"{root = nodes[$id$]; els = stack.splice(stack.length-$n$); if (root.listening) { listeners.removeAllNonBubbling(root); } root.replaceWith(...els);}"
|
||||
}
|
||||
fn insert_after(id: u32, n: u16) {
|
||||
"{nodes[$id$].after(...stack.splice(stack.length-$n$));}"
|
||||
}
|
||||
fn insert_before(id: u32, n: u16) {
|
||||
"{nodes[$id$].before(...stack.splice(stack.length-$n$));}"
|
||||
}
|
||||
fn remove(id: u32) {
|
||||
"{node = nodes[$id$]; if (node !== undefined) { if (node.listening) { listeners.removeAllNonBubbling(node); } node.remove(); }}"
|
||||
}
|
||||
fn create_raw_text(text: &str) {
|
||||
"{stack.push(document.createTextNode($text$));}"
|
||||
}
|
||||
fn create_text_node(text: &str, id: u32) {
|
||||
"{node = document.createTextNode($text$); nodes[$id$] = node; stack.push(node);}"
|
||||
}
|
||||
fn create_element(element: &'static str<u8, el>) {
|
||||
"{stack.push(document.createElement($element$))}"
|
||||
}
|
||||
fn create_element_ns(element: &'static str<u8, el>, ns: &'static str<u8, namespace>) {
|
||||
"{stack.push(document.createElementNS($ns$, $element$))}"
|
||||
}
|
||||
fn create_placeholder(id: u32) {
|
||||
"{node = document.createElement('pre'); node.hidden = true; stack.push(node); nodes[$id$] = node;}"
|
||||
}
|
||||
fn add_placeholder() {
|
||||
"{node = document.createElement('pre'); node.hidden = true; stack.push(node);}"
|
||||
}
|
||||
fn new_event_listener(event_name: &str<u8, evt>, id: u32, bubbles: u8) {
|
||||
r#"
|
||||
bubbles = bubbles == 1;
|
||||
node = nodes[id];
|
||||
if(node.listening){
|
||||
node.listening += 1;
|
||||
} else {
|
||||
node.removeAttributeNS(ns, field);
|
||||
node.listening = 1;
|
||||
}
|
||||
}"#
|
||||
}
|
||||
fn assign_id(array: &[u8], id: u32) {
|
||||
"{nodes[$id$] = LoadChild($array$);}"
|
||||
}
|
||||
fn hydrate_text(array: &[u8], value: &str, id: u32) {
|
||||
r#"{
|
||||
node = LoadChild($array$);
|
||||
if (node.nodeType == Node.TEXT_NODE) {
|
||||
node.textContent = value;
|
||||
node.setAttribute('data-dioxus-id', `\${id}`);
|
||||
|
||||
// if this is a mounted listener, we send the event immediately
|
||||
if (event_name === "mounted") {
|
||||
window.ipc.postMessage(
|
||||
serializeIpcMessage("user_event", {
|
||||
name: event_name,
|
||||
element: id,
|
||||
data: null,
|
||||
bubbles,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
let text = document.createTextNode(value);
|
||||
node.replaceWith(text);
|
||||
node = text;
|
||||
}
|
||||
nodes[$id$] = node;
|
||||
}"#
|
||||
}
|
||||
fn replace_placeholder(array: &[u8], n: u16) {
|
||||
"{els = stack.splice(stack.length - $n$); node = LoadChild($array$); node.replaceWith(...els);}"
|
||||
}
|
||||
fn load_template(tmpl_id: u16, index: u16, id: u32) {
|
||||
"{node = templates[$tmpl_id$][$index$].cloneNode(true); nodes[$id$] = node; stack.push(node);}"
|
||||
}
|
||||
fn add_templates(tmpl_id: u16, len: u16) {
|
||||
"{templates[$tmpl_id$] = stack.splice(stack.length-$len$);}"
|
||||
listeners.create(event_name, node, bubbles, (event) => {
|
||||
handler(event, event_name, bubbles, config);
|
||||
});
|
||||
}"#
|
||||
}
|
||||
fn remove_event_listener(event_name: &str<u8, evt>, id: u32, bubbles: u8) {
|
||||
"{node = nodes[$id$]; node.listening -= 1; node.removeAttribute('data-dioxus-id'); listeners.remove(node, $event_name$, $bubbles$);}"
|
||||
}
|
||||
fn set_text(id: u32, text: &str) {
|
||||
"{nodes[$id$].textContent = $text$;}"
|
||||
}
|
||||
fn set_attribute(id: u32, field: &str<u8, attr>, value: &str, ns: &str<u8, ns_cache>) {
|
||||
"{node = nodes[$id$]; SetAttributeInner(node, $field$, $value$, $ns$);}"
|
||||
}
|
||||
fn set_top_attribute(field: &str<u8, attr>, value: &str, ns: &str<u8, ns_cache>) {
|
||||
"{SetAttributeInner(stack[stack.length-1], $field$, $value$, $ns$);}"
|
||||
}
|
||||
fn remove_attribute(id: u32, field: &str<u8, attr>, ns: &str<u8, ns_cache>) {
|
||||
r#"{
|
||||
node = nodes[$id$];
|
||||
if (!ns) {
|
||||
switch (field) {
|
||||
case "value":
|
||||
node.value = "";
|
||||
break;
|
||||
case "checked":
|
||||
node.checked = false;
|
||||
break;
|
||||
case "selected":
|
||||
node.selected = false;
|
||||
break;
|
||||
case "dangerous_inner_html":
|
||||
node.innerHTML = "";
|
||||
break;
|
||||
default:
|
||||
node.removeAttribute(field);
|
||||
break;
|
||||
}
|
||||
} else if (ns == "style") {
|
||||
node.style.removeProperty(name);
|
||||
} else {
|
||||
node.removeAttributeNS(ns, field);
|
||||
}
|
||||
}"#
|
||||
}
|
||||
fn assign_id(array: &[u8], id: u32) {
|
||||
"{nodes[$id$] = LoadChild($array$);}"
|
||||
}
|
||||
fn hydrate_text(array: &[u8], value: &str, id: u32) {
|
||||
r#"{
|
||||
node = LoadChild($array$);
|
||||
if (node.nodeType == Node.TEXT_NODE) {
|
||||
node.textContent = value;
|
||||
} else {
|
||||
let text = document.createTextNode(value);
|
||||
node.replaceWith(text);
|
||||
node = text;
|
||||
}
|
||||
nodes[$id$] = node;
|
||||
}"#
|
||||
}
|
||||
fn replace_placeholder(array: &[u8], n: u16) {
|
||||
"{els = stack.splice(stack.length - $n$); node = LoadChild($array$); node.replaceWith(...els);}"
|
||||
}
|
||||
fn load_template(tmpl_id: u16, index: u16, id: u32) {
|
||||
"{node = templates[$tmpl_id$][$index$].cloneNode(true); nodes[$id$] = node; stack.push(node);}"
|
||||
}
|
||||
fn add_templates(tmpl_id: u16, len: u16) {
|
||||
"{templates[$tmpl_id$] = stack.splice(stack.length-$len$);}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ serde_json = "1.0.91"
|
|||
rustc-hash = { workspace = true }
|
||||
dioxus-html = { workspace = true, features = ["serialize"] }
|
||||
dioxus-core = { workspace = true, features = ["serialize"] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["sledgehammer"] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] }
|
||||
dioxus-hot-reload = { workspace = true, optional = true }
|
||||
|
||||
# warp
|
||||
|
@ -54,7 +54,7 @@ salvo = { version = "0.44.1", features = ["affix", "ws"] }
|
|||
tower = "0.4.13"
|
||||
|
||||
[build-dependencies]
|
||||
dioxus-interpreter-js = { workspace = true, features = ["sledgehammer"] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] }
|
||||
minify-js = "0.5.6"
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use dioxus_interpreter_js::SLEDGEHAMMER_JS;
|
||||
use dioxus_interpreter_js::binary_protocol::SLEDGEHAMMER_JS;
|
||||
use minify_js::*;
|
||||
use std::io::Write;
|
||||
|
||||
|
@ -55,9 +55,9 @@ fn main() {
|
|||
let js = format!("{interpreter}\n{main_js}");
|
||||
|
||||
let session = Session::new();
|
||||
let mut out = Vec::new();
|
||||
minify(&session, TopLevelMode::Module, js.as_bytes(), &mut out).unwrap();
|
||||
let minified = String::from_utf8(out).unwrap();
|
||||
// let mut out = Vec::new();
|
||||
// minify(&session, TopLevelMode::Module, js.as_bytes(), &mut out).unwrap();
|
||||
// let minified = String::from_utf8(out).unwrap();
|
||||
let mut file = std::fs::File::create("src/minified.js").unwrap();
|
||||
file.write_all(minified.as_bytes()).unwrap();
|
||||
file.write_all(js.as_bytes()).unwrap();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ impl RenderedElementBacking for LiveviewElement {
|
|||
>,
|
||||
>,
|
||||
> {
|
||||
let script = format!("return window.interpreter.GetClientRect({});", self.id.0);
|
||||
let script = format!("return getClientRect({});", self.id.0);
|
||||
|
||||
let fut = self
|
||||
.query
|
||||
|
@ -53,7 +53,7 @@ impl RenderedElementBacking for LiveviewElement {
|
|||
behavior: dioxus_html::ScrollBehavior,
|
||||
) -> std::pin::Pin<Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<()>>>> {
|
||||
let script = format!(
|
||||
"return window.interpreter.ScrollTo({}, {});",
|
||||
"return scrollTo({}, {});",
|
||||
self.id.0,
|
||||
serde_json::to_string(&behavior).expect("Failed to serialize ScrollBehavior")
|
||||
);
|
||||
|
@ -76,10 +76,7 @@ impl RenderedElementBacking for LiveviewElement {
|
|||
&self,
|
||||
focus: bool,
|
||||
) -> std::pin::Pin<Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<()>>>> {
|
||||
let script = format!(
|
||||
"return window.interpreter.SetFocus({}, {});",
|
||||
self.id.0, focus
|
||||
);
|
||||
let script = format!("return setFocus({}, {});", self.id.0, focus);
|
||||
|
||||
let fut = self.query.new_query::<bool>(&script).resolve();
|
||||
|
||||
|
|
|
@ -28,19 +28,26 @@ class IPC {
|
|||
};
|
||||
|
||||
ws.onmessage = (message) => {
|
||||
if (message.data instanceof ArrayBuffer) {
|
||||
console.log(message.data);
|
||||
const u8view = new Uint8Array(message.data);
|
||||
const binaryFrame = u8view[0] == 1;
|
||||
const messageData = message.data.slice(1)
|
||||
// The first byte tells the shim if this is a binary of text frame
|
||||
if (binaryFrame) {
|
||||
// binary frame
|
||||
run_from_bytes(message.data);
|
||||
} else {
|
||||
run_from_bytes(messageData);
|
||||
}
|
||||
else {
|
||||
// text frame
|
||||
|
||||
let decoder = new TextDecoder("utf-8");
|
||||
|
||||
// Using decode method to get string output
|
||||
let str = decoder.decode(messageData);
|
||||
// Ignore pongs
|
||||
if (message.data != "__pong__") {
|
||||
const event = JSON.parse(message.data);
|
||||
if (str != "__pong__") {
|
||||
const event = JSON.parse(str);
|
||||
switch (event.type) {
|
||||
case "edits":
|
||||
let edits = event.data;
|
||||
window.interpreter.handleEdits(edits);
|
||||
break;
|
||||
case "query":
|
||||
Function("Eval", `"use strict";${event.data};`)();
|
||||
break;
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
};
|
||||
use dioxus_core::{prelude::*, BorrowedAttributeValue, Mutations};
|
||||
use dioxus_html::{event_bubbles, EventData, HtmlEvent, MountedData};
|
||||
use dioxus_interpreter_js::Channel;
|
||||
use dioxus_interpreter_js::binary_protocol::Channel;
|
||||
use futures_util::{pin_mut, SinkExt, StreamExt};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Serialize;
|
||||
|
@ -173,7 +173,7 @@ pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), Li
|
|||
match evt.as_ref().map(|o| o.as_deref()) {
|
||||
// respond with a pong every ping to keep the websocket alive
|
||||
Some(Ok(b"__ping__")) => {
|
||||
// ws.send(b"__pong__".to_vec()).await?;
|
||||
ws.send(text_frame("__pong__")).await?;
|
||||
}
|
||||
Some(Ok(evt)) => {
|
||||
if let Ok(message) = serde_json::from_str::<IpcMessage>(&String::from_utf8_lossy(evt)) {
|
||||
|
@ -212,7 +212,7 @@ pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), Li
|
|||
|
||||
// handle any new queries
|
||||
Some(query) = query_rx.recv() => {
|
||||
// ws.send(serde_json::to_string(&ClientUpdate::Query(query)).unwrap().into_bytes()).await?;
|
||||
ws.send(text_frame(&serde_json::to_string(&ClientUpdate::Query(query)).unwrap())).await?;
|
||||
}
|
||||
|
||||
Some(msg) = hot_reload_wait => {
|
||||
|
@ -247,13 +247,19 @@ pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), Li
|
|||
}
|
||||
}
|
||||
|
||||
fn text_frame(text: &str) -> Vec<u8> {
|
||||
let mut bytes = vec![0];
|
||||
bytes.extend(text.as_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
fn add_template(
|
||||
template: &Template<'static>,
|
||||
channel: &mut Channel,
|
||||
templates: &mut FxHashMap<String, u16>,
|
||||
max_template_count: &mut u16,
|
||||
) {
|
||||
for (idx, root) in template.roots.iter().enumerate() {
|
||||
for root in template.roots.iter() {
|
||||
create_template_node(channel, root);
|
||||
templates.insert(template.name.to_owned(), *max_template_count);
|
||||
}
|
||||
|
@ -368,16 +374,16 @@ fn apply_edits(
|
|||
}
|
||||
}
|
||||
|
||||
let bytes: Vec<_> = channel.export_memory().collect();
|
||||
// Add an extra one at the beginning to tell the shim this is a binary frame
|
||||
let mut bytes = vec![1];
|
||||
bytes.extend(channel.export_memory());
|
||||
channel.reset();
|
||||
Some(bytes)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
enum ClientUpdate<'a> {
|
||||
#[serde(rename = "edits")]
|
||||
Edits(Mutations<'a>),
|
||||
enum ClientUpdate {
|
||||
#[serde(rename = "query")]
|
||||
Query(String),
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue