From 8a59112127a29a6fd8c035c39d538b49e3c9a2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pokrywka?= Date: Sun, 3 May 2026 10:59:46 +0200 Subject: [PATCH] Added `on_change_file`, in `dom!` macro fixed block of statements with inferred attr name --- .../vertigo-macro/src/html_parser/commons.rs | 25 +++++-- .../src/html_parser/group_attrs.rs | 1 + crates/vertigo-macro/src/html_parser/node.rs | 6 +- crates/vertigo/src/dom/dom_element.rs | 37 ++++++++++ crates/vertigo/src/dom_macro/dom.rs | 2 + .../src_js/api/command/dom/callbackManager.ts | 45 ++++++++++++- crates/vertigo/src/driver_module/wasm_run.js | 2 +- .../vertigo/src/driver_module/wasm_run.js.map | 2 +- .../src/tests/dom/component_namespaces.rs | 51 +++++++------- crates/vertigo/src/tests/dom/html_attrs.rs | 64 +++++++++++++++--- crates/vertigo/src/tests/dom/list_spread.rs | 67 +++++++++---------- crates/vertigo/src/tests/dom/params.rs | 43 ++++++++++-- docs/CHANGELOG.md | 2 + 13 files changed, 261 insertions(+), 86 deletions(-) diff --git a/crates/vertigo-macro/src/html_parser/commons.rs b/crates/vertigo-macro/src/html_parser/commons.rs index 03a58e09..32e23e68 100644 --- a/crates/vertigo-macro/src/html_parser/commons.rs +++ b/crates/vertigo-macro/src/html_parser/commons.rs @@ -149,9 +149,16 @@ pub(super) fn parse_block_of_statements( quote! { into() } }; - // If the last statement is a reference, use it as the value - // Otherwise, try to unwrap single statement block or use the whole block as the value - let value = dereferenced.unwrap_or_else(|| unwrap_block_if_single(block)); + // For multi-statement blocks ending with a reference, keep the whole block so that + // preceding statements (e.g. `let mut x = ...; x += 1; &x`) are not lost. + // For single-statement reference blocks (e.g. `{&my_var}`), use the inner expression + // directly so `.clone()` applies to the value, not to a double-reference. + // For non-reference blocks, unwrap single-statement blocks or use the whole block. + let value = match &dereferenced { + Some(inner) if block.stmts.len() > 1 => block.to_token_stream(), + Some(inner) => inner.clone(), + None => unwrap_block_if_single(block), + }; (key, value, method) } @@ -237,7 +244,7 @@ mod tests { #[test] fn test_parse_block_of_statements_reference_value() { - // Reference: key and value are the inner expr; method is clone() + // Single-statement reference: inner expr used as value so `.clone()` applies correctly let block: Block = syn::parse_quote! { { &my_var } }; let (key, value, method) = parse_block_of_statements(&block); assert_eq!(key.to_string(), "my_var"); @@ -245,6 +252,16 @@ mod tests { assert_eq!(method.to_string(), "clone ()"); } + #[test] + fn test_parse_block_of_statements_reference_with_preceding_stmts() { + // Multi-statement block ending with a reference: whole block preserved as value + let block: Block = syn::parse_quote! { { let mut x = 1; x += 1; &x } }; + let (key, value, method) = parse_block_of_statements(&block); + assert_eq!(key.to_string(), "x"); + assert_eq!(value.to_string(), "{ let mut x = 1 ; x += 1 ; & x }"); + assert_eq!(method.to_string(), "clone ()"); + } + #[test] fn test_extract_spread_block_with_spread() { // Spread block: last stmt is a range like `..expr` diff --git a/crates/vertigo-macro/src/html_parser/group_attrs.rs b/crates/vertigo-macro/src/html_parser/group_attrs.rs index 987cca8a..d9cf9367 100644 --- a/crates/vertigo-macro/src/html_parser/group_attrs.rs +++ b/crates/vertigo-macro/src/html_parser/group_attrs.rs @@ -53,6 +53,7 @@ fn attr_to_group_variant(key: impl AsRef, value: TokenStream2) -> TokenStre "hook_key_down" => quote! { vertigo::AttrGroupValue::hook_key_down(#value) }, "on_blur" => quote! { vertigo::AttrGroupValue::on_blur(#value) }, "on_change" => quote! { vertigo::AttrGroupValue::on_change(#value) }, + "on_change_file" => quote! { vertigo::AttrGroupValue::on_change_file(#value) }, "on_click" => quote! { vertigo::AttrGroupValue::on_click(#value) }, "on_dropfile" => quote! { vertigo::AttrGroupValue::on_dropfile(#value) }, "on_input" => quote! { vertigo::AttrGroupValue::on_input(#value) }, diff --git a/crates/vertigo-macro/src/html_parser/node.rs b/crates/vertigo-macro/src/html_parser/node.rs index 83c58227..6f9a0b7e 100644 --- a/crates/vertigo-macro/src/html_parser/node.rs +++ b/crates/vertigo-macro/src/html_parser/node.rs @@ -161,9 +161,9 @@ fn push_attribute( } let method_str = match name.as_str() { - "hook_key_down" | "on_blur" | "on_change" | "on_click" | "on_dropfile" | "on_input" - | "on_key_down" | "on_load" | "on_mouse_down" | "on_mouse_enter" | "on_mouse_leave" - | "on_mouse_up" | "on_submit" => &name, + "hook_key_down" | "on_blur" | "on_change" | "on_change_file" | "on_click" + | "on_dropfile" | "on_input" | "on_key_down" | "on_load" | "on_mouse_down" + | "on_mouse_enter" | "on_mouse_leave" | "on_mouse_up" | "on_submit" => &name, "form" => "on_submit", diff --git a/crates/vertigo/src/dom/dom_element.rs b/crates/vertigo/src/dom/dom_element.rs index 518d4436..bc14c15f 100644 --- a/crates/vertigo/src/dom/dom_element.rs +++ b/crates/vertigo/src/dom/dom_element.rs @@ -108,6 +108,9 @@ impl DomElement { ("on_dropfile", AttrGroupValue::OnDropfile(on_dropfile)) => { self.on_dropfile_rc(on_dropfile) } + ("on_change_file", AttrGroupValue::OnChangeFile(on_change_file)) => { + self.on_change_file_rc(on_change_file) + } ("on_input", AttrGroupValue::OnInput(on_input)) => self.on_input_rc(on_input), ("on_key_down", AttrGroupValue::OnKeyDown(on_key_down)) => { self.on_key_down_rc(on_key_down) @@ -274,6 +277,40 @@ impl DomElement { }) } + pub fn on_change_file(self, on_change_file: impl Into>) -> Self { + self.on_change_file_rc(Rc::new(on_change_file.into())) + } + + pub fn on_change_file_rc(self, on_change_file: Rc>) -> Self { + let on_change_file = self.install_callback1(on_change_file); + + self.add_event_listener("change_file", move |data| { + let params = data.map_list(|mut params: JsJsonListDecoder| { + let files = params.get_vec("change file", |item: JsJson| { + item.map_list(|mut item: JsJsonListDecoder| { + let name = item.get_string("name")?; + let data = item.get_buffer("data")?; + + Ok(DropFileItem::new(name, data)) + }) + })?; + + Ok(DropFileEvent::new(files)) + }); + + match params { + Ok(params) => { + on_change_file(params); + } + Err(error) => { + log::error!("on_change_file -> params decode error -> {error}"); + } + }; + + JsJson::Null + }) + } + pub fn on_click(self, on_click: impl Into>) -> Self { self.on_click_rc(Rc::new(on_click.into())) } diff --git a/crates/vertigo/src/dom_macro/dom.rs b/crates/vertigo/src/dom_macro/dom.rs index e7002d3c..fd4acef1 100644 --- a/crates/vertigo/src/dom_macro/dom.rs +++ b/crates/vertigo/src/dom_macro/dom.rs @@ -51,6 +51,7 @@ pub enum AttrGroupValue { OnChange(Rc>), OnClick(Rc>), OnDropfile(Rc>), + OnChangeFile(Rc>), OnInput(Rc>), OnKeyDown(Rc>), OnLoad(Rc>), @@ -88,6 +89,7 @@ impl AttrGroupValue { group_value_constructor!(on_change, Callback1, OnChange); group_value_constructor!(on_click, Callback1, OnClick); group_value_constructor!(on_dropfile, Callback1, OnDropfile); + group_value_constructor!(on_change_file, Callback1, OnChangeFile); group_value_constructor!(on_input, Callback1, OnInput); group_value_constructor!(on_key_down, Callback1, OnKeyDown); group_value_constructor!(on_load, Callback<()>, OnLoad); diff --git a/crates/vertigo/src/driver_module/src_js/api/command/dom/callbackManager.ts b/crates/vertigo/src/driver_module/src_js/api/command/dom/callbackManager.ts index 00b89cb7..72517e6c 100644 --- a/crates/vertigo/src/driver_module/src_js/api/command/dom/callbackManager.ts +++ b/crates/vertigo/src/driver_module/src_js/api/command/dom/callbackManager.ts @@ -68,6 +68,10 @@ export class CallbackManager { return this.load(event, callback_id); } + if (event_name === 'change_file') { + return this.changeFile(event, callback_id); + } + console.error(`No support for the event ${event_name}`); }; @@ -82,7 +86,8 @@ export class CallbackManager { document.addEventListener('keydown', callback, false); } else { const node = nodes.get('callback_add', id); - node.addEventListener(event_name, callback, false); + const domEventName = event_name === 'change_file' ? 'change' : event_name; + node.addEventListener(domEventName, callback, false); } } @@ -99,7 +104,8 @@ export class CallbackManager { document.removeEventListener('keydown', callback); } else { const node = nodes.get('callback_remove', id); - node.removeEventListener(event_name, callback); + const domEventName = event_name === 'change_file' ? 'change' : event_name; + node.removeEventListener(domEventName, callback); } } @@ -154,6 +160,41 @@ export class CallbackManager { console.warn('event input ignore', target); } + private changeFile(event: Event, callback_id: CallbackId) { + const target = event.target; + + if (target instanceof HTMLInputElement && target.files !== null && target.files.length > 0) { + const promises: Array> = []; + + for (let i = 0; i < target.files.length; i++) { + const file = target.files[i]; + if (file !== undefined) { + promises.push( + file.arrayBuffer().then((buf) => ({ + name: file.name, + data: new Uint8Array(buf), + })) + ); + } + } + + if (promises.length > 0) { + Promise.all(promises).then((files) => { + const params = []; + for (const f of files) { + params.push([f.name, Array.from(f.data)]); + } + this.wasmCallback(callback_id, [params]); + }).catch((err) => console.error('changeFile ->', err)); + } + + target.value = ''; + return; + } + + console.warn('changeFile: not a file input or no files', target); + } + private blur(_event: Event, callback_id: CallbackId) { this.wasmCallback(callback_id, undefined); } diff --git a/crates/vertigo/src/driver_module/wasm_run.js b/crates/vertigo/src/driver_module/wasm_run.js index 9194d80c..35fd1557 100644 --- a/crates/vertigo/src/driver_module/wasm_run.js +++ b/crates/vertigo/src/driver_module/wasm_run.js @@ -1,2 +1,2 @@ -"use strict";const e=new TextDecoder("utf-8"),t=new TextEncoder;class o{constructor(e,t){this.getUint8Memory=e,this.pointer=0,this.ptr=Number(t>>32n),this.size=Number(t%2n**32n),this.dataView=new DataView(this.getUint8Memory().buffer,this.ptr,this.size)}getByte(){const e=this.dataView.getUint8(this.pointer);return this.pointer+=1,e}setByte(e){this.dataView.setUint8(this.pointer,e),this.pointer+=1}getU16(){const e=this.dataView.getUint16(this.pointer);return this.pointer+=2,e}setU16(e){this.dataView.setUint16(this.pointer,e),this.pointer+=2}getU32(){const e=this.dataView.getUint32(this.pointer);return this.pointer+=4,e}setU32(e){this.dataView.setUint32(this.pointer,e),this.pointer+=4}getI32(){const e=this.dataView.getInt32(this.pointer);return this.pointer+=4,e}setI32(e){this.dataView.setInt32(this.pointer,e),this.pointer+=4}getU64(){const e=this.dataView.getBigUint64(this.pointer);return this.pointer+=8,e}setU64(e){this.dataView.setBigUint64(this.pointer,e),this.pointer+=8}getI64(){const e=this.dataView.getBigInt64(this.pointer);return this.pointer+=8,e}setI64(e){this.dataView.setBigInt64(this.pointer,e),this.pointer+=8}getF64(){const e=this.dataView.getFloat64(this.pointer);return this.pointer+=8,e}setF64(e){this.dataView.setFloat64(this.pointer,e),this.pointer+=8}getBuffer(){const e=this.getU32(),t=this.getUint8Memory().subarray(this.ptr+this.pointer,this.ptr+this.pointer+e);return this.pointer+=e,t}setBuffer(e){const t=e.length;this.setU32(t);this.getUint8Memory().subarray(this.ptr+this.pointer,this.ptr+this.pointer+t).set(e),this.pointer+=t}getString(){return e.decode(this.getBuffer())}setString(e){const o=t.encode(e);this.setBuffer(o)}getSavedSize(){return this.pointer}}const n=1,s=2,r=3,i=4,a=5,l=6,c=7,d=8,h=9,u=e=>{if(!0===e||!1===e||null==e)return 1;if("string"==typeof e)return 5+(new TextEncoder).encode(e).length;if("number"==typeof e)return 9;if(e instanceof Uint8Array)return 5+e.length;if(Array.isArray(e)){let t=5;for(const o of e)t+=u(o);return t}if("object"==typeof e&&null!==e){let t=3;for(const[o,n]of Object.entries(e))t+=4+(new TextEncoder).encode(o).length,t+=u(n);return t}throw new Error("jsJsonGetSize: Unknown type "+typeof e)},m=e=>{const t=e.getByte();if(t===n)return!0;if(t===s)return!1;if(t===r)return null;if(t!==i){if(t===a)return e.getString();if(t===l)return e.getF64();if(t===c){const t=e.getU32(),o=[];for(let n=0;n{if(!0!==e)if(!1!==e)if(null!==e)if(void 0!==e){if("string"==typeof e)return t.setByte(a),void t.setString(e);if("number"==typeof e)return t.setByte(l),void t.setF64(e);if(e instanceof Uint8Array)return t.setByte(h),void t.setBuffer(e);if(!Array.isArray(e)){if("object"==typeof e&&null!==e){const o=Object.entries(e);t.setByte(d),t.setU16(o.length);for(const[e,n]of o)t.setString(e),f(n,t);return}throw new Error("saveJsJsonToBufferItem: Unknown type "+typeof e)}t.setByte(c),t.setU32(e.length);for(const o of e)f(o,t)}else t.setByte(i);else t.setByte(r);else t.setByte(s);else t.setByte(n)},g=async(e,t)=>{const n=await(async(e,t)=>{if("function"==typeof WebAssembly.instantiateStreaming){const o=fetch(e);try{return await WebAssembly.instantiateStreaming(o,t)}catch(e){console.warn("`WebAssembly.instantiateStreaming` failed. This could happen if your server does not serve wasm with `application/wasm` MIME type, but check the original error too. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e)}}console.info("fetchModule by WebAssembly.instantiate");const o=await fetch(e),n=await o.arrayBuffer();return await WebAssembly.instantiate(n,t)})(e,t);let s=new Uint8Array(1);const r=()=>{if(n.instance.exports.memory instanceof WebAssembly.Memory)return s.buffer!==n.instance.exports.memory.buffer&&(s=new Uint8Array(n.instance.exports.memory.buffer)),s;throw Error("Missing memory")},i=n.instance.exports;return{exports:i,getUint8Memory:r,wasmCommand:e=>{const t=u(e),n=i.vertigo_export_alloc_block(t),s=new o(r,n);f(e,s);let a=i.vertigo_export_wasm_command(n);if(0n===a)return null;const l=new o(r,a),c=m(l);return i.vertigo_export_free_block(a),c}}};class p{constructor(){this.events=new Set}on(e){let t=!0;const o=o=>{t&&e(o)};return this.events.add(o),()=>{t=!1,this.events.delete(o)}}trigger(e){const t=Array.from(this.events.values());for(const o of t)try{o(e)}catch(e){console.error(e)}}get size(){return this.events.size}}class v{constructor(){this.inner=null,this.resolve=e=>{const t=this.inner;this.inner=null,null!==t&&t.resolve(e)},this.reject=e=>{const t=this.inner;this.inner=null,null!==t&&t.reject(e)},this.isFulfilled=()=>null===this.inner;const[e,t]=(()=>{let e=null,t=null;const o=new Promise((o,n)=>{e=o,t=n});if(null===e)throw Error("createPromiseValue - resolve is null");if(null===t)throw Error("createPromiseValue - reject is null");return[{resolve:e,reject:t},o]})();this.inner=e,this.promise=t}}const w=async(e,t)=>{console.info(`${e} wait ${t}ms`),await(async e=>new Promise(t=>{setTimeout(t,e)}))(t),console.info(`${e} go forth`)};class k{constructor(e){this.host=e,this.formatLog=e=>`Socket ${this.host} ==> ${e}`}}class b{constructor(e,t){this.eventMessage=new p,this.close=e,this.send=t}static connect(e,t,o){const n=new v,s=new v,r=new WebSocket(t);let i=!1;console.info(e.formatLog("starting ..."));const a=()=>{i||(console.info(e.formatLog("close")),i=!0,n.resolve(null),s.resolve(),r.close())},l=new b(a,e=>{i||r.send(e)});setTimeout(()=>{!1===n.isFulfilled()&&(console.error(e.formatLog(`timeout (${o}ms)`)),a())},o);return r.addEventListener("open",()=>{console.info(e.formatLog("open")),n.resolve(l)}),r.addEventListener("error",t=>{console.error(e.formatLog("error"),t),a()}),r.addEventListener("close",a),r.addEventListener("message",t=>{if(i)return;const o=t.data;"string"!=typeof o?console.error(e.formatLog("onMessage - expected string"),o):l.eventMessage.trigger(o)}),{socket:n.promise,done:s.promise}}static startSocket(e,t,o,n){let s=!0,r=null;const i=new k(e);return(async()=>{for(;s;){const a=b.connect(i,e,t),l=await a.socket;if(null!==l){if(r=l,n({type:"socket",socket:l}),l.eventMessage.on(e=>{n({type:"message",message:e})}),await a.done,n({type:"close"}),!s)return void console.info(i.formatLog("disconnect (1)"));await w(i.formatLog("reconnect after close"),o)}else await w(i.formatLog("reconnect after error"),o)}console.info(i.formatLog("disconnect (2)"))})().catch(e=>{console.error(e)}),{send:e=>{null===r?console.error("send fail - missing connection",e):r.send(e)},dispose:()=>{s=!1,r?.close()}}}}const y=e=>{try{return JSON.parse(e)}catch{throw console.error("Failed to parse websocket message",e),Error(e)}},C=(e,t,o)=>{e.wasmCommand({Websocket:{callback:t,message:o}})};class E{constructor(e){this.websocket_register_callback=(e,t)=>{const o=this.getWasm();let n=b.startSocket(e,5e3,3e3,e=>{if(!1!==this.controllerList.has(t)){if("socket"===e.type)return this.socket.set(t,e.socket),void C(o,t,"Connected");if("message"!==e.type)return"close"===e.type?(this.socket.delete(t),void C(o,t,"Disconnected")):(e=>{throw console.error(e),Error("unknown message")})(e);C(o,t,{Message:{message:y(e.message)}})}});this.controllerList.set(t,n)},this.websocket_unregister_callback=e=>{const t=this.controllerList.get(e);void 0!==t?(t.dispose(),this.controllerList.delete(e)):console.error("Expected controller")},this.websocket_send_message=(e,t)=>{const o=this.socket.get(e);var n;void 0===o?console.error(`Missing socket connection for callback_id=${e}`):o.send((n=t,JSON.stringify(n)))},this.getWasm=e,this.controllerList=new Map,this.socket=new Map}}const T=e=>{const t={};for(const{k:o,v:n}of e)t[o]=n;return t},L=e=>{if("None"!==e)return JSON.stringify(e.Data.data)},x=async e=>{const t=e.status,o=e.headers.get("Content-Type");try{if(o?.startsWith("text/plain;"))return{Ok:{status:t,response:{Text:await e.text()}}};return{Ok:{status:t,response:{Json:0===(n=await e.text()).length?null:JSON.parse(n)}}}}catch(e){return{Err:{message:String(e)}}}var n};class S{constructor(e){this.timerSet=(e,t,o)=>{switch(o){case"Interval":{const o=setInterval(()=>{this.getWasm().wasmCommand({TimerCall:{callback:e}})},t);this.data.set(e,{kind:"Interval",timerId:o});break}case"Timeout":{const o=setTimeout(()=>{this.getWasm().wasmCommand({TimerCall:{callback:e}})},t);this.data.set(e,{kind:"Timeout",timerId:o});break}}},this.timerClear=e=>{const t=this.data.get(e);if(void 0===t)throw Error("panic");switch(t.kind){case"Interval":clearInterval(t.timerId);break;case"Timeout":clearTimeout(t.timerId)}},this.getWasm=e,this.data=new Map}}class N{constructor(e){this.trigger=()=>{for(const e of Array.from(this.callback.values()))e()},this.add=e=>{this.callback.set(e,()=>{this.getWasm().wasmCommand({LocationCall:{callback:e,value:this.get()}})})},this.remove=e=>{this.callback.delete(e)},this.push=e=>{this.get()!==e&&(location.hash=e,this.trigger())},this.replace=e=>{this.get()!==e&&history.replaceState(null,"",`#${e}`)},this.getWasm=e,this.callback=new Map,window.addEventListener("hashchange",this.trigger)}get(){return decodeURIComponent(location.hash.substr(1))}}class A{constructor(e){this.trigger=()=>{for(const e of Array.from(this.callback.values()))e()},this.add=e=>{this.callback.set(e,()=>{this.getWasm().wasmCommand({LocationCall:{callback:e,value:this.get()}})})},this.remove=e=>{this.callback.delete(e)},this.push=e=>{this.get()!==e&&(window.history.pushState(null,"",e),this.trigger())},this.replace=e=>{this.get()!==e&&(window.history.replaceState(null,"",e),this.trigger())},this.getWasm=e,this.callback=new Map,window.addEventListener("popstate",this.trigger)}get(){return window.location.pathname+window.location.search+window.location.hash}}class _{constructor(e){this.callback=(e,t,o)=>{switch(t){case"Add":return void this.locations[e].add(o);case"Remove":return void this.locations[e].remove(o)}},this.set=(e,t,o)=>{switch(t){case"Push":return void this.locations[e].push(o);case"Replace":return void this.locations[e].replace(o)}},this.get=e=>this.locations[e].get(),this.locations={Hash:new N(e),History:new A(e)}}}class M{constructor(){this.get=e=>{for(const t of document.cookie.split(";")){if(""===t)continue;const o=t.trim().split("=");if(2!==o.length){console.warn(`Cookies.get: Incorrect number of cookieChunk => ${o.length} in ${t}`);continue}const n=o[0],s=o[1];if(void 0!==n&&void 0!==s){if(n===e)return decodeURIComponent(s)}else console.warn(`Cookies.get: Broken cookie part => ${t}`)}return""},this.getJson=e=>{let t=this.get(e);if(0!==t.length)try{return JSON.parse(t)}catch(e){console.error("Error deserializing cookie",e)}return null},this.set=(e,t,o)=>{const n=null==t?"":encodeURIComponent(t),s=new Date;s.setTime(s.getTime()+1e3*o);let r="expires="+s.toUTCString();document.cookie=`${e}=${n};${r};path=/; samesite=Strict`},this.setJson=(e,t,o)=>{let n=JSON.stringify(t);this.set(e,n,o)}}}const I=(e,t)=>{const o=t-e+1;return e+Math.floor(Math.random()*o)};class B{constructor(e){this.getWasm=e,this.callbacks=new Map}add(e,t,o,n){const s=e=>"click"===o?this.click(e,n):"submit"===o?this.submit(e,n):"input"===o?this.input(e,n):"change"===o?this.change(e,n):"blur"===o?this.blur(e,n):"mousedown"===o?this.mousedown(e,n):"mouseup"===o?this.mouseup(e,n):"mouseenter"===o?this.mouseenter(e,n):"mouseleave"===o?this.mouseleave(e,n):"keydown"===o||"hook_keydown"===o?this.keydown(e,n):"drop"===o?this.drop(e,n):"load"===o?this.load(e,n):void console.error(`No support for the event ${o}`);if(this.callbacks.has(n))console.error(`There was already a callback added with the callback_id=${n}`);else if(this.callbacks.set(n,s),"hook_keydown"===o)document.addEventListener("keydown",s,!1);else{e.get("callback_add",t).addEventListener(o,s,!1)}}remove(e,t,o,n){const s=this.callbacks.get(n);if(this.callbacks.delete(n),void 0!==s)if("hook_keydown"===o)document.removeEventListener("keydown",s);else{e.get("callback_remove",t).removeEventListener(o,s)}else console.error(`The callback is missing with the id=${n}`)}wasmCallback(e,t){return this.getWasm().wasmCommand({CallbackCall:{callback_id:e,value:t}})}click(e,t){e.preventDefault();let o=this.wasmCallback(t,void 0);null===o||"object"!=typeof o||Array.isArray(o)||("stop_propagation"in o&&!0===o.stop_propagation&&e.stopPropagation(),"prevent_default"in o&&!0===o.prevent_default&&e.preventDefault())}submit(e,t){e.preventDefault(),this.wasmCallback(t,void 0)}input(e,t){const o=e.target;o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement?this.wasmCallback(t,o.value):console.warn("event input ignore",o)}change(e,t){const o=e.target;o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement||o instanceof HTMLSelectElement?this.wasmCallback(t,o.value):console.warn("event input ignore",o)}blur(e,t){this.wasmCallback(t,void 0)}mousedown(e,t){this.wasmCallback(t,void 0)&&e.preventDefault()}mouseup(e,t){this.wasmCallback(t,void 0)&&e.preventDefault()}mouseenter(e,t){this.wasmCallback(t,void 0)}mouseleave(e,t){this.wasmCallback(t,void 0)}drop(e,t){if(e.preventDefault(),e instanceof DragEvent)if(null===e.dataTransfer)console.error("dom -> drop -> dataTransfer null");else{const o=function(e){const t=[];for(let o=0;o drop -> item - undefined");else{const e=n.getAsFile();null===e?console.error(`dom -> drop -> index:${o} -> It's not a file`):t.push(e.arrayBuffer().then(t=>({name:e.name,data:new Uint8Array(t)})))}}return t}(e.dataTransfer.items);o.length?Promise.all(o).then(e=>{const o=[];for(const t of e){const e=Array.from(t.data);o.push([t.name,e])}this.wasmCallback(t,[o])}).catch(e=>{console.error("callback_drop -> promise.all -> ",e)}):console.error("No files to send")}else console.warn("event drop ignore",e)}keydown(e,t){if(e instanceof KeyboardEvent){return void(!0===this.wasmCallback(t,[e.key,e.code,e.altKey,e.ctrlKey,e.shiftKey,e.metaKey])&&(e.preventDefault(),e.stopPropagation()))}console.warn("keydown ignore",e)}load(e,t){e.preventDefault(),this.wasmCallback(t,void 0)}}function U(e,t){"a"===e.tagName.toLocaleLowerCase()&&function(e,t){e.addEventListener("click",o=>{let n=e.getAttribute("href");null!==n&&(n.startsWith("#")||n.startsWith("http://")||n.startsWith("https://")||n.startsWith("//")||(o.preventDefault(),t.set("History","Push",n),window.scrollTo(0,0)))})}(e,t)}class R{constructor(e,t,o){this.depth=-1,this.matched=0,this.nodes=t,this.appLocation=o,this.virtualNodes=this.createVirtualNodes(e)}hydrate(){this.virtualNodes.get(3)&&this.hydrateNode(3,document.body);this.virtualNodes.get(2)&&this.hydrateNode(2,document.head),console.log("Hydration complete,",(100*this.matched/this.virtualNodes.size).toFixed(2)," % vnodes matched.")}hydrateNode(e,t){const o=this.virtualNodes.get(e);if(!o)return;const n=Array.from(t.childNodes);let s=0;this.depth++;let r=!1;for(const e of o.children){const t=this.virtualNodes.get(e);if(t)if(r&&void 0!==t.value)this.matched++;else{r=!1;for(let o=s;o{let o=t.get(e);return o||(o={id:e,children:[]},t.set(e,o)),o};for(const t of e)if("CreateNode"in t){o(t.CreateNode.id).name=t.CreateNode.name.toUpperCase()}else if("CreateText"in t){o(t.CreateText.id).value=t.CreateText.value}else if("InsertBefore"in t){const e=o(t.InsertBefore.parent),n=t.InsertBefore.child,s=t.InsertBefore.ref_id;if(null==s)e.children.push(n);else{const o=e.children.indexOf(s);-1!==o?e.children.splice(o,0,n):(console.warn(`Hydration: ref_id ${s} not found in parent ${t.InsertBefore.parent}`),e.children.push(n))}}else if("SetAttr"in t){const e=o(t.SetAttr.id);e.attributes||(e.attributes=new Map),e.attributes.set(t.SetAttr.name,t.SetAttr.value)}return t}}class ${constructor(){this.data=new Map,this.initNodes=[...this.getRootHead().childNodes,...this.getRootBody().childNodes],this.style=document.createElement("style")}getRootHtml(){return document.documentElement}getRootHead(){return document.head}getRootBody(){return document.body}set(e,t){1===e||2===e||3===e||this.data.set(e,t)}getAnyOption(e){return 1===e?this.getRootHtml():2===e?this.getRootHead():3===e?this.getRootBody():this.data.get(e)}getAny(e,t){const o=this.getAnyOption(t);if(void 0===o)throw Error(`${e} -> item not found=${t}`);return o}get(e,t){const o=this.getAnyOption(t);if(void 0===o)throw new Error(`${e}->get: Item id not found = ${t}`);return o}getNodeElement(e,t){const o=this.get(e,t);if(o instanceof HTMLElement)return o;throw Error(`Expected id=${t} as HTMLElement`)}getNode(e,t){const o=this.get(e,t);if(o instanceof Element)return o;throw Error(`Expected id=${t} as Element`)}getText(e,t){const o=this.get(e,t);if(o instanceof Text)return o;throw Error(`Expected id=${t} as Text`)}getComment(e,t){const o=this.get(e,t);if(o instanceof Comment)return o;throw Error(`Expected id=${t} as Comment`)}delete(e,t){const o=this.getAnyOption(t);if(this.data.delete(t),void 0===o)throw new Error(`${e}->delete: Item id not found = ${t}`);return o}insertCss(e,t){if(null!==e){const o=document.createTextNode(`\n${e} { ${t} }`);this.style.appendChild(o)}else{const e=document.createTextNode(`\n${t}`);this.style.appendChild(e)}}removeInitNodes(){const e=this.initNodes;if(this.initNodes=null,null!==e)for(const t of e)t.remove()}insertBefore(e,t,o){const n=this.get("insert_before",e),s=this.getAny("insert_before child",t);if(null==o)n.insertBefore(s,null);else{const e=this.getAny("insert_before ref",o);n.insertBefore(s,e)}}addStyles(){this.getRootHead().appendChild(this.style)}hasInitNodes(){return null!==this.initNodes}claimNode(e,t){if(this.data.set(e,t),this.initNodes){const e=this.initNodes.indexOf(t);e>-1&&this.initNodes.splice(e,1)}}has(e){return 1===e||2===e||3===e||this.data.has(e)}}const W=new Set(["animate","animateMotion","animateTransform","circle","clipPath","defs","desc","discard","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","hatch","hatchpath","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","svg","switch","symbol","text","textPath","tspan","use","view","svg:a","svg:title","svg:desc","svg:script","svg:style"]);class D{constructor(e,t,o){this.metadata=e,this.update=e=>{this.nodes.hasInitNodes()&&this.metadata.getEnabledHydration()&&((e,t,o)=>{new R(e,t,o).hydrate()})(e,this.nodes,this.appLocation);const t=new Set;for(const o of e){try{this.runCommand(o)}catch(e){console.error("bulk_update - item",e,o)}"SetAttr"in o&&"autofocus"===o.SetAttr.name.toLocaleLowerCase()&&t.add(o.SetAttr.id)}t.size>0&&setTimeout(()=>{for(const e of t){this.nodes.getNodeElement(`set focus ${e}`,e).focus()}},0),this.nodes.removeInitNodes(),this.nodes.addStyles()},this.appLocation=t,this.nodes=new $,this.callbacks=new B(o),document.addEventListener("dragover",e=>{e.preventDefault()})}createNode(e,t){if(1===e||2===e||3===e)return;if(this.nodes.has(e))return;const o=(e=>W.has(e)?document.createElementNS("http://www.w3.org/2000/svg",e.replace("svg:","")):document.createElement(e))(t);this.nodes.set(e,o),U(o,this.appLocation)}setAttr(e,t,o){const n=this.nodes.getNode("set_attribute",e);if(n.setAttribute(t,o),"value"==t){if(n instanceof HTMLInputElement)return void(n.value=o);if(n instanceof HTMLTextAreaElement)return n.value=o,void(n.defaultValue=o)}}removeAttr(e,t){const o=this.nodes.getNode("remove_attribute",e);if(o.removeAttribute(t),"value"==t){if(o instanceof HTMLInputElement)return void(o.value="");if(o instanceof HTMLTextAreaElement)return o.value="",void(o.defaultValue="")}}removeNode(e){if(1===e||2===e||3===e)return;this.nodes.delete("remove_node",e).remove()}createText(e,t){if(this.nodes.has(e))return;const o=document.createTextNode(t);this.nodes.set(e,o)}removeText(e){this.nodes.delete("remove_node",e).remove()}updateText(e,t){this.nodes.getText("set_attribute",e).textContent=t}runCommand(e){if("RemoveNode"in e)this.removeNode(e.RemoveNode.id);else if("InsertBefore"in e)this.nodes.insertBefore(e.InsertBefore.parent,e.InsertBefore.child,null===e.InsertBefore.ref_id?null:e.InsertBefore.ref_id);else if("CreateNode"in e)this.createNode(e.CreateNode.id,e.CreateNode.name);else if("CreateText"in e)this.createText(e.CreateText.id,e.CreateText.value);else if("UpdateText"in e)this.updateText(e.UpdateText.id,e.UpdateText.value);else if("SetAttr"in e)this.setAttr(e.SetAttr.id,e.SetAttr.name,e.SetAttr.value);else if("RemoveAttr"in e)this.removeAttr(e.RemoveAttr.id,e.RemoveAttr.name);else if("RemoveText"in e)this.removeText(e.RemoveText.id);else if("InsertCss"in e)this.nodes.insertCss(e.InsertCss.selector,e.InsertCss.value);else{if("CreateComment"in e){const t=document.createComment(e.CreateComment.value);return void this.nodes.set(e.CreateComment.id,t)}if("RemoveComment"in e){return void this.nodes.delete("remove_comment",e.RemoveComment.id).remove()}if("CallbackAdd"in e)this.callbacks.add(this.nodes,e.CallbackAdd.id,e.CallbackAdd.event_name,e.CallbackAdd.callback_id);else{if(!("CallbackRemove"in e))return(e=>{throw console.error(e),Error("unknown command")})(e);this.callbacks.remove(this.nodes,e.CallbackRemove.id,e.CallbackRemove.event_name,e.CallbackRemove.callback_id)}}}}class O{constructor(e,t){this.metadata=e,this.getWasm=t;const o=new _(t);this.dom=new D(e,o,t),this.websocket=new E(t),this.interval=new S(t),this.location=o,this.cookie=new M}exec(e){const t=e;if("FetchCacheGet"===t)return{data:this.metadata.getFetchCache()};if("IsBrowser"===t)return{value:!0};if("GetDateNow"===t)return{value:Date.now()};if("TimezoneOffset"===t)return{value:(new Date).getTimezoneOffset()};if("HistoryBack"===t)return window.history.back(),null;if("FetchExec"in t)return(async(e,t,o)=>{const n=e();try{const e=await fetch(o.url,{method:o.method,headers:T(o.headers),body:L(o.body)}),s=await x(e);n.wasmCommand({FetchExecResponse:{response:s,callback:t}})}catch(e){console.error("fetch error (1)",e);const o={Err:{message:new String(e).toString()}};n.wasmCommand({FetchExecResponse:{response:o,callback:t}})}})(this.getWasm,t.FetchExec.callback,t.FetchExec.request),null;if("WebsocketRegister"in t)return this.websocket.websocket_register_callback(t.WebsocketRegister.host,t.WebsocketRegister.callback),null;if("WebsocketSendMessage"in t)return this.websocket.websocket_send_message(t.WebsocketSendMessage.callback,t.WebsocketSendMessage.message),null;if("WebsocketUnregister"in t)return this.websocket.websocket_unregister_callback(t.WebsocketUnregister.callback),null;if("TimerSet"in t)return this.interval.timerSet(t.TimerSet.callback,t.TimerSet.duration,t.TimerSet.kind),null;if("TimerClear"in t)return this.interval.timerClear(t.TimerClear.callback),null;if("LocationGet"in t)return{value:this.location.get(t.LocationGet.target)};if("LocationCallback"in t)return this.location.callback(t.LocationCallback.target,t.LocationCallback.mode,t.LocationCallback.callback),null;if("LocationSet"in t)return this.location.set(t.LocationSet.target,t.LocationSet.mode,t.LocationSet.value),null;if("CookieGet"in t)return{value:this.cookie.get(t.CookieGet.name)};if("CookieSet"in t)return this.cookie.set(t.CookieSet.name,t.CookieSet.value,t.CookieSet.expires_in),null;if("CookieJsonGet"in t)return{value:this.cookie.getJson(t.CookieJsonGet.name)};if("CookieJsonSet"in t)return this.cookie.setJson(t.CookieJsonSet.name,t.CookieJsonSet.value,t.CookieJsonSet.expires_in),null;if("GetEnv"in t){const e=t.GetEnv.name;return{value:this.metadata.getEnv(e)}}if("Log"in t)switch(t.Log.kind){case"Info":return console.info(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Debug":return console.debug(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Error":return console.error(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Log":return console.log(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Warn":return console.warn(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null}return"GetRandom"in t?{value:I(t.GetRandom.min,t.GetRandom.max)}:"JsApiCall"in t?this.executeJsApiCall(t.JsApiCall.commands):"DomBulkUpdate"in t?(this.dom.update(t.DomBulkUpdate.list),null):(console.info("exec_command: Arg",t),(()=>{throw Error("assert never")})())}executeJsApiCall(e){let t=null;for(const o of e)if("Root"in o)if("window"===o.Root.name)t=window;else{if("document"!==o.Root.name)return console.error(`Unknown root: ${o.Root.name}`),null;t=document}else if("RootElement"in o){const e=o.RootElement.dom_id,n=this.dom.nodes.getAnyOption(e);if(void 0===n)return console.error(`Element not found: ${e}`),null;t=n}else if("Get"in o){if(null===t)return console.error("Get called on null"),null;t=t[o.Get.property]}else if("Set"in o){if(null===t)return console.error("Set called on null"),null;t[o.Set.property]=o.Set.value,t=void 0}else if("Call"in o){if(null===t)return console.error("Call called on null"),null;t=t[o.Call.method](...o.Call.args)}const o=e=>{if(null==e)return null;if("boolean"==typeof e)return e;if("string"==typeof e)return e;if("number"==typeof e)return e;if(e instanceof Uint8Array)return e;if(Array.isArray(e))return e.map(e=>o(e));if((e=>{if(null===e)return!1;if("object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t})(e)){const t={};for(const n of Object.keys(e))t[n]=o(e[n]);return t}return null};return o(t)}}class F{constructor(){this.get=e=>this.metadata.getAttribute(e)??null,this.getEnabledHydration=()=>"true"!==this.get("data-env-disable-hydration");const e=document.getElementById("v-metadata");if(null===e)throw Error("Expected v-metadata");this.metadata=e,e.remove()}getEnv(e){return this.get(`data-env-${e}`)}getFetchCache(){return this.get("data-fetch-cache")??null}}class H{constructor(e){this.wasm=e}vertigoEntryFunction(e,t){this.wasm.exports.vertigo_entry_function(e,t)}static async create(e){let t=null;const n=()=>{if(null===t)throw Error("Wasm is no initialized");return t},s=new F,r=new O(s,n);return window.$vertigoApi=r,t=await g(e,{mod:{panic_message:e=>{const t=Number(e%2n**32n),o=Number(e>>32n),s=new TextDecoder("utf-8"),r=n().getUint8Memory().subarray(o,o+t),i=s.decode(r);console.error("PANIC",i)},dom_access:e=>{if(0n===e)return console.error("dom_access - null pointer"),0n;const t=new o(()=>n().getUint8Memory(),e),s=m(t);n().exports.vertigo_export_free_block(e);const i=r.exec(s),a=u(i),l=n().exports.vertigo_export_alloc_block(a),c=new o(()=>n().getUint8Memory(),l);return f(i,c),l}}}),new H(t)}}const J=new Set,V=async()=>{document.querySelectorAll("*[data-vertigo-run-wasm]").forEach(e=>{const t=e.getAttribute("data-vertigo-run-wasm");"string"==typeof t?(async e=>{if(J.has(e))return;if(J.size>0)return void console.error("Only one wasm module can be run",{moduleRun:J,wasm:e});J.add(e),console.info(`Wasm module: "${e}" -> start`);const t=await H.create(e);console.info(`Wasm module: "${e}" -> initialized`),t.vertigoEntryFunction(0,11),console.info(`Wasm module: "${e}" -> launched vertigoEntryFunction with version 0.11`)})(t):console.error("Run error",e)})};window.addEventListener("load",V),setTimeout(V,3e3); +"use strict";const e=new TextDecoder("utf-8"),t=new TextEncoder;class o{constructor(e,t){this.getUint8Memory=e,this.pointer=0,this.ptr=Number(t>>32n),this.size=Number(t%2n**32n),this.dataView=new DataView(this.getUint8Memory().buffer,this.ptr,this.size)}getByte(){const e=this.dataView.getUint8(this.pointer);return this.pointer+=1,e}setByte(e){this.dataView.setUint8(this.pointer,e),this.pointer+=1}getU16(){const e=this.dataView.getUint16(this.pointer);return this.pointer+=2,e}setU16(e){this.dataView.setUint16(this.pointer,e),this.pointer+=2}getU32(){const e=this.dataView.getUint32(this.pointer);return this.pointer+=4,e}setU32(e){this.dataView.setUint32(this.pointer,e),this.pointer+=4}getI32(){const e=this.dataView.getInt32(this.pointer);return this.pointer+=4,e}setI32(e){this.dataView.setInt32(this.pointer,e),this.pointer+=4}getU64(){const e=this.dataView.getBigUint64(this.pointer);return this.pointer+=8,e}setU64(e){this.dataView.setBigUint64(this.pointer,e),this.pointer+=8}getI64(){const e=this.dataView.getBigInt64(this.pointer);return this.pointer+=8,e}setI64(e){this.dataView.setBigInt64(this.pointer,e),this.pointer+=8}getF64(){const e=this.dataView.getFloat64(this.pointer);return this.pointer+=8,e}setF64(e){this.dataView.setFloat64(this.pointer,e),this.pointer+=8}getBuffer(){const e=this.getU32(),t=this.getUint8Memory().subarray(this.ptr+this.pointer,this.ptr+this.pointer+e);return this.pointer+=e,t}setBuffer(e){const t=e.length;this.setU32(t);this.getUint8Memory().subarray(this.ptr+this.pointer,this.ptr+this.pointer+t).set(e),this.pointer+=t}getString(){return e.decode(this.getBuffer())}setString(e){const o=t.encode(e);this.setBuffer(o)}getSavedSize(){return this.pointer}}const n=1,s=2,r=3,i=4,a=5,l=6,c=7,d=8,h=9,u=e=>{if(!0===e||!1===e||null==e)return 1;if("string"==typeof e)return 5+(new TextEncoder).encode(e).length;if("number"==typeof e)return 9;if(e instanceof Uint8Array)return 5+e.length;if(Array.isArray(e)){let t=5;for(const o of e)t+=u(o);return t}if("object"==typeof e&&null!==e){let t=3;for(const[o,n]of Object.entries(e))t+=4+(new TextEncoder).encode(o).length,t+=u(n);return t}throw new Error("jsJsonGetSize: Unknown type "+typeof e)},m=e=>{const t=e.getByte();if(t===n)return!0;if(t===s)return!1;if(t===r)return null;if(t!==i){if(t===a)return e.getString();if(t===l)return e.getF64();if(t===c){const t=e.getU32(),o=[];for(let n=0;n{if(!0!==e)if(!1!==e)if(null!==e)if(void 0!==e){if("string"==typeof e)return t.setByte(a),void t.setString(e);if("number"==typeof e)return t.setByte(l),void t.setF64(e);if(e instanceof Uint8Array)return t.setByte(h),void t.setBuffer(e);if(!Array.isArray(e)){if("object"==typeof e&&null!==e){const o=Object.entries(e);t.setByte(d),t.setU16(o.length);for(const[e,n]of o)t.setString(e),f(n,t);return}throw new Error("saveJsJsonToBufferItem: Unknown type "+typeof e)}t.setByte(c),t.setU32(e.length);for(const o of e)f(o,t)}else t.setByte(i);else t.setByte(r);else t.setByte(s);else t.setByte(n)},g=async(e,t)=>{const n=await(async(e,t)=>{if("function"==typeof WebAssembly.instantiateStreaming){const o=fetch(e);try{return await WebAssembly.instantiateStreaming(o,t)}catch(e){console.warn("`WebAssembly.instantiateStreaming` failed. This could happen if your server does not serve wasm with `application/wasm` MIME type, but check the original error too. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e)}}console.info("fetchModule by WebAssembly.instantiate");const o=await fetch(e),n=await o.arrayBuffer();return await WebAssembly.instantiate(n,t)})(e,t);let s=new Uint8Array(1);const r=()=>{if(n.instance.exports.memory instanceof WebAssembly.Memory)return s.buffer!==n.instance.exports.memory.buffer&&(s=new Uint8Array(n.instance.exports.memory.buffer)),s;throw Error("Missing memory")},i=n.instance.exports;return{exports:i,getUint8Memory:r,wasmCommand:e=>{const t=u(e),n=i.vertigo_export_alloc_block(t),s=new o(r,n);f(e,s);let a=i.vertigo_export_wasm_command(n);if(0n===a)return null;const l=new o(r,a),c=m(l);return i.vertigo_export_free_block(a),c}}};class p{constructor(){this.events=new Set}on(e){let t=!0;const o=o=>{t&&e(o)};return this.events.add(o),()=>{t=!1,this.events.delete(o)}}trigger(e){const t=Array.from(this.events.values());for(const o of t)try{o(e)}catch(e){console.error(e)}}get size(){return this.events.size}}class v{constructor(){this.inner=null,this.resolve=e=>{const t=this.inner;this.inner=null,null!==t&&t.resolve(e)},this.reject=e=>{const t=this.inner;this.inner=null,null!==t&&t.reject(e)},this.isFulfilled=()=>null===this.inner;const[e,t]=(()=>{let e=null,t=null;const o=new Promise((o,n)=>{e=o,t=n});if(null===e)throw Error("createPromiseValue - resolve is null");if(null===t)throw Error("createPromiseValue - reject is null");return[{resolve:e,reject:t},o]})();this.inner=e,this.promise=t}}const w=async(e,t)=>{console.info(`${e} wait ${t}ms`),await(async e=>new Promise(t=>{setTimeout(t,e)}))(t),console.info(`${e} go forth`)};class k{constructor(e){this.host=e,this.formatLog=e=>`Socket ${this.host} ==> ${e}`}}class y{constructor(e,t){this.eventMessage=new p,this.close=e,this.send=t}static connect(e,t,o){const n=new v,s=new v,r=new WebSocket(t);let i=!1;console.info(e.formatLog("starting ..."));const a=()=>{i||(console.info(e.formatLog("close")),i=!0,n.resolve(null),s.resolve(),r.close())},l=new y(a,e=>{i||r.send(e)});setTimeout(()=>{!1===n.isFulfilled()&&(console.error(e.formatLog(`timeout (${o}ms)`)),a())},o);return r.addEventListener("open",()=>{console.info(e.formatLog("open")),n.resolve(l)}),r.addEventListener("error",t=>{console.error(e.formatLog("error"),t),a()}),r.addEventListener("close",a),r.addEventListener("message",t=>{if(i)return;const o=t.data;"string"!=typeof o?console.error(e.formatLog("onMessage - expected string"),o):l.eventMessage.trigger(o)}),{socket:n.promise,done:s.promise}}static startSocket(e,t,o,n){let s=!0,r=null;const i=new k(e);return(async()=>{for(;s;){const a=y.connect(i,e,t),l=await a.socket;if(null!==l){if(r=l,n({type:"socket",socket:l}),l.eventMessage.on(e=>{n({type:"message",message:e})}),await a.done,n({type:"close"}),!s)return void console.info(i.formatLog("disconnect (1)"));await w(i.formatLog("reconnect after close"),o)}else await w(i.formatLog("reconnect after error"),o)}console.info(i.formatLog("disconnect (2)"))})().catch(e=>{console.error(e)}),{send:e=>{null===r?console.error("send fail - missing connection",e):r.send(e)},dispose:()=>{s=!1,r?.close()}}}}const b=e=>{try{return JSON.parse(e)}catch{throw console.error("Failed to parse websocket message",e),Error(e)}},C=(e,t,o)=>{e.wasmCommand({Websocket:{callback:t,message:o}})};class E{constructor(e){this.websocket_register_callback=(e,t)=>{const o=this.getWasm();let n=y.startSocket(e,5e3,3e3,e=>{if(!1!==this.controllerList.has(t)){if("socket"===e.type)return this.socket.set(t,e.socket),void C(o,t,"Connected");if("message"!==e.type)return"close"===e.type?(this.socket.delete(t),void C(o,t,"Disconnected")):(e=>{throw console.error(e),Error("unknown message")})(e);C(o,t,{Message:{message:b(e.message)}})}});this.controllerList.set(t,n)},this.websocket_unregister_callback=e=>{const t=this.controllerList.get(e);void 0!==t?(t.dispose(),this.controllerList.delete(e)):console.error("Expected controller")},this.websocket_send_message=(e,t)=>{const o=this.socket.get(e);var n;void 0===o?console.error(`Missing socket connection for callback_id=${e}`):o.send((n=t,JSON.stringify(n)))},this.getWasm=e,this.controllerList=new Map,this.socket=new Map}}const T=e=>{const t={};for(const{k:o,v:n}of e)t[o]=n;return t},L=e=>{if("None"!==e)return JSON.stringify(e.Data.data)},x=async e=>{const t=e.status,o=e.headers.get("Content-Type");try{if(o?.startsWith("text/plain;"))return{Ok:{status:t,response:{Text:await e.text()}}};return{Ok:{status:t,response:{Json:0===(n=await e.text()).length?null:JSON.parse(n)}}}}catch(e){return{Err:{message:String(e)}}}var n};class S{constructor(e){this.timerSet=(e,t,o)=>{switch(o){case"Interval":{const o=setInterval(()=>{this.getWasm().wasmCommand({TimerCall:{callback:e}})},t);this.data.set(e,{kind:"Interval",timerId:o});break}case"Timeout":{const o=setTimeout(()=>{this.getWasm().wasmCommand({TimerCall:{callback:e}})},t);this.data.set(e,{kind:"Timeout",timerId:o});break}}},this.timerClear=e=>{const t=this.data.get(e);if(void 0===t)throw Error("panic");switch(t.kind){case"Interval":clearInterval(t.timerId);break;case"Timeout":clearTimeout(t.timerId)}},this.getWasm=e,this.data=new Map}}class A{constructor(e){this.trigger=()=>{for(const e of Array.from(this.callback.values()))e()},this.add=e=>{this.callback.set(e,()=>{this.getWasm().wasmCommand({LocationCall:{callback:e,value:this.get()}})})},this.remove=e=>{this.callback.delete(e)},this.push=e=>{this.get()!==e&&(location.hash=e,this.trigger())},this.replace=e=>{this.get()!==e&&history.replaceState(null,"",`#${e}`)},this.getWasm=e,this.callback=new Map,window.addEventListener("hashchange",this.trigger)}get(){return decodeURIComponent(location.hash.substr(1))}}class N{constructor(e){this.trigger=()=>{for(const e of Array.from(this.callback.values()))e()},this.add=e=>{this.callback.set(e,()=>{this.getWasm().wasmCommand({LocationCall:{callback:e,value:this.get()}})})},this.remove=e=>{this.callback.delete(e)},this.push=e=>{this.get()!==e&&(window.history.pushState(null,"",e),this.trigger())},this.replace=e=>{this.get()!==e&&(window.history.replaceState(null,"",e),this.trigger())},this.getWasm=e,this.callback=new Map,window.addEventListener("popstate",this.trigger)}get(){return window.location.pathname+window.location.search+window.location.hash}}class _{constructor(e){this.callback=(e,t,o)=>{switch(t){case"Add":return void this.locations[e].add(o);case"Remove":return void this.locations[e].remove(o)}},this.set=(e,t,o)=>{switch(t){case"Push":return void this.locations[e].push(o);case"Replace":return void this.locations[e].replace(o)}},this.get=e=>this.locations[e].get(),this.locations={Hash:new A(e),History:new N(e)}}}class M{constructor(){this.get=e=>{for(const t of document.cookie.split(";")){if(""===t)continue;const o=t.trim().split("=");if(2!==o.length){console.warn(`Cookies.get: Incorrect number of cookieChunk => ${o.length} in ${t}`);continue}const n=o[0],s=o[1];if(void 0!==n&&void 0!==s){if(n===e)return decodeURIComponent(s)}else console.warn(`Cookies.get: Broken cookie part => ${t}`)}return""},this.getJson=e=>{let t=this.get(e);if(0!==t.length)try{return JSON.parse(t)}catch(e){console.error("Error deserializing cookie",e)}return null},this.set=(e,t,o)=>{const n=null==t?"":encodeURIComponent(t),s=new Date;s.setTime(s.getTime()+1e3*o);let r="expires="+s.toUTCString();document.cookie=`${e}=${n};${r};path=/; samesite=Strict`},this.setJson=(e,t,o)=>{let n=JSON.stringify(t);this.set(e,n,o)}}}const I=(e,t)=>{const o=t-e+1;return e+Math.floor(Math.random()*o)};class B{constructor(e){this.getWasm=e,this.callbacks=new Map}add(e,t,o,n){const s=e=>"click"===o?this.click(e,n):"submit"===o?this.submit(e,n):"input"===o?this.input(e,n):"change"===o?this.change(e,n):"blur"===o?this.blur(e,n):"mousedown"===o?this.mousedown(e,n):"mouseup"===o?this.mouseup(e,n):"mouseenter"===o?this.mouseenter(e,n):"mouseleave"===o?this.mouseleave(e,n):"keydown"===o||"hook_keydown"===o?this.keydown(e,n):"drop"===o?this.drop(e,n):"load"===o?this.load(e,n):"change_file"===o?this.changeFile(e,n):void console.error(`No support for the event ${o}`);if(this.callbacks.has(n))console.error(`There was already a callback added with the callback_id=${n}`);else if(this.callbacks.set(n,s),"hook_keydown"===o)document.addEventListener("keydown",s,!1);else{const n=e.get("callback_add",t),r="change_file"===o?"change":o;n.addEventListener(r,s,!1)}}remove(e,t,o,n){const s=this.callbacks.get(n);if(this.callbacks.delete(n),void 0!==s)if("hook_keydown"===o)document.removeEventListener("keydown",s);else{const n="change_file"===o?"change":o;e.get("callback_remove",t).removeEventListener(n,s)}else console.error(`The callback is missing with the id=${n}`)}wasmCallback(e,t){return this.getWasm().wasmCommand({CallbackCall:{callback_id:e,value:t}})}click(e,t){e.preventDefault();let o=this.wasmCallback(t,void 0);null===o||"object"!=typeof o||Array.isArray(o)||("stop_propagation"in o&&!0===o.stop_propagation&&e.stopPropagation(),"prevent_default"in o&&!0===o.prevent_default&&e.preventDefault())}submit(e,t){e.preventDefault(),this.wasmCallback(t,void 0)}input(e,t){const o=e.target;o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement?this.wasmCallback(t,o.value):console.warn("event input ignore",o)}change(e,t){const o=e.target;o instanceof HTMLInputElement||o instanceof HTMLTextAreaElement||o instanceof HTMLSelectElement?this.wasmCallback(t,o.value):console.warn("event input ignore",o)}changeFile(e,t){const o=e.target;if(o instanceof HTMLInputElement&&null!==o.files&&o.files.length>0){const e=[];for(let t=0;t({name:n.name,data:new Uint8Array(e)})))}return e.length>0&&Promise.all(e).then(e=>{const o=[];for(const t of e)o.push([t.name,Array.from(t.data)]);this.wasmCallback(t,[o])}).catch(e=>console.error("changeFile ->",e)),void(o.value="")}console.warn("changeFile: not a file input or no files",o)}blur(e,t){this.wasmCallback(t,void 0)}mousedown(e,t){this.wasmCallback(t,void 0)&&e.preventDefault()}mouseup(e,t){this.wasmCallback(t,void 0)&&e.preventDefault()}mouseenter(e,t){this.wasmCallback(t,void 0)}mouseleave(e,t){this.wasmCallback(t,void 0)}drop(e,t){if(e.preventDefault(),e instanceof DragEvent)if(null===e.dataTransfer)console.error("dom -> drop -> dataTransfer null");else{const o=function(e){const t=[];for(let o=0;o drop -> item - undefined");else{const e=n.getAsFile();null===e?console.error(`dom -> drop -> index:${o} -> It's not a file`):t.push(e.arrayBuffer().then(t=>({name:e.name,data:new Uint8Array(t)})))}}return t}(e.dataTransfer.items);o.length?Promise.all(o).then(e=>{const o=[];for(const t of e){const e=Array.from(t.data);o.push([t.name,e])}this.wasmCallback(t,[o])}).catch(e=>{console.error("callback_drop -> promise.all -> ",e)}):console.error("No files to send")}else console.warn("event drop ignore",e)}keydown(e,t){if(e instanceof KeyboardEvent){return void(!0===this.wasmCallback(t,[e.key,e.code,e.altKey,e.ctrlKey,e.shiftKey,e.metaKey])&&(e.preventDefault(),e.stopPropagation()))}console.warn("keydown ignore",e)}load(e,t){e.preventDefault(),this.wasmCallback(t,void 0)}}function U(e,t){"a"===e.tagName.toLocaleLowerCase()&&function(e,t){e.addEventListener("click",o=>{let n=e.getAttribute("href");null!==n&&(n.startsWith("#")||n.startsWith("http://")||n.startsWith("https://")||n.startsWith("//")||(o.preventDefault(),t.set("History","Push",n),window.scrollTo(0,0)))})}(e,t)}class R{constructor(e,t,o){this.depth=-1,this.matched=0,this.nodes=t,this.appLocation=o,this.virtualNodes=this.createVirtualNodes(e)}hydrate(){this.virtualNodes.get(3)&&this.hydrateNode(3,document.body);this.virtualNodes.get(2)&&this.hydrateNode(2,document.head),console.log("Hydration complete,",(100*this.matched/this.virtualNodes.size).toFixed(2)," % vnodes matched.")}hydrateNode(e,t){const o=this.virtualNodes.get(e);if(!o)return;const n=Array.from(t.childNodes);let s=0;this.depth++;let r=!1;for(const e of o.children){const t=this.virtualNodes.get(e);if(t)if(r&&void 0!==t.value)this.matched++;else{r=!1;for(let o=s;o{let o=t.get(e);return o||(o={id:e,children:[]},t.set(e,o)),o};for(const t of e)if("CreateNode"in t){o(t.CreateNode.id).name=t.CreateNode.name.toUpperCase()}else if("CreateText"in t){o(t.CreateText.id).value=t.CreateText.value}else if("InsertBefore"in t){const e=o(t.InsertBefore.parent),n=t.InsertBefore.child,s=t.InsertBefore.ref_id;if(null==s)e.children.push(n);else{const o=e.children.indexOf(s);-1!==o?e.children.splice(o,0,n):(console.warn(`Hydration: ref_id ${s} not found in parent ${t.InsertBefore.parent}`),e.children.push(n))}}else if("SetAttr"in t){const e=o(t.SetAttr.id);e.attributes||(e.attributes=new Map),e.attributes.set(t.SetAttr.name,t.SetAttr.value)}return t}}class ${constructor(){this.data=new Map,this.initNodes=[...this.getRootHead().childNodes,...this.getRootBody().childNodes],this.style=document.createElement("style")}getRootHtml(){return document.documentElement}getRootHead(){return document.head}getRootBody(){return document.body}set(e,t){1===e||2===e||3===e||this.data.set(e,t)}getAnyOption(e){return 1===e?this.getRootHtml():2===e?this.getRootHead():3===e?this.getRootBody():this.data.get(e)}getAny(e,t){const o=this.getAnyOption(t);if(void 0===o)throw Error(`${e} -> item not found=${t}`);return o}get(e,t){const o=this.getAnyOption(t);if(void 0===o)throw new Error(`${e}->get: Item id not found = ${t}`);return o}getNodeElement(e,t){const o=this.get(e,t);if(o instanceof HTMLElement)return o;throw Error(`Expected id=${t} as HTMLElement`)}getNode(e,t){const o=this.get(e,t);if(o instanceof Element)return o;throw Error(`Expected id=${t} as Element`)}getText(e,t){const o=this.get(e,t);if(o instanceof Text)return o;throw Error(`Expected id=${t} as Text`)}getComment(e,t){const o=this.get(e,t);if(o instanceof Comment)return o;throw Error(`Expected id=${t} as Comment`)}delete(e,t){const o=this.getAnyOption(t);if(this.data.delete(t),void 0===o)throw new Error(`${e}->delete: Item id not found = ${t}`);return o}insertCss(e,t){if(null!==e){const o=document.createTextNode(`\n${e} { ${t} }`);this.style.appendChild(o)}else{const e=document.createTextNode(`\n${t}`);this.style.appendChild(e)}}removeInitNodes(){const e=this.initNodes;if(this.initNodes=null,null!==e)for(const t of e)t.remove()}insertBefore(e,t,o){const n=this.get("insert_before",e),s=this.getAny("insert_before child",t);if(null==o)n.insertBefore(s,null);else{const e=this.getAny("insert_before ref",o);n.insertBefore(s,e)}}addStyles(){this.getRootHead().appendChild(this.style)}hasInitNodes(){return null!==this.initNodes}claimNode(e,t){if(this.data.set(e,t),this.initNodes){const e=this.initNodes.indexOf(t);e>-1&&this.initNodes.splice(e,1)}}has(e){return 1===e||2===e||3===e||this.data.has(e)}}const W=new Set(["animate","animateMotion","animateTransform","circle","clipPath","defs","desc","discard","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","hatch","hatchpath","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","svg","switch","symbol","text","textPath","tspan","use","view","svg:a","svg:title","svg:desc","svg:script","svg:style"]);class F{constructor(e,t,o){this.metadata=e,this.update=e=>{this.nodes.hasInitNodes()&&this.metadata.getEnabledHydration()&&((e,t,o)=>{new R(e,t,o).hydrate()})(e,this.nodes,this.appLocation);const t=new Set;for(const o of e){try{this.runCommand(o)}catch(e){console.error("bulk_update - item",e,o)}"SetAttr"in o&&"autofocus"===o.SetAttr.name.toLocaleLowerCase()&&t.add(o.SetAttr.id)}t.size>0&&setTimeout(()=>{for(const e of t){this.nodes.getNodeElement(`set focus ${e}`,e).focus()}},0),this.nodes.removeInitNodes(),this.nodes.addStyles()},this.appLocation=t,this.nodes=new $,this.callbacks=new B(o),document.addEventListener("dragover",e=>{e.preventDefault()})}createNode(e,t){if(1===e||2===e||3===e)return;if(this.nodes.has(e))return;const o=(e=>W.has(e)?document.createElementNS("http://www.w3.org/2000/svg",e.replace("svg:","")):document.createElement(e))(t);this.nodes.set(e,o),U(o,this.appLocation)}setAttr(e,t,o){const n=this.nodes.getNode("set_attribute",e);if(n.setAttribute(t,o),"value"==t){if(n instanceof HTMLInputElement)return void(n.value=o);if(n instanceof HTMLTextAreaElement)return n.value=o,void(n.defaultValue=o)}}removeAttr(e,t){const o=this.nodes.getNode("remove_attribute",e);if(o.removeAttribute(t),"value"==t){if(o instanceof HTMLInputElement)return void(o.value="");if(o instanceof HTMLTextAreaElement)return o.value="",void(o.defaultValue="")}}removeNode(e){if(1===e||2===e||3===e)return;this.nodes.delete("remove_node",e).remove()}createText(e,t){if(this.nodes.has(e))return;const o=document.createTextNode(t);this.nodes.set(e,o)}removeText(e){this.nodes.delete("remove_node",e).remove()}updateText(e,t){this.nodes.getText("set_attribute",e).textContent=t}runCommand(e){if("RemoveNode"in e)this.removeNode(e.RemoveNode.id);else if("InsertBefore"in e)this.nodes.insertBefore(e.InsertBefore.parent,e.InsertBefore.child,null===e.InsertBefore.ref_id?null:e.InsertBefore.ref_id);else if("CreateNode"in e)this.createNode(e.CreateNode.id,e.CreateNode.name);else if("CreateText"in e)this.createText(e.CreateText.id,e.CreateText.value);else if("UpdateText"in e)this.updateText(e.UpdateText.id,e.UpdateText.value);else if("SetAttr"in e)this.setAttr(e.SetAttr.id,e.SetAttr.name,e.SetAttr.value);else if("RemoveAttr"in e)this.removeAttr(e.RemoveAttr.id,e.RemoveAttr.name);else if("RemoveText"in e)this.removeText(e.RemoveText.id);else if("InsertCss"in e)this.nodes.insertCss(e.InsertCss.selector,e.InsertCss.value);else{if("CreateComment"in e){const t=document.createComment(e.CreateComment.value);return void this.nodes.set(e.CreateComment.id,t)}if("RemoveComment"in e){return void this.nodes.delete("remove_comment",e.RemoveComment.id).remove()}if("CallbackAdd"in e)this.callbacks.add(this.nodes,e.CallbackAdd.id,e.CallbackAdd.event_name,e.CallbackAdd.callback_id);else{if(!("CallbackRemove"in e))return(e=>{throw console.error(e),Error("unknown command")})(e);this.callbacks.remove(this.nodes,e.CallbackRemove.id,e.CallbackRemove.event_name,e.CallbackRemove.callback_id)}}}}class D{constructor(e,t){this.metadata=e,this.getWasm=t;const o=new _(t);this.dom=new F(e,o,t),this.websocket=new E(t),this.interval=new S(t),this.location=o,this.cookie=new M}exec(e){const t=e;if("FetchCacheGet"===t)return{data:this.metadata.getFetchCache()};if("IsBrowser"===t)return{value:!0};if("GetDateNow"===t)return{value:Date.now()};if("TimezoneOffset"===t)return{value:(new Date).getTimezoneOffset()};if("HistoryBack"===t)return window.history.back(),null;if("FetchExec"in t)return(async(e,t,o)=>{const n=e();try{const e=await fetch(o.url,{method:o.method,headers:T(o.headers),body:L(o.body)}),s=await x(e);n.wasmCommand({FetchExecResponse:{response:s,callback:t}})}catch(e){console.error("fetch error (1)",e);const o={Err:{message:new String(e).toString()}};n.wasmCommand({FetchExecResponse:{response:o,callback:t}})}})(this.getWasm,t.FetchExec.callback,t.FetchExec.request),null;if("WebsocketRegister"in t)return this.websocket.websocket_register_callback(t.WebsocketRegister.host,t.WebsocketRegister.callback),null;if("WebsocketSendMessage"in t)return this.websocket.websocket_send_message(t.WebsocketSendMessage.callback,t.WebsocketSendMessage.message),null;if("WebsocketUnregister"in t)return this.websocket.websocket_unregister_callback(t.WebsocketUnregister.callback),null;if("TimerSet"in t)return this.interval.timerSet(t.TimerSet.callback,t.TimerSet.duration,t.TimerSet.kind),null;if("TimerClear"in t)return this.interval.timerClear(t.TimerClear.callback),null;if("LocationGet"in t)return{value:this.location.get(t.LocationGet.target)};if("LocationCallback"in t)return this.location.callback(t.LocationCallback.target,t.LocationCallback.mode,t.LocationCallback.callback),null;if("LocationSet"in t)return this.location.set(t.LocationSet.target,t.LocationSet.mode,t.LocationSet.value),null;if("CookieGet"in t)return{value:this.cookie.get(t.CookieGet.name)};if("CookieSet"in t)return this.cookie.set(t.CookieSet.name,t.CookieSet.value,t.CookieSet.expires_in),null;if("CookieJsonGet"in t)return{value:this.cookie.getJson(t.CookieJsonGet.name)};if("CookieJsonSet"in t)return this.cookie.setJson(t.CookieJsonSet.name,t.CookieJsonSet.value,t.CookieJsonSet.expires_in),null;if("GetEnv"in t){const e=t.GetEnv.name;return{value:this.metadata.getEnv(e)}}if("Log"in t)switch(t.Log.kind){case"Info":return console.info(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Debug":return console.debug(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Error":return console.error(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Log":return console.log(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null;case"Warn":return console.warn(t.Log.message,t.Log.arg2,t.Log.arg3,t.Log.arg4),null}return"GetRandom"in t?{value:I(t.GetRandom.min,t.GetRandom.max)}:"JsApiCall"in t?this.executeJsApiCall(t.JsApiCall.commands):"DomBulkUpdate"in t?(this.dom.update(t.DomBulkUpdate.list),null):(console.info("exec_command: Arg",t),(()=>{throw Error("assert never")})())}executeJsApiCall(e){let t=null;for(const o of e)if("Root"in o)if("window"===o.Root.name)t=window;else{if("document"!==o.Root.name)return console.error(`Unknown root: ${o.Root.name}`),null;t=document}else if("RootElement"in o){const e=o.RootElement.dom_id,n=this.dom.nodes.getAnyOption(e);if(void 0===n)return console.error(`Element not found: ${e}`),null;t=n}else if("Get"in o){if(null===t)return console.error("Get called on null"),null;t=t[o.Get.property]}else if("Set"in o){if(null===t)return console.error("Set called on null"),null;t[o.Set.property]=o.Set.value,t=void 0}else if("Call"in o){if(null===t)return console.error("Call called on null"),null;t=t[o.Call.method](...o.Call.args)}const o=e=>{if(null==e)return null;if("boolean"==typeof e)return e;if("string"==typeof e)return e;if("number"==typeof e)return e;if(e instanceof Uint8Array)return e;if(Array.isArray(e))return e.map(e=>o(e));if((e=>{if(null===e)return!1;if("object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t})(e)){const t={};for(const n of Object.keys(e))t[n]=o(e[n]);return t}return null};return o(t)}}class O{constructor(){this.get=e=>this.metadata.getAttribute(e)??null,this.getEnabledHydration=()=>"true"!==this.get("data-env-disable-hydration");const e=document.getElementById("v-metadata");if(null===e)throw Error("Expected v-metadata");this.metadata=e,e.remove()}getEnv(e){return this.get(`data-env-${e}`)}getFetchCache(){return this.get("data-fetch-cache")??null}}class H{constructor(e){this.wasm=e}vertigoEntryFunction(e,t){this.wasm.exports.vertigo_entry_function(e,t)}static async create(e){let t=null;const n=()=>{if(null===t)throw Error("Wasm is no initialized");return t},s=new O,r=new D(s,n);return window.$vertigoApi=r,t=await g(e,{mod:{panic_message:e=>{const t=Number(e%2n**32n),o=Number(e>>32n),s=new TextDecoder("utf-8"),r=n().getUint8Memory().subarray(o,o+t),i=s.decode(r);console.error("PANIC",i)},dom_access:e=>{if(0n===e)return console.error("dom_access - null pointer"),0n;const t=new o(()=>n().getUint8Memory(),e),s=m(t);n().exports.vertigo_export_free_block(e);const i=r.exec(s),a=u(i),l=n().exports.vertigo_export_alloc_block(a),c=new o(()=>n().getUint8Memory(),l);return f(i,c),l}}}),new H(t)}}const J=new Set,V=async()=>{document.querySelectorAll("*[data-vertigo-run-wasm]").forEach(e=>{const t=e.getAttribute("data-vertigo-run-wasm");"string"==typeof t?(async e=>{if(J.has(e))return;if(J.size>0)return void console.error("Only one wasm module can be run",{moduleRun:J,wasm:e});J.add(e),console.info(`Wasm module: "${e}" -> start`);const t=await H.create(e);console.info(`Wasm module: "${e}" -> initialized`),t.vertigoEntryFunction(0,11),console.info(`Wasm module: "${e}" -> launched vertigoEntryFunction with version 0.11`)})(t):console.error("Run error",e)})};window.addEventListener("load",V),setTimeout(V,3e3); //# sourceMappingURL=wasm_run.js.map diff --git a/crates/vertigo/src/driver_module/wasm_run.js.map b/crates/vertigo/src/driver_module/wasm_run.js.map index 33588424..19289d60 100644 --- a/crates/vertigo/src/driver_module/wasm_run.js.map +++ b/crates/vertigo/src/driver_module/wasm_run.js.map @@ -1 +1 @@ -{"version":3,"file":"wasm_run.js","sources":["src_js/buffer_cursor.ts","src_js/jsjson.ts","src_js/wasm_init.ts","src_js/api/websocket/event_emiter.ts","src_js/api/websocket/promise.ts","src_js/api/websocket/connection.ts","src_js/api/websocket/websocket.ts","src_js/assert_never.ts","src_js/api/command/fetchExec.ts","src_js/api/command/interval.ts","src_js/api/location/hashrouter.ts","src_js/api/location/historyLocation.ts","src_js/api/location/AppLocation.ts","src_js/api/command/cookies.ts","src_js/api/command/getRandom.ts","src_js/api/command/dom/callbackManager.ts","src_js/api/command/dom/dataTransfer.ts","src_js/api/command/dom/injects.ts","src_js/api/command/dom/hydration.ts","src_js/api/command/dom/map_nodes.ts","src_js/api/command/dom/dom.ts","src_js/api/api.ts","src_js/api/command/fetchCacheGet.ts","src_js/api/metadata.ts","src_js/wasm_module.ts","src_js/index.ts"],"sourcesContent":["///https://javascript.info/arraybuffer-binary-arrays#dataview\n\nconst decoder = new TextDecoder(\"utf-8\");\nconst encoder = new TextEncoder();\n\nexport class BufferCursor {\n private dataView: DataView;\n private pointer: number = 0;\n private ptr: number;\n private size: number;\n\n constructor(\n private getUint8Memory: () => Uint8Array,\n long_ptr: bigint,\n ) {\n this.ptr = Number(long_ptr >> 32n);\n this.size = Number(long_ptr % (2n ** 32n));\n\n this.dataView = new DataView(\n this.getUint8Memory().buffer,\n this.ptr,\n this.size\n );\n }\n\n public getByte(): number {\n const value = this.dataView.getUint8(this.pointer);\n this.pointer += 1;\n return value;\n }\n\n public setByte(byte: number) {\n this.dataView.setUint8(this.pointer, byte);\n this.pointer += 1;\n }\n\n public getU16(): number {\n const value = this.dataView.getUint16(this.pointer);\n this.pointer += 2;\n return value;\n }\n\n public setU16(value: number) {\n this.dataView.setUint16(this.pointer, value);\n this.pointer += 2;\n }\n\n public getU32(): number {\n const value = this.dataView.getUint32(this.pointer);\n this.pointer += 4;\n return value;\n }\n\n public setU32(value: number) {\n this.dataView.setUint32(this.pointer, value);\n this.pointer += 4;\n }\n\n public getI32(): number {\n const value = this.dataView.getInt32(this.pointer);\n this.pointer += 4;\n return value;\n }\n\n public setI32(value: number) {\n this.dataView.setInt32(this.pointer, value);\n this.pointer += 4;\n }\n\n public getU64(): bigint {\n const value = this.dataView.getBigUint64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setU64(value: bigint) {\n this.dataView.setBigUint64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getI64(): bigint {\n const value = this.dataView.getBigInt64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setI64(value: bigint) {\n this.dataView.setBigInt64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getF64(): number {\n const value = this.dataView.getFloat64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setF64(value: number) {\n this.dataView.setFloat64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getBuffer(): Uint8Array {\n const size = this.getU32();\n const result = this\n .getUint8Memory()\n .subarray(\n this.ptr + this.pointer,\n this.ptr + this.pointer + size\n );\n\n this.pointer += size;\n return result;\n }\n\n public setBuffer(buffer: Uint8Array) {\n const size = buffer.length;\n this.setU32(size);\n\n const sub_buffer = this\n .getUint8Memory()\n .subarray(\n this.ptr + this.pointer,\n this.ptr + this.pointer + size\n );\n\n sub_buffer.set(buffer);\n\n this.pointer += size;\n }\n\n public getString(): string {\n return decoder.decode(this.getBuffer());\n }\n\n public setString(value: string) {\n const buffer = encoder.encode(value);\n this.setBuffer(buffer);\n }\n\n public getSavedSize(): number {\n return this.pointer;\n }\n}\n\nexport const getStringSize = (value: string): number => {\n return new TextEncoder().encode(value).length;\n};\n\n","import { BufferCursor } from \"./buffer_cursor\";\n\nconst JsJsonConst = {\n True: 1,\n False: 2,\n Null: 3,\n Undefined: 4,\n String: 5,\n Number: 6,\n List: 7,\n Object: 8,\n Vec: 9,\n} as const;\n\nexport type JsJsonType = boolean | null | undefined | string | number | Uint8Array | Array | { [key: string]: JsJsonType };\n\nexport const jsJsonGetSize = (value: JsJsonType): number => {\n if (value === true || value === false || value === null || value === undefined) {\n return 1;\n }\n\n if (typeof value === 'string') {\n return 1 + 4 + new TextEncoder().encode(value).length;\n }\n\n if (typeof value === 'number') {\n return 1 + 8;\n }\n\n if (value instanceof Uint8Array) {\n return 1 + 4 + value.length;\n }\n\n if (Array.isArray(value)) {\n let sum = 1 + 4;\n for (const item of value) {\n sum += jsJsonGetSize(item);\n }\n return sum;\n }\n\n if (typeof value === 'object' && value !== null) {\n let sum = 1 + 2;\n for (const [key, propertyValue] of Object.entries(value)) {\n sum += 4 + new TextEncoder().encode(key).length;\n sum += jsJsonGetSize(propertyValue);\n }\n return sum;\n }\n\n throw new Error(`jsJsonGetSize: Unknown type ${typeof value}`);\n};\n\nexport const jsJsonDecodeItem = (buffer: BufferCursor): JsJsonType => {\n const typeId = buffer.getByte();\n\n if (typeId === JsJsonConst.True) {\n return true;\n }\n\n if (typeId === JsJsonConst.False) {\n return false;\n }\n\n if (typeId === JsJsonConst.Null) {\n return null;\n }\n\n if (typeId === JsJsonConst.Undefined) {\n return undefined;\n }\n\n if (typeId === JsJsonConst.String) {\n return buffer.getString();\n }\n\n if (typeId === JsJsonConst.Number) {\n return buffer.getF64();\n }\n\n if (typeId === JsJsonConst.List) {\n const count = buffer.getU32();\n const list: Array = [];\n\n for (let i = 0; i < count; i++) {\n list.push(jsJsonDecodeItem(buffer));\n }\n\n return list;\n }\n\n if (typeId === JsJsonConst.Object) {\n const count = buffer.getU16();\n const obj: { [key: string]: JsJsonType } = {};\n\n for (let i = 0; i < count; i++) {\n const key = buffer.getString();\n const value = jsJsonDecodeItem(buffer);\n obj[key] = value;\n }\n\n return obj;\n }\n\n if (typeId === JsJsonConst.Vec) {\n return buffer.getBuffer();\n }\n\n throw new Error(`jsJsonDecodeItem: Unknown type id ${typeId}`);\n};\n\nexport const saveJsJsonToBufferItem = (value: JsJsonType, buffer: BufferCursor): void => {\n if (value === true) {\n buffer.setByte(JsJsonConst.True);\n return;\n }\n\n if (value === false) {\n buffer.setByte(JsJsonConst.False);\n return;\n }\n\n if (value === null) {\n buffer.setByte(JsJsonConst.Null);\n return;\n }\n\n if (value === undefined) {\n buffer.setByte(JsJsonConst.Undefined);\n return;\n }\n\n if (typeof value === 'string') {\n buffer.setByte(JsJsonConst.String);\n buffer.setString(value);\n return;\n }\n\n if (typeof value === 'number') {\n buffer.setByte(JsJsonConst.Number);\n buffer.setF64(value);\n return;\n }\n\n if (value instanceof Uint8Array) {\n buffer.setByte(JsJsonConst.Vec);\n buffer.setBuffer(value);\n return;\n }\n\n if (Array.isArray(value)) {\n buffer.setByte(JsJsonConst.List);\n buffer.setU32(value.length);\n\n for (const item of value) {\n saveJsJsonToBufferItem(item, buffer);\n }\n\n return;\n }\n\n if (typeof value === 'object' && value !== null) {\n const entries = Object.entries(value);\n\n buffer.setByte(JsJsonConst.Object);\n buffer.setU16(entries.length);\n\n for (const [key, propertyValue] of entries) {\n buffer.setString(key);\n saveJsJsonToBufferItem(propertyValue, buffer);\n }\n\n return;\n }\n\n throw new Error(`saveJsJsonToBufferItem: Unknown type ${typeof value}`);\n};\n","import { BufferCursor } from './buffer_cursor';\nimport { jsJsonGetSize, jsJsonDecodeItem, saveJsJsonToBufferItem, JsJsonType } from './jsjson';\n\nexport interface BaseExportType {\n vertigo_export_alloc_block: (size: number) => bigint,\n vertigo_export_free_block: (pointer: bigint) => void,\n vertigo_export_wasm_command: (value_ptr: bigint) => bigint,\n};\n\nexport interface ModuleControllerType {\n exports: ExportType,\n getUint8Memory: () => Uint8Array,\n wasmCommand: (params: JsJsonType) => JsJsonType,\n}\n\nconst fetchModule = async (wasmBinPath: string, imports: Record): Promise => {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n const stream = fetch(wasmBinPath);\n try {\n const module = await WebAssembly.instantiateStreaming(stream, imports);\n return module;\n } catch (err) {\n console.warn(\"`WebAssembly.instantiateStreaming` failed. This could happen if your server does not serve wasm with `application/wasm` MIME type, but check the original error too. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", err);\n }\n }\n\n console.info('fetchModule by WebAssembly.instantiate');\n\n const resp = await fetch(wasmBinPath);\n const binary = await resp.arrayBuffer();\n const module_instance = await WebAssembly.instantiate(binary, imports);\n return module_instance;\n};\n\nexport const wasmInit = async , ExportType extends BaseExportType>(\n wasmBinPath: string,\n imports: { mod: ImportType },\n): Promise> => {\n const module_instance = await fetchModule(wasmBinPath, imports);\n\n let cacheGetUint8Memory: Uint8Array = new Uint8Array(1);\n\n const getUint8Memory = () => {\n if (module_instance.instance.exports.memory instanceof WebAssembly.Memory) {\n if (cacheGetUint8Memory.buffer !== module_instance.instance.exports.memory.buffer) {\n cacheGetUint8Memory = new Uint8Array(module_instance.instance.exports.memory.buffer);\n }\n return cacheGetUint8Memory;\n } else {\n throw Error('Missing memory');\n }\n };\n\n //@ts-expect-error\n const exports: ExportType = module_instance.instance.exports;\n\n const wasmCommand = (value: JsJsonType): JsJsonType => {\n // Serialize JsJson\n const size = jsJsonGetSize(value);\n const long_ptr = exports.vertigo_export_alloc_block(size);\n const buffer = new BufferCursor(getUint8Memory, long_ptr);\n saveJsJsonToBufferItem(value, buffer);\n\n let result_long_ptr = exports.vertigo_export_wasm_command(long_ptr);\n\n // Decode JsJson\n if (result_long_ptr === 0n) {\n return null;\n }\n const resultBuffer = new BufferCursor(getUint8Memory, result_long_ptr);\n const result = jsJsonDecodeItem(resultBuffer);\n exports.vertigo_export_free_block(result_long_ptr);\n\n return result;\n };\n\n\n return {\n exports,\n getUint8Memory,\n wasmCommand: wasmCommand,\n };\n};\n","export class EventEmitter {\n private events: Set<(param: T) => void>;\n\n constructor() {\n this.events = new Set()\n }\n\n on(callback: (param: T) => void) {\n let isActive = true;\n\n const onExec = (param: T) => {\n if (isActive) {\n callback(param);\n }\n };\n\n this.events.add(onExec);\n\n return () => {\n isActive = false;\n this.events.delete(onExec);\n };\n }\n\n trigger(param: T) {\n const eventsCopy = Array.from(this.events.values())\n\n for (const itemCallbackToRun of eventsCopy) {\n try {\n itemCallbackToRun(param);\n } catch (err) {\n console.error(err);\n }\n }\n }\n\n get size(): number {\n return this.events.size;\n }\n}\n","type ResolveFn = (data: T) => void;\ntype RejectFn = (err: unknown) => void;\n\ninterface PromiseResolveReject {\n readonly resolve: (value: T) => void,\n readonly reject: (err: unknown) => void,\n};\n\nconst createPromiseValue = (): [PromiseResolveReject, Promise] => {\n let resolve: ResolveFn | null = null;\n let reject: RejectFn | null = null;\n\n const promise: Promise = new Promise((localResolve: ResolveFn, localReject: RejectFn) => {\n resolve = localResolve;\n reject = localReject;\n });\n\n if (resolve === null) {\n throw Error('createPromiseValue - resolve is null');\n }\n\n if (reject === null) {\n throw Error('createPromiseValue - reject is null');\n }\n\n const promiseValue = {\n resolve,\n reject,\n };\n\n return [promiseValue, promise];\n};\n\nexport class PromiseBoxRace {\n private inner: PromiseResolveReject | null = null;\n readonly promise: Promise;\n\n constructor() {\n const [promiseResolveReject, promise] = createPromiseValue();\n\n this.inner = promiseResolveReject;\n this.promise = promise;\n }\n\n resolve = (value: T) => {\n const promiseResolveReject = this.inner;\n this.inner = null;\n\n if (promiseResolveReject === null) {\n return;\n }\n\n promiseResolveReject.resolve(value);\n }\n\n reject = (err?: unknown) => {\n const promiseResolveReject = this.inner;\n this.inner = null;\n\n if (promiseResolveReject === null) {\n return;\n }\n\n promiseResolveReject.reject(err);\n }\n\n isFulfilled = (): boolean => {\n return this.inner === null;\n }\n}\n","import { EventEmitter } from \"./event_emiter\";\nimport { PromiseBoxRace } from \"./promise\";\n\nconst timeout = async (timeout: number): Promise => {\n return new Promise((resolve: (data: void) => void) => {\n setTimeout(resolve, timeout);\n });\n};\n\n\nconst reconnectDelay = async (label: string, timeout_retry: number): Promise => {\n console.info(`${label} wait ${timeout_retry}ms`);\n await timeout(timeout_retry);\n console.info(`${label} go forth`);\n};\n\nexport type SocketEventType = {\n type: 'message',\n message: string,\n} | {\n type: 'socket',\n socket: SocketConnection\n} | {\n type: 'close',\n};\n\nexport type OnMessageType = (message: SocketEventType) => void;\nexport type UnsubscribeFnType = () => void;\n\ninterface OpenSocketResult {\n socket: Promise,\n done: Promise,\n}\n\nexport interface SocketConnectionController {\n send: (message: string) => void,\n dispose: UnsubscribeFnType\n}\n\nclass LogContext {\n public constructor(private host: string) {}\n public formatLog = (message: string): string => `Socket ${this.host} ==> ${message}`;\n}\nexport class SocketConnection {\n private readonly eventMessage: EventEmitter;\n public readonly close: () => void;\n public readonly send: (message: string) => void;\n\n private constructor(\n close: () => void,\n send: (message: string) => void,\n ) {\n this.eventMessage = new EventEmitter();\n this.close = close;\n this.send = send;\n }\n\n private static connect(\n log: LogContext,\n host: string,\n timeout: number,\n ): OpenSocketResult {\n const result = new PromiseBoxRace();\n const done = new PromiseBoxRace();\n const socket = new WebSocket(host);\n let isClose: boolean = false;\n\n console.info(log.formatLog('starting ...'));\n\n const closeSocket = (): void => {\n if (isClose) {\n return;\n }\n\n console.info(log.formatLog('close'));\n\n isClose = true;\n result.resolve(null);\n done.resolve();\n socket.close();\n };\n\n\n const socketConnection = new SocketConnection(\n closeSocket,\n (message: string) => {\n if (isClose) {\n return;\n }\n socket.send(message);\n }\n );\n\n setTimeout(() => {\n if (result.isFulfilled() === false) {\n console.error(log.formatLog(`timeout (${timeout}ms)`));\n closeSocket();\n }\n }, timeout);\n\n const onOpen = (): void => {\n console.info(log.formatLog('open'));\n result.resolve(socketConnection);\n };\n\n const onError = (error: Event): void => {\n console.error(log.formatLog('error'), error);\n closeSocket();\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (isClose) {\n return;\n }\n\n const dataRaw = event.data;\n\n if (typeof dataRaw === 'string') {\n socketConnection.eventMessage.trigger(dataRaw);\n return;\n }\n\n console.error(log.formatLog('onMessage - expected string'), dataRaw);\n };\n\n socket.addEventListener('open', onOpen);\n socket.addEventListener('error', onError);\n socket.addEventListener('close', closeSocket);\n socket.addEventListener('message', onMessage);\n\n return {\n socket: result.promise,\n done: done.promise\n };\n }\n\n public static startSocket(\n host: string,\n timeout_connection: number,\n timeout_retry: number,\n onMessage: OnMessageType,\n ): SocketConnectionController {\n let isConnect: boolean = true;\n let socketConnection: SocketConnection | null = null;\n\n const log = new LogContext(host);\n\n (async (): Promise => {\n while (isConnect) {\n const openSocketResult = SocketConnection.connect(log, host, timeout_connection);\n\n const socket = await openSocketResult.socket;\n\n if (socket === null) {\n await reconnectDelay(log.formatLog('reconnect after error'), timeout_retry);\n continue;\n }\n\n socketConnection = socket;\n onMessage({\n type: 'socket',\n socket\n });\n\n socket.eventMessage.on(message => {\n onMessage({\n type: 'message',\n message\n });\n });\n\n await openSocketResult.done;\n\n onMessage({\n type: 'close'\n });\n\n if (!isConnect) {\n console.info(log.formatLog('disconnect (1)'));\n return;\n }\n\n await reconnectDelay(log.formatLog('reconnect after close'), timeout_retry);\n }\n\n console.info(log.formatLog('disconnect (2)'));\n })().catch((error) => {\n console.error(error);\n });\n\n return {\n send: (message: string): void => {\n if (socketConnection === null) {\n console.error('send fail - missing connection', message);\n } else {\n socketConnection.send(message);\n }\n },\n dispose: (): void => {\n isConnect = false;\n socketConnection?.close();\n }\n };\n }\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { SocketConnection, SocketConnectionController } from \"./connection\";\n\nconst wireStringToJsJson = (raw: string): JsJsonType => {\n try {\n return JSON.parse(raw) as JsJsonType;\n } catch {\n console.error('Failed to parse websocket message', raw);\n throw Error(raw);\n }\n};\n\nconst jsJsonToWebSocketWire = (value: JsJsonType): string => {\n return JSON.stringify(value);\n};\n\nconst assertNeverMessage = (data: never): never => {\n console.error(data);\n throw Error('unknown message');\n};\n\ntype CommandType = 'Connected' | 'Disconnected' | {\n 'Message': {\n message: JsJsonType,\n }\n}\nconst wasmCallback = (wasm: ModuleControllerType, callbackId: CallbackId, command: CommandType) => {\n wasm.wasmCommand({\n 'Websocket': {\n callback: callbackId,\n message: command,\n }\n })\n};\n\n\nexport class DriverWebsocket {\n private getWasm: () => ModuleControllerType;\n private readonly controllerList: Map;\n private readonly socket: Map;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.controllerList = new Map();\n this.socket = new Map();\n }\n\n public websocket_register_callback = (\n host: string,\n callback_id: CallbackId,\n ) => {\n const wasm = this.getWasm();\n\n let controller = SocketConnection.startSocket(\n host,\n 5000, //timeout connection\n 3000, //timeout reconnection\n (message) => {\n\n if (this.controllerList.has(callback_id) === false) {\n return;\n }\n\n if (message.type === 'socket') {\n this.socket.set(callback_id, message.socket);\n wasmCallback(wasm, callback_id, 'Connected');\n return;\n }\n\n if (message.type === 'message') {\n wasmCallback(wasm, callback_id, {\n 'Message': {\n message: wireStringToJsJson(message.message)\n }\n });\n return;\n }\n\n if (message.type === 'close') {\n this.socket.delete(callback_id);\n wasmCallback(wasm, callback_id, 'Disconnected');\n return;\n }\n\n return assertNeverMessage(message);\n }\n );\n\n this.controllerList.set(callback_id, controller);\n }\n\n public websocket_unregister_callback = (callback_id: CallbackId) => {\n const controller = this.controllerList.get(callback_id);\n\n if (controller === undefined) {\n console.error('Expected controller');\n return;\n }\n\n controller.dispose();\n this.controllerList.delete(callback_id);\n }\n\n public websocket_send_message = (\n callback_id: CallbackId,\n message: JsJsonType,\n ) => {\n const socket = this.socket.get(callback_id);\n\n if (socket === undefined) {\n console.error(`Missing socket connection for callback_id=${callback_id}`);\n } else {\n socket.send(jsJsonToWebSocketWire(message));\n }\n }\n}\n","\nexport const assertNever = (_value: never) => {\n throw Error(\"assert never\");\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\n\nexport interface FetchRequestType {\n method: string,\n url: string,\n headers: Array<{ k: string, v: string }>,\n body: 'None' | {\n Data: {\n data: JsJsonType\n }\n }\n}\n\ntype FetchResponseType = {\n Ok: {\n status: number,\n response: {\n Text: string\n } | {\n Json: JsJsonType,\n }\n }\n} | {\n Err: {\n message: string,\n }\n};\n\nconst getHeaders = (headers: Array<{ k: string, v: string }>): Record => {\n const result: Record = {};\n\n for (const { k, v } of headers) {\n result[k] = v;\n }\n\n return result;\n};\n\nconst getBodyString = (body: FetchRequestType['body']): string | undefined => {\n if (body === 'None') {\n return undefined;\n }\n\n return JSON.stringify(body.Data.data);\n};\n\n// 204/205 carry no body, and any other response with an empty body\n// would crash response.json(). Treat both as Json: null so the caller\n// sees a successful response with the real status code.\nexport const parseJsonBody = (bodyText: string): JsJsonType | null =>\n bodyText.length === 0 ? null : JSON.parse(bodyText);\n\nconst processResponse = async (response: Response): Promise => {\n const status = response.status;\n const contentType = response.headers.get(\"Content-Type\");\n\n try {\n if (contentType?.startsWith('text/plain;')) {\n return {\n Ok: {\n status,\n response: {\n Text: await response.text(),\n }\n }\n }\n }\n\n const json = parseJsonBody(await response.text());\n\n return {\n Ok: {\n status,\n response: {\n Json: json\n }\n }\n };\n } catch (error) {\n return {\n Err: {\n message: String(error),\n }\n };\n }\n};\n\n\nexport const fetchExec = async (\n getWasm: () => ModuleControllerType,\n callback_id: CallbackId,\n request: FetchRequestType\n): Promise => {\n const wasm = getWasm();\n\n try {\n const response = await fetch(request.url, {\n method: request.method,\n headers: getHeaders(request.headers),\n body: getBodyString(request.body),\n });\n\n const response2 = await processResponse(response);\n\n wasm.wasmCommand({\n 'FetchExecResponse': {\n response: response2,\n callback: callback_id,\n }\n });\n\n } catch (err) {\n console.error('fetch error (1)', err);\n const responseMessage = new String(err).toString();\n\n const responseToWasm: FetchResponseType = {\n 'Err': {\n message: responseMessage\n }\n };\n\n wasm.wasmCommand({\n 'FetchExecResponse': {\n response: responseToWasm,\n callback: callback_id,\n }\n });\n }\n};\n\n\n","import { CallbackId } from \"../types\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\n\ntype TimerResourceId = ReturnType;\n\ninterface TimerId {\n kind: 'Interval' | 'Timeout',\n timerId: TimerResourceId,\n}\n\nexport class Interval {\n private readonly getWasm: () => ModuleControllerType;\n private readonly data: Map;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.data = new Map();\n }\n\n timerSet = (callback: CallbackId, duration: number, kind: 'Interval' | 'Timeout') => {\n switch (kind) {\n case 'Interval': {\n const timerId = setInterval(() => {\n this.getWasm().wasmCommand({\n 'TimerCall': {\n callback,\n },\n })\n }, duration);\n\n this.data.set(callback, {\n kind: 'Interval',\n timerId,\n });\n break;\n }\n case 'Timeout': {\n const timerId = setTimeout(() => {\n this.getWasm().wasmCommand({\n 'TimerCall': {\n callback,\n },\n })\n }, duration);\n\n this.data.set(callback, {\n kind: 'Timeout',\n timerId,\n });\n break;\n }\n }\n }\n\n timerClear = (callback: CallbackId) => {\n const timerResource = this.data.get(callback);\n\n if (timerResource === undefined) {\n throw Error('panic');\n }\n\n switch (timerResource.kind) {\n case 'Interval': {\n clearInterval(timerResource.timerId);\n break;\n }\n case 'Timeout': {\n clearTimeout(timerResource.timerId);\n break;\n }\n }\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { LocationCommonType } from \"./types\";\n\nexport class HashRouter implements LocationCommonType {\n private getWasm: () => ModuleControllerType;\n private callback: Map void>;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callback = new Map();\n\n window.addEventListener(\"hashchange\", this.trigger);\n }\n\n private trigger = () => {\n for (const callback of Array.from(this.callback.values())) {\n callback();\n }\n }\n\n public add = (callback_id: CallbackId) => {\n this.callback.set(callback_id, () => {\n this.getWasm().wasmCommand({\n LocationCall: {\n callback: callback_id,\n value: this.get(),\n }\n });\n });\n }\n\n public remove = (callback_id: CallbackId) => {\n this.callback.delete(callback_id);\n }\n\n public push = (new_hash: string) => {\n if (this.get() === new_hash) {\n return;\n }\n\n location.hash = new_hash;\n this.trigger();\n }\n\n public replace = (new_hash: string) => {\n if (this.get() === new_hash) {\n return;\n }\n\n history.replaceState(null, '', `#${new_hash}`);\n }\n\n public get(): string {\n return decodeURIComponent(location.hash.substr(1));\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { LocationCommonType } from \"./types\";\n\nexport class HistoryLocation implements LocationCommonType {\n private getWasm: () => ModuleControllerType;\n private callback: Map void>;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callback = new Map();\n\n window.addEventListener(\"popstate\", this.trigger);\n }\n\n private trigger = () => {\n for (const callback of Array.from(this.callback.values())) {\n callback();\n }\n }\n\n public add = (callback_id: CallbackId) => {\n this.callback.set(callback_id, () => {\n this.getWasm().wasmCommand({\n LocationCall: {\n callback: callback_id,\n value: this.get(),\n }\n });\n });\n }\n\n public remove = (callback_id: CallbackId) => {\n this.callback.delete(callback_id);\n }\n\n public push = (url: string) => {\n if (this.get() === url) {\n return;\n }\n\n window.history.pushState(null, '', url);\n this.trigger();\n }\n\n public replace = (url: string) => {\n if (this.get() === url) {\n return;\n }\n\n window.history.replaceState(null, '', url);\n this.trigger();\n }\n\n public get(): string {\n return window.location.pathname + window.location.search + window.location.hash;\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { HashRouter } from \"./hashrouter\";\nimport { HistoryLocation } from \"./historyLocation\";\nimport { LocationCommonType } from \"./types\";\n\ntype LocationTarget = 'Hash' | 'History';\n\nexport class AppLocation {\n private readonly locations: Record;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.locations = {\n Hash: new HashRouter(getWasm),\n History: new HistoryLocation(getWasm),\n };\n }\n\n callback = (target: LocationTarget, mode: 'Add' | 'Remove', callbackId: CallbackId) => {\n switch (mode) {\n case 'Add': {\n this.locations[target].add(callbackId);\n return;\n }\n case 'Remove': {\n this.locations[target].remove(callbackId);\n return;\n }\n }\n }\n\n set = (target: LocationTarget, mode: 'Push' | 'Replace', newValue: string) => {\n switch (mode) {\n case 'Push': {\n this.locations[target].push(newValue);\n return;\n }\n case 'Replace': {\n this.locations[target].replace(newValue);\n return;\n }\n }\n }\n\n get = (target: LocationTarget): string => {\n return this.locations[target].get();\n }\n}","import { JsJsonType } from \"../../jsjson\";\n\nexport class Cookies {\n public get = (cname: string): string => {\n for (const cookie of document.cookie.split(';')) {\n if (cookie === \"\") continue;\n\n const cookieChunk = cookie.trim().split('=');\n\n if (cookieChunk.length !== 2) {\n console.warn(`Cookies.get: Incorrect number of cookieChunk => ${cookieChunk.length} in ${cookie}`);\n continue;\n }\n\n const cookieName = cookieChunk[0];\n const cookieValue = cookieChunk[1];\n\n if (cookieName === undefined || cookieValue === undefined) {\n console.warn(`Cookies.get: Broken cookie part => ${cookie}`);\n continue;\n }\n\n if (cookieName === cname) {\n return decodeURIComponent(cookieValue);\n }\n }\n\n return '';\n }\n\n public getJson = (cname: string): JsJsonType => {\n let cvalue_str = this.get(cname);\n\n if (cvalue_str.length !== 0) {\n try {\n let cookie_value = JSON.parse(cvalue_str);\n return cookie_value;\n } catch (e) {\n console.error!(\"Error deserializing cookie\", e);\n }\n }\n return null\n }\n\n public set = (\n cname: string,\n cvalue: string,\n expires_in: number,\n ) => {\n const cvalueEncoded = cvalue == null ? \"\" : encodeURIComponent(cvalue);\n\n const d = new Date();\n d.setTime(d.getTime() + (expires_in * 1000));\n let expires = \"expires=\" + d.toUTCString();\n\n document.cookie = `${cname}=${cvalueEncoded};${expires};path=/; samesite=Strict`;\n }\n\n public setJson = (\n cname: string,\n cvalue: JsJsonType,\n expires_in: number,\n ) => {\n let cvalue_str = JSON.stringify(cvalue);\n\n this.set(cname, cvalue_str, expires_in);\n }\n}\n","export const getRandom = (min: number, max: number): number => {\n const range = max - min + 1;\n let result = Math.floor(Math.random() * range);\n return min + result;\n};\n\n","import { ExportType } from \"../../../wasm_module\";\nimport { getFiles } from \"./dataTransfer\";\nimport { JsJsonType } from \"../../../jsjson\";\nimport { ModuleControllerType } from \"../../../wasm_init\";\nimport { MapNodes } from \"./map_nodes\";\nimport { CallbackId } from \"../../types\";\n\nexport class CallbackManager {\n private readonly getWasm: () => ModuleControllerType;\n private callbacks: Map void>;\n\n public constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callbacks = new Map();\n }\n\n public add(nodes: MapNodes, id: number, event_name: string, callback_id: CallbackId) {\n const callback = (event: Event) => {\n if (event_name === 'click') {\n return this.click(event, callback_id);\n }\n\n if (event_name === 'submit') {\n return this.submit(event, callback_id);\n }\n\n if (event_name === 'input') {\n return this.input(event, callback_id);\n }\n\n if (event_name === 'change') {\n return this.change(event, callback_id);\n }\n\n if (event_name === 'blur') {\n return this.blur(event, callback_id);\n }\n\n if (event_name === 'mousedown') {\n return this.mousedown(event, callback_id);\n }\n\n if (event_name === 'mouseup') {\n return this.mouseup(event, callback_id);\n }\n\n if (event_name === 'mouseenter') {\n return this.mouseenter(event, callback_id);\n }\n\n if (event_name === 'mouseleave') {\n return this.mouseleave(event, callback_id);\n }\n\n if (event_name === 'keydown') {\n return this.keydown(event, callback_id);\n }\n\n if (event_name === 'hook_keydown') {\n return this.keydown(event, callback_id);\n }\n\n if (event_name === 'drop') {\n return this.drop(event, callback_id);\n }\n\n if (event_name === 'load') {\n return this.load(event, callback_id);\n }\n\n console.error(`No support for the event ${event_name}`);\n };\n\n if (this.callbacks.has(callback_id)) {\n console.error(`There was already a callback added with the callback_id=${callback_id}`);\n return;\n }\n\n this.callbacks.set(callback_id, callback);\n\n if (event_name === 'hook_keydown') {\n document.addEventListener('keydown', callback, false);\n } else {\n const node = nodes.get('callback_add', id);\n node.addEventListener(event_name, callback, false);\n }\n }\n\n public remove(nodes: MapNodes, id: number, event_name: string, callback_id: CallbackId) {\n const callback = this.callbacks.get(callback_id);\n this.callbacks.delete(callback_id);\n\n if (callback === undefined) {\n console.error(`The callback is missing with the id=${callback_id}`);\n return;\n }\n\n if (event_name === 'hook_keydown') {\n document.removeEventListener('keydown', callback);\n } else {\n const node = nodes.get('callback_remove', id);\n node.removeEventListener(event_name, callback);\n }\n }\n\n private wasmCallback(callback_id: CallbackId, value: JsJsonType): JsJsonType {\n return this.getWasm().wasmCommand({\n CallbackCall: {\n callback_id,\n value: value\n }\n });\n }\n\n private click(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n let click_event = this.wasmCallback(callback_id, undefined);\n\n // Check if click_event is an object (JsJson Object type)\n if (click_event !== null && typeof click_event === 'object' && !Array.isArray(click_event)) {\n if ('stop_propagation' in click_event && click_event['stop_propagation'] === true) {\n event.stopPropagation();\n }\n if ('prevent_default' in click_event && click_event['prevent_default'] === true) {\n event.preventDefault();\n }\n }\n }\n\n private submit(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n this.wasmCallback(callback_id, undefined);\n }\n\n private input(event: Event, callback_id: CallbackId) {\n const target = event.target;\n\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n this.wasmCallback(callback_id, target.value);\n return;\n }\n\n console.warn('event input ignore', target);\n }\n\n private change(event: Event, callback_id: CallbackId) {\n const target = event.target;\n\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement) {\n this.wasmCallback(callback_id, target.value);\n return;\n }\n\n console.warn('event input ignore', target);\n }\n\n private blur(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private mousedown(event: Event, callback_id: CallbackId) {\n if (this.wasmCallback(callback_id, undefined)) {\n event.preventDefault()\n }\n }\n\n private mouseup(event: Event, callback_id: CallbackId) {\n if (this.wasmCallback(callback_id, undefined)) {\n event.preventDefault()\n }\n }\n\n private mouseenter(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private mouseleave(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private drop(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n\n if (event instanceof DragEvent) {\n if (event.dataTransfer === null) {\n console.error('dom -> drop -> dataTransfer null');\n } else {\n const files = getFiles(event.dataTransfer.items);\n\n if (files.length) {\n Promise.all(files).then((files) => {\n const params = [];\n\n for (const file of files) {\n // Convert Uint8Array to array of numbers for JsJson\n const dataArray = Array.from(file.data);\n params.push([\n file.name,\n dataArray,\n ]);\n }\n\n this.wasmCallback(callback_id, [params]);\n }).catch((error) => {\n console.error('callback_drop -> promise.all -> ', error);\n });\n } else {\n console.error('No files to send');\n }\n }\n } else {\n console.warn('event drop ignore', event);\n }\n }\n\n private keydown(event: Event, callback_id: CallbackId) {\n if (event instanceof KeyboardEvent) {\n const result = this.wasmCallback(callback_id, [\n event.key,\n event.code,\n event.altKey,\n event.ctrlKey,\n event.shiftKey,\n event.metaKey\n ]);\n\n if (result === true) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n return;\n }\n\n console.warn('keydown ignore', event);\n }\n\n private load(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n this.wasmCallback(callback_id, undefined);\n }\n\n}\n","interface FileItemType {\n name: string,\n data: Uint8Array,\n}\n\nexport function getFiles(items: DataTransferItemList): Array> {\n const files: Array> = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n\n if (item === undefined) {\n console.error('dom -> drop -> item - undefined');\n } else {\n const file = item.getAsFile();\n\n if (file === null) {\n console.error(`dom -> drop -> index:${i} -> It's not a file`);\n } else {\n files.push(file\n .arrayBuffer()\n .then((data): FileItemType => ({\n name: file.name,\n data: new Uint8Array(data),\n }))\n );\n }\n }\n }\n return files;\n}\n","import { AppLocation } from \"../../location/AppLocation\";\n\nexport function injects(node: Element, appLocation: AppLocation) {\n if (node.tagName.toLocaleLowerCase() === 'a') {\n hydrateLink(node, appLocation);\n }\n}\n\nfunction hydrateLink(node: Element, appLocation: AppLocation) {\n node.addEventListener('click', (e) => {\n let href = node.getAttribute('href');\n if (href === null) {\n return;\n }\n\n if (href.startsWith('#') || href.startsWith('http://') || href.startsWith('https://') || href.startsWith('//')) {\n return;\n }\n\n e.preventDefault();\n appLocation.set('History', 'Push', href);\n window.scrollTo(0, 0);\n })\n}\n","import { AppLocation } from \"../../location/AppLocation\";\nimport { CommandType } from \"./dom\";\nimport { injects } from \"./injects\";\nimport { MapNodes } from \"./map_nodes\";\n\ninterface VirtualNode {\n id: number;\n name?: string;\n value?: string;\n attributes?: Map;\n children: Array;\n}\n\nexport const hydrate = (commands: Array, nodes: MapNodes, appLocation: AppLocation) => {\n const engine = new HydrationEngine(commands, nodes, appLocation);\n engine.hydrate();\n};\n\nclass HydrationEngine {\n private nodes: MapNodes;\n private appLocation: AppLocation;\n private virtualNodes: Map;\n private depth: number = -1;\n private matched: number = 0;\n\n constructor(commands: Array, nodes: MapNodes, appLocation: AppLocation) {\n this.nodes = nodes;\n this.appLocation = appLocation;\n this.virtualNodes = this.createVirtualNodes(commands);\n }\n\n public hydrate() {\n // Start hydration from Body (id=3) and Head (id=2) if needed\n // Usually we care about Body.\n const bodyVNode = this.virtualNodes.get(3);\n if (bodyVNode) {\n this.hydrateNode(3, document.body);\n }\n\n const headVNode = this.virtualNodes.get(2);\n if (headVNode) {\n this.hydrateNode(2, document.head);\n }\n\n console.log(\n \"Hydration complete,\",\n (this.matched * 100 / this.virtualNodes.size).toFixed(2),\n \" % vnodes matched.\",\n );\n };\n\n // Traverse and Match\n private hydrateNode(vNodeId: number, realNode: Node) {\n const vNode = this.virtualNodes.get(vNodeId);\n if (!vNode) return;\n\n // console.log(`Hydration ${this.depth + 1}: Hydrate node`, vNode, realNode);\n\n // Match children\n const realChildren = Array.from(realNode.childNodes);\n let realIndex = 0;\n this.depth++;\n let skipTextVNodes = false;\n\n for (const childVId of vNode.children) {\n const childVNode = this.virtualNodes.get(childVId);\n if (!childVNode) continue;\n\n // If we are in group of text vnodes, skip them until we find a non-text vnode.\n if (skipTextVNodes && childVNode.value !== undefined) {\n // Deliberately skipped vNodes should be counted as matched\n this.matched++;\n continue;\n } else {\n skipTextVNodes = false;\n }\n\n // Find a matching real node starting from realIndex\n for (let i = realIndex; i < realChildren.length; i++) {\n const candidate = realChildren[i];\n if (!candidate) continue;\n\n let isMatch = false;\n if (childVNode.name) {\n // Element\n isMatch = this.checkElementMatch(candidate, childVNode);\n } else if (childVNode.value !== undefined) {\n // Text\n if (candidate.nodeType === Node.TEXT_NODE) {\n this.checkTextMatch(candidate, childVNode);\n isMatch = true;\n // Start skipping eventual group of text vnodes\n // as they were probably merged into one on SSR side.\n skipTextVNodes = true;\n } else {\n console.error(`Hydration ${this.depth}: Text node mismatch`, childVNode, candidate);\n }\n }\n\n if (isMatch) {\n this.removeSkippedNodes(realChildren, realIndex, i);\n this.claimNode(candidate, childVId);\n this.matched++;\n\n // Recurse if element\n if (childVNode.name) {\n this.hydrateNode(childVId, candidate);\n }\n\n // Advance realIndex to i + 1 (consume this node)\n realIndex = i + 1;\n break;\n }\n }\n }\n\n // Remove remaining real nodes\n this.removeSkippedNodes(realChildren, realIndex, realChildren.length);\n this.depth--;\n };\n\n private checkElementMatch(candidate: Node, childVNode: VirtualNode) {\n let isMatch = false;\n if (candidate.nodeType === Node.ELEMENT_NODE && (candidate as Element).tagName === childVNode.name) {\n isMatch = true;\n // Check attributes\n if (childVNode.attributes) {\n const element = candidate as Element;\n for (const [name, value] of childVNode.attributes) {\n if (element.getAttribute(name) !== value) {\n // console.info(`Hydration ${depth}: Reseting attribute`, element.getAttribute(name), \" !== \", value);\n element.setAttribute(name, value);\n }\n }\n }\n }\n return isMatch;\n };\n\n private checkTextMatch(candidate: Node, childVNode: VirtualNode) {\n // For text nodes, we might want to be lenient or exact.\n // Let's assume exact match or at least non-empty.\n // Often text nodes might have whitespace differences.\n // For now, let's just check if it's a text node.\n // Checking content might be safer.\n if (candidate.textContent?.replace('\\n', ' ').trim() !== childVNode.value?.replace('\\n', ' ').trim()) {\n // console.debug(`Hydration ${depth}: Joint text`, childVNode, candidate);\n candidate.textContent = childVNode.value || \"\";\n }\n };\n\n // Claim node and run injects\n private claimNode(candidate: Node, childVId: number) {\n if (candidate instanceof Element || candidate instanceof Comment || candidate instanceof Text) {\n this.nodes.claimNode(childVId, candidate);\n\n // Run injects\n if (candidate instanceof Element) {\n injects(candidate, this.appLocation);\n }\n }\n }\n\n // Remove nodes skipped during matching\n private removeSkippedNodes(realChildren: ChildNode[], realIndex: number, i: number) {\n for (let j = realIndex; j < i; j++) {\n const nodeToRemove = realChildren[j];\n if (nodeToRemove) {\n if (this.depth !== 0 && nodeToRemove.nodeType !== Node.TEXT_NODE) {\n console.warn(`Hydration ${this.depth}: Removing node`, nodeToRemove);\n }\n nodeToRemove.remove();\n }\n }\n }\n\n private createVirtualNodes(commands: Array): Map {\n const virtualNodes = new Map();\n\n // Helper to get or create a virtual node\n const getVNode = (id: number): VirtualNode => {\n let node = virtualNodes.get(id);\n if (!node) {\n node = { id, children: [] };\n virtualNodes.set(id, node);\n }\n return node;\n };\n\n // Build Virtual Tree from Commands\n for (const command of commands) {\n if ('CreateNode' in command) {\n const node = getVNode(command.CreateNode.id);\n node.name = command.CreateNode.name.toUpperCase();\n } else if ('CreateText' in command) {\n const node = getVNode(command.CreateText.id);\n node.value = command.CreateText.value;\n } else if ('InsertBefore' in command) {\n const parent = getVNode(command.InsertBefore.parent);\n const childId = command.InsertBefore.child;\n const refId = command.InsertBefore.ref_id;\n\n if (refId === null || refId === undefined) {\n parent.children.push(childId);\n } else {\n const index = parent.children.indexOf(refId);\n if (index !== -1) {\n parent.children.splice(index, 0, childId);\n } else {\n console.warn(`Hydration: ref_id ${refId} not found in parent ${command.InsertBefore.parent}`);\n parent.children.push(childId);\n }\n }\n } else if ('SetAttr' in command) {\n const node = getVNode(command.SetAttr.id);\n if (!node.attributes) {\n node.attributes = new Map();\n }\n node.attributes.set(command.SetAttr.name, command.SetAttr.value);\n }\n }\n\n return virtualNodes;\n };\n}\n","type NodeType = Element | Comment | Text;\nexport class MapNodes {\n private data: Map;\n private initNodes: Array | null;\n private style: HTMLStyleElement;\n\n constructor() {\n this.data = new Map();\n\n this.initNodes = [\n ...this.getRootHead().childNodes,\n ...this.getRootBody().childNodes,\n ];\n\n this.style = document.createElement('style');\n }\n\n private getRootHtml(): Element {\n return document.documentElement;\n }\n\n private getRootHead(): Element {\n return document.head;\n }\n\n private getRootBody(): Element {\n return document.body;\n }\n\n public set(id: number, value: NodeType) {\n if (id === 1 || id === 2 || id === 3) {\n //ignore\n } else {\n this.data.set(id, value);\n }\n }\n\n public getAnyOption(id: number): NodeType | undefined {\n if (id === 1) {\n return this.getRootHtml();\n }\n\n if (id === 2) {\n return this.getRootHead();\n }\n\n if (id === 3) {\n return this.getRootBody();\n }\n\n return this.data.get(id);\n }\n\n public getAny(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n\n if (item === undefined) {\n throw Error(`${label} -> item not found=${id}`);\n }\n\n return item;\n }\n\n public get(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n\n if (item === undefined) {\n throw new Error(`${label}->get: Item id not found = ${id}`);\n }\n return item;\n }\n\n public getNodeElement(label: string, id: number): HTMLElement {\n const node = this.get(label, id);\n if (node instanceof HTMLElement) {\n return node;\n } else {\n throw Error(`Expected id=${id} as HTMLElement`);\n }\n }\n\n public getNode(label: string, id: number): Element {\n const node = this.get(label, id);\n if (node instanceof Element) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Element`);\n }\n }\n\n public getText(label: string, id: number): Text {\n const node = this.get(label, id);\n if (node instanceof Text) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Text`);\n }\n }\n\n public getComment(label: string, id: number): Comment {\n const node = this.get(label, id);\n if (node instanceof Comment) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Comment`);\n }\n }\n\n public delete(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n this.data.delete(id);\n\n if (item === undefined) {\n throw new Error(`${label}->delete: Item id not found = ${id}`);\n }\n\n return item;\n }\n\n public insertCss(selector: string | null, value: string) {\n if (selector !== null) {\n // Add autocss styles\n const content = document.createTextNode(`\\n${selector} { ${value} }`);\n this.style.appendChild(content);\n } else {\n // Add bundle (i.e. a tailwind bundle)\n const content = document.createTextNode(`\\n${value}`);\n this.style.appendChild(content);\n }\n }\n\n public removeInitNodes() {\n const initNodes = this.initNodes;\n this.initNodes = null;\n\n if (initNodes === null) {\n return;\n }\n\n for (const node of initNodes) {\n node.remove();\n }\n }\n\n public insertBefore(parent: number, child: number, ref_id: number | null | undefined) {\n const parentNode = this.get(\"insert_before\", parent);\n const childNode = this.getAny(\"insert_before child\", child);\n\n if (ref_id === null || ref_id === undefined) {\n parentNode.insertBefore(childNode, null);\n } else {\n const ref_node = this.getAny('insert_before ref', ref_id);\n parentNode.insertBefore(childNode, ref_node);\n }\n }\n\n public addStyles() {\n this.getRootHead().appendChild(this.style);\n }\n\n public hasInitNodes(): boolean {\n return this.initNodes !== null;\n }\n\n public claimNode(id: number, node: NodeType) {\n this.data.set(id, node);\n\n if (this.initNodes) {\n const index = this.initNodes.indexOf(node as ChildNode);\n if (index > -1) {\n this.initNodes.splice(index, 1);\n }\n }\n }\n\n public has(id: number): boolean {\n // Root nodes always exist in real DOM\n if (id === 1 || id === 2 || id === 3) {\n return true;\n }\n\n return this.data.has(id);\n }\n}\n","import { AppLocation } from \"../../location/AppLocation\";\nimport { CallbackManager } from \"./callbackManager\";\nimport { ExportType } from \"../../../wasm_module\";\nimport { hydrate } from \"./hydration\";\nimport { injects } from \"./injects\";\nimport { MapNodes } from \"./map_nodes\";\nimport { ModuleControllerType } from \"../../../wasm_init\";\nimport { Metadata } from \"../../metadata\";\n\n// Workaround, remove when https://github.com/vertigo-web/vertigo/issues/539 is done.\nconst SVG_TAGS = new Set([\n \"animate\", \"animateMotion\", \"animateTransform\", \"circle\", \"clipPath\", \"defs\",\n \"desc\", \"discard\", \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\",\n \"feComposite\", \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\",\n \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \"feFuncG\",\n \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \"feMorphology\",\n \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \"feSpotLight\", \"feTile\",\n \"feTurbulence\", \"filter\", \"foreignObject\", \"g\", \"hatch\", \"hatchpath\", \"image\",\n \"line\", \"linearGradient\", \"marker\", \"mask\", \"metadata\", \"mpath\", \"path\", \"pattern\",\n \"polygon\", \"polyline\", \"radialGradient\", \"rect\", \"set\", \"stop\", \"svg\", \"switch\",\n \"symbol\", \"text\", \"textPath\", \"tspan\", \"use\", \"view\",\n \"svg:a\", \"svg:title\", \"svg:desc\", \"svg:script\", \"svg:style\"\n]);\n\nconst createElement = (name: string): Element => {\n if (SVG_TAGS.has(name)) {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", name.replace(\"svg:\", \"\"));\n } else {\n return document.createElement(name);\n }\n}\n\nexport type CommandType = {\n CreateNode: {\n id: number,\n name: string,\n }\n} | {\n CreateText: {\n id: number,\n value: string\n }\n} | {\n UpdateText: {\n id: number,\n value: string\n }\n} | {\n SetAttr: {\n id: number,\n name: string,\n value: string\n }\n} | {\n RemoveAttr: {\n id: number,\n name: string\n }\n} | {\n RemoveNode: {\n id: number,\n }\n} | {\n RemoveText: {\n id: number,\n }\n} | {\n InsertBefore: {\n parent: number,\n child: number,\n ref_id: number | null,\n }\n} | {\n InsertCss: {\n selector: string | null,\n value: string\n }\n} | {\n CreateComment: {\n id: number,\n value: string\n }\n} | {\n RemoveComment: {\n id: number,\n }\n} | {\n CallbackAdd: {\n id: number,\n event_name: string,\n callback_id: number,\n }\n} | {\n CallbackRemove: {\n id: number,\n event_name: string,\n callback_id: number,\n }\n};\n\nconst assertNeverCommand = (data: never): never => {\n console.error(data);\n throw Error('unknown command');\n};\n\nexport class DriverDom {\n private appLocation: AppLocation;\n public readonly nodes: MapNodes;\n private readonly callbacks: CallbackManager;\n\n public constructor(private readonly metadata: Metadata, appLocation: AppLocation, getWasm: () => ModuleControllerType) {\n this.appLocation = appLocation;\n this.nodes = new MapNodes();\n this.callbacks = new CallbackManager(getWasm);\n\n document.addEventListener('dragover', (ev): void => {\n // console.log('File(s) in drop zone');\n ev.preventDefault();\n });\n }\n\n public update = (commands: Array) => {\n if (this.nodes.hasInitNodes() && this.metadata.getEnabledHydration()) {\n hydrate(commands, this.nodes, this.appLocation);\n }\n\n const setFocus: Set = new Set();\n\n for (const command of commands) {\n try {\n this.runCommand(command);\n } catch (error) {\n console.error('bulk_update - item', error, command);\n }\n\n if ('SetAttr' in command && command.SetAttr.name.toLocaleLowerCase() === 'autofocus') {\n setFocus.add(command.SetAttr.id);\n }\n }\n\n if (setFocus.size > 0) {\n setTimeout(() => {\n for (const id of setFocus) {\n const node = this.nodes.getNodeElement(`set focus ${id}`, id);\n node.focus();\n }\n }, 0);\n }\n\n this.nodes.removeInitNodes();\n\n // Make sure that the client-side generated styles are always the last element of the head\n this.nodes.addStyles();\n }\n\n private createNode(id: number, name: string) {\n // Root nodes (html/head/body) already exist in the real DOM\n if (id === 1 || id === 2 || id === 3) {\n return;\n }\n\n if (this.nodes.has(id)) {\n return;\n }\n\n const node = createElement(name);\n this.nodes.set(id, node);\n\n injects(node, this.appLocation);\n }\n\n private setAttr(id: number, name: string, value: string) {\n const node = this.nodes.getNode(\"set_attribute\", id);\n node.setAttribute(name, value);\n\n if (name == \"value\") {\n if (node instanceof HTMLInputElement) {\n node.value = value;\n return;\n }\n\n if (node instanceof HTMLTextAreaElement) {\n node.value = value;\n node.defaultValue = value;\n return;\n }\n }\n }\n\n private removeAttr(id: number, name: string) {\n const node = this.nodes.getNode(\"remove_attribute\", id);\n node.removeAttribute(name);\n\n if (name == \"value\") {\n if (node instanceof HTMLInputElement) {\n node.value = \"\";\n return;\n }\n\n if (node instanceof HTMLTextAreaElement) {\n node.value = \"\";\n node.defaultValue = \"\";\n return;\n }\n }\n }\n\n private removeNode(id: number) {\n // Never remove real document roots\n if (id === 1 || id === 2 || id === 3) {\n return;\n }\n\n const node = this.nodes.delete(\"remove_node\", id);\n node.remove();\n }\n\n private createText(id: number, value: string) {\n if (this.nodes.has(id)) {\n return;\n }\n\n const text = document.createTextNode(value);\n this.nodes.set(id, text);\n }\n\n private removeText(id: number) {\n const text = this.nodes.delete(\"remove_node\", id);\n text.remove();\n }\n\n private updateText(id: number, value: string) {\n const text = this.nodes.getText(\"set_attribute\", id);\n text.textContent = value;\n }\n\n private runCommand(command: CommandType) {\n if ('RemoveNode' in command) {\n this.removeNode(command.RemoveNode.id);\n return;\n }\n\n if ('InsertBefore' in command) {\n this.nodes.insertBefore(command.InsertBefore.parent, command.InsertBefore.child, command.InsertBefore.ref_id === null ? null : command.InsertBefore.ref_id);\n return;\n }\n\n if ('CreateNode' in command) {\n this.createNode(command.CreateNode.id, command.CreateNode.name);\n return;\n }\n\n if ('CreateText' in command) {\n this.createText(command.CreateText.id, command.CreateText.value);\n return;\n }\n\n if ('UpdateText' in command) {\n this.updateText(command.UpdateText.id, command.UpdateText.value);\n return;\n }\n\n if ('SetAttr' in command) {\n this.setAttr(command.SetAttr.id, command.SetAttr.name, command.SetAttr.value);\n return;\n }\n\n if ('RemoveAttr' in command) {\n this.removeAttr(command.RemoveAttr.id, command.RemoveAttr.name);\n return;\n }\n\n if ('RemoveText' in command) {\n this.removeText(command.RemoveText.id);\n return;\n }\n\n if ('InsertCss' in command) {\n this.nodes.insertCss(command.InsertCss.selector, command.InsertCss.value);\n return;\n }\n\n if ('CreateComment' in command) {\n const comment = document.createComment(command.CreateComment.value);\n this.nodes.set(command.CreateComment.id, comment);\n return;\n }\n\n if ('RemoveComment' in command) {\n const comment = this.nodes.delete(\"remove_comment\", command.RemoveComment.id);\n comment.remove();\n return;\n }\n\n if ('CallbackAdd' in command) {\n this.callbacks.add(this.nodes, command.CallbackAdd.id, command.CallbackAdd.event_name, command.CallbackAdd.callback_id);\n return;\n }\n\n if ('CallbackRemove' in command) {\n this.callbacks.remove(this.nodes, command.CallbackRemove.id, command.CallbackRemove.event_name, command.CallbackRemove.callback_id);\n return;\n }\n\n return assertNeverCommand(command);\n }\n}\n","import { DriverWebsocket } from \"./websocket/websocket\";\nimport { assertNever } from \"../assert_never\";\nimport { JsJsonType } from \"../jsjson\";\nimport { ModuleControllerType } from \"../wasm_init\";\nimport { ExportType } from \"../wasm_module\";\nimport { fetchCacheGet } from \"./command/fetchCacheGet\";\nimport { fetchExec, FetchRequestType } from \"./command/fetchExec\";\nimport { CallbackId } from \"./types\";\nimport { Interval } from \"./command/interval\";\nimport { AppLocation } from './location/AppLocation';\nimport { Cookies } from \"./command/cookies\";\nimport { getRandom } from \"./command/getRandom\";\nimport { CommandType, DriverDom } from \"./command/dom/dom\";\nimport { Metadata } from \"./metadata\";\n\ntype JsApiCommandType =\n | { Root: { name: string } }\n | { RootElement: { dom_id: number } }\n | { Get: { property: string } }\n | { Set: { property: string, value: JsJsonType } }\n | { Call: { method: string, args: JsJsonType[] } };\n\ntype ExecType\n = 'FetchCacheGet'\n | 'IsBrowser'\n | 'GetDateNow'\n | 'TimezoneOffset'\n | 'HistoryBack'\n | {\n FetchExec: {\n callback: CallbackId,\n request: FetchRequestType,\n }\n }\n | {\n WebsocketRegister: {\n callback: CallbackId,\n host: string\n }\n }\n | {\n WebsocketSendMessage: {\n callback: CallbackId,\n message: JsJsonType,\n }\n }\n | {\n WebsocketUnregister: {\n callback: CallbackId,\n }\n }\n | {\n TimerSet: {\n callback: CallbackId,\n duration: number,\n kind: 'Interval' | 'Timeout',\n }\n }\n | {\n TimerClear: {\n callback: CallbackId,\n }\n }\n | {\n LocationGet: {\n target: 'Hash' | 'History',\n }\n }\n | {\n LocationCallback: {\n callback: CallbackId,\n mode: 'Add' | 'Remove',\n target: 'Hash' | 'History'\n }\n }\n | {\n LocationSet: {\n mode: 'Push' | 'Replace',\n target: 'Hash' | 'History'\n value: string\n }\n }\n | {\n CookieSet: {\n name: string,\n value: string,\n expires_in: number,\n }\n }\n | {\n CookieGet: {\n name: string,\n }\n }\n | {\n CookieJsonSet: {\n name: string,\n value: JsJsonType,\n expires_in: number,\n }\n }\n | {\n CookieJsonGet: {\n name: string,\n }\n }\n | {\n GetEnv: {\n name: string\n }\n }\n | {\n Log: {\n arg2: string, //\"color: white; padding: 0 3px; background: green;\",\n arg3: string, //\"font-weight: bold; color: inherit\",\n arg4: string, //\"background: inherit; color: inherit\",\n kind: 'Debug' | 'Info' | 'Log' | 'Warn' | 'Error',\n message: string, //\"%cINFO%c crates/vertigo/src/driver_module/api/api_fetch_cache.rs:26%c FetchCache ready\"\n }\n }\n | {\n GetRandom: {\n min: number,\n max: number,\n }\n }\n | {\n JsApiCall: {\n commands: Array\n }\n }\n | {\n DomBulkUpdate: {\n list: Array\n }\n };\n\nexport class Api {\n public readonly dom: DriverDom;\n private readonly websocket: DriverWebsocket;\n private readonly interval: Interval;\n private readonly location: AppLocation;\n private readonly cookie: Cookies;\n\n\n constructor(private readonly metadata: Metadata, private readonly getWasm: () => ModuleControllerType) {\n const appLocation = new AppLocation(getWasm);\n\n this.dom = new DriverDom(metadata, appLocation, getWasm);\n this.websocket = new DriverWebsocket(getWasm);\n this.interval = new Interval(getWasm);\n this.location = appLocation;\n this.cookie = new Cookies();\n }\n\n exec(arg: JsJsonType): JsJsonType {\n\n //@ts-expect-error - //TODO Add safe type checking\n const safeArg: ExecType = arg;\n\n // console.info('exec arg', safeArg);\n\n if (safeArg === 'FetchCacheGet') {\n return fetchCacheGet(this.metadata);\n }\n\n if (safeArg === 'IsBrowser') {\n return {\n value: true\n };\n }\n\n if (safeArg === 'GetDateNow') {\n return {\n value: Date.now(),\n };\n }\n\n if (safeArg === 'TimezoneOffset') {\n return {\n value: new Date().getTimezoneOffset()\n };\n }\n\n if (safeArg === 'HistoryBack') {\n window.history.back();\n return null;\n }\n\n if ('FetchExec' in safeArg) {\n fetchExec(this.getWasm, safeArg.FetchExec.callback, safeArg.FetchExec.request);\n return null;\n }\n\n if ('WebsocketRegister' in safeArg) {\n this.websocket.websocket_register_callback(safeArg.WebsocketRegister.host, safeArg.WebsocketRegister.callback);\n return null;\n }\n\n if ('WebsocketSendMessage' in safeArg) {\n this.websocket.websocket_send_message(safeArg.WebsocketSendMessage.callback, safeArg.WebsocketSendMessage.message);\n return null;\n }\n\n if ('WebsocketUnregister' in safeArg) {\n this.websocket.websocket_unregister_callback(safeArg.WebsocketUnregister.callback);\n return null;\n }\n\n if ('TimerSet' in safeArg) {\n this.interval.timerSet(safeArg.TimerSet.callback, safeArg.TimerSet.duration, safeArg.TimerSet.kind);\n return null;\n }\n\n if ('TimerClear' in safeArg) {\n this.interval.timerClear(safeArg.TimerClear.callback);\n return null;\n }\n\n if ('LocationGet' in safeArg) {\n return {\n value: this.location.get(safeArg.LocationGet.target)\n };\n }\n\n if ('LocationCallback' in safeArg) {\n this.location.callback(safeArg.LocationCallback.target, safeArg.LocationCallback.mode, safeArg.LocationCallback.callback);\n return null;\n }\n\n if ('LocationSet' in safeArg) {\n this.location.set(safeArg.LocationSet.target, safeArg.LocationSet.mode, safeArg.LocationSet.value);\n return null;\n }\n\n if ('CookieGet' in safeArg) {\n return {\n value: this.cookie.get(safeArg.CookieGet.name)\n };\n }\n\n if ('CookieSet' in safeArg) {\n this.cookie.set(safeArg.CookieSet.name, safeArg.CookieSet.value, safeArg.CookieSet.expires_in);\n return null;\n }\n\n if ('CookieJsonGet' in safeArg) {\n return {\n value: this.cookie.getJson(safeArg.CookieJsonGet.name)\n };\n }\n\n if ('CookieJsonSet' in safeArg) {\n this.cookie.setJson(safeArg.CookieJsonSet.name, safeArg.CookieJsonSet.value, safeArg.CookieJsonSet.expires_in);\n return null;\n }\n\n if ('GetEnv' in safeArg) {\n const name = safeArg.GetEnv.name;\n\n return {\n value: this.metadata.getEnv(name),\n }\n }\n\n if ('Log' in safeArg) {\n switch (safeArg.Log.kind) {\n case 'Info': {\n console.info(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Debug': {\n console.debug(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Error': {\n console.error(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Log': {\n console.log(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Warn': {\n console.warn(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n }\n }\n\n if ('GetRandom' in safeArg) {\n return {\n value: getRandom(safeArg.GetRandom.min, safeArg.GetRandom.max)\n };\n }\n\n if ('JsApiCall' in safeArg) {\n return this.executeJsApiCall(safeArg.JsApiCall.commands);\n }\n\n if ('DomBulkUpdate' in safeArg) {\n this.dom.update(safeArg.DomBulkUpdate.list);\n return null;\n }\n\n console.info('exec_command: Arg', safeArg);\n return assertNever(safeArg);\n }\n\n private executeJsApiCall(commands: Array): JsJsonType {\n let current: any = null;\n\n for (const command of commands) {\n if ('Root' in command) {\n if (command.Root.name === 'window') {\n current = window;\n } else if (command.Root.name === 'document') {\n current = document;\n } else {\n console.error(`Unknown root: ${command.Root.name}`);\n return null;\n }\n } else if ('RootElement' in command) {\n const domId = command.RootElement.dom_id;\n const node = this.dom.nodes.getAnyOption(domId);\n if (node === undefined) {\n console.error(`Element not found: ${domId}`);\n return null;\n }\n current = node;\n } else if ('Get' in command) {\n if (current === null) {\n console.error('Get called on null');\n return null;\n }\n current = current[command.Get.property];\n } else if ('Set' in command) {\n if (current === null) {\n console.error('Set called on null');\n return null;\n }\n current[command.Set.property] = command.Set.value;\n current = undefined;\n } else if ('Call' in command) {\n if (current === null) {\n console.error('Call called on null');\n return null;\n }\n current = current[command.Call.method](...command.Call.args);\n }\n }\n\n // Convert result to JsJson - sanitize host objects (Window, Element, Function, etc.)\n const isPlainObject = (obj: any): boolean => {\n if (obj === null) return false;\n if (typeof obj !== 'object') return false;\n const proto = Object.getPrototypeOf(obj);\n return proto === Object.prototype || proto === null;\n };\n\n const sanitize = (value: any): JsJsonType => {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'boolean') {\n return value;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number') {\n return value;\n }\n if (value instanceof Uint8Array) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((v) => sanitize(v));\n }\n if (isPlainObject(value)) {\n const out: { [k: string]: JsJsonType } = {};\n for (const k of Object.keys(value)) {\n out[k] = sanitize(value[k]);\n }\n return out;\n }\n\n // Host objects (Window, Element, DOM nodes, functions, class instances, etc.)\n // are not serializable to JsJson. Return null for safety.\n return null;\n };\n\n return sanitize(current);\n }\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { Metadata } from \"../metadata\";\n\nexport const fetchCacheGet = (metadata: Metadata): JsJsonType => {\n const cache = metadata.getFetchCache();\n\n return {\n data: cache\n };\n};\n","export class Metadata {\n private readonly metadata: HTMLElement;\n\n constructor() {\n const metadata = document.getElementById('v-metadata');\n\n if (metadata === null) {\n throw Error('Expected v-metadata');\n }\n\n this.metadata = metadata;\n metadata.remove();\n }\n\n private get = (attr: string): string | null => {\n return this.metadata.getAttribute(attr) ?? null;\n }\n\n getEnv(name: string) {\n return this.get(`data-env-${name}`);\n }\n\n getFetchCache() {\n return this.get('data-fetch-cache') ?? null;\n }\n\n getEnabledHydration = (): boolean => {\n const value = this.get('data-env-disable-hydration');\n return value !== 'true';\n }\n}\n","import { wasmInit, ModuleControllerType } from './wasm_init';\nimport { BufferCursor } from './buffer_cursor';\nimport { jsJsonDecodeItem, jsJsonGetSize, saveJsJsonToBufferItem } from './jsjson';\nimport { Api } from './api/api';\nimport { Metadata } from './api/metadata';\n\n//Number -> u32 or i32\n//BigInt -> u64 or i64\n\nexport type ImportType = {\n panic_message: (long_ptr: bigint) => void,\n //call from rust\n dom_access: (long_ptr: bigint) => bigint,\n}\n\nexport type ExportType = {\n vertigo_export_alloc_block: (size: number) => bigint,\n vertigo_export_free_block: (pointer: bigint) => void,\n vertigo_export_wasm_command: (value_ptr: bigint) => bigint,\n vertigo_entry_function: (major: number, minor: number) => void,\n}\n\nexport class WasmModule {\n private readonly wasm: ModuleControllerType;\n\n private constructor(\n wasm: ModuleControllerType,\n ) {\n this.wasm = wasm;\n }\n\n public vertigoEntryFunction(major: number, minor: number) {\n this.wasm.exports.vertigo_entry_function(major, minor);\n }\n\n public static async create(wasmBinPath: string): Promise {\n let wasmModule: ModuleControllerType | null = null;\n\n const getWasm = (): ModuleControllerType => {\n if (wasmModule === null) {\n throw Error('Wasm is no initialized');\n }\n\n return wasmModule;\n };\n\n const metadata = new Metadata();\n const vertigo_api = new Api(metadata, getWasm);\n\n //@ts-expect-error\n window.$vertigoApi = vertigo_api;\n\n wasmModule = await wasmInit(wasmBinPath, {\n mod: {\n panic_message: (long_ptr: bigint) => {\n\n const size = Number(long_ptr % (2n ** 32n));\n const ptr = Number(long_ptr >> 32n);\n\n const decoder = new TextDecoder(\"utf-8\");\n const m = getWasm().getUint8Memory().subarray(ptr, ptr + size);\n const message = decoder.decode(m);\n console.error('PANIC', message);\n },\n dom_access: (long_ptr: bigint): bigint => {\n if (long_ptr === 0n) {\n console.error('dom_access - null pointer');\n return 0n;\n }\n\n // Decode JsJson\n const buffer = new BufferCursor(\n () => getWasm().getUint8Memory(),\n long_ptr\n );\n const args = jsJsonDecodeItem(buffer);\n getWasm().exports.vertigo_export_free_block(long_ptr);\n\n // Execute command (now using JsApiCall instead of array-of-arrays)\n const response = vertigo_api.exec(args);\n\n // Save JsJson response\n const responseSize = jsJsonGetSize(response);\n const responseLongPtr = getWasm().exports.vertigo_export_alloc_block(responseSize);\n const responseBuffer = new BufferCursor(\n () => getWasm().getUint8Memory(),\n responseLongPtr\n );\n saveJsJsonToBufferItem(response, responseBuffer);\n\n return responseLongPtr;\n }\n }\n });\n\n return new WasmModule(wasmModule);\n }\n}\n","import { WasmModule } from \"./wasm_module\";\n\n// vertigo-cli compatibility version, change together with package version.\nconst VERTIGO_COMPAT_VERSION_MAJOR = 0;\nconst VERTIGO_COMPAT_VERSION_MINOR = 11;\n\nconst moduleRun: Set = new Set();\n\nconst runModule = async (wasm: string) => {\n if (moduleRun.has(wasm)) {\n //ok, module is run\n return;\n }\n\n if (moduleRun.size > 0) {\n console.error('Only one wasm module can be run', { moduleRun, wasm });\n return;\n }\n\n moduleRun.add(wasm);\n\n console.info(`Wasm module: \"${wasm}\" -> start`);\n const wasmModule = await WasmModule.create(wasm);\n console.info(`Wasm module: \"${wasm}\" -> initialized`);\n wasmModule.vertigoEntryFunction(VERTIGO_COMPAT_VERSION_MAJOR, VERTIGO_COMPAT_VERSION_MINOR);\n console.info(`Wasm module: \"${wasm}\" -> launched vertigoEntryFunction with version ${VERTIGO_COMPAT_VERSION_MAJOR}.${VERTIGO_COMPAT_VERSION_MINOR}`);\n};\n\nconst findAndRunModule = async () => {\n document.querySelectorAll('*[data-vertigo-run-wasm]').forEach((node) => {\n const wasm = node.getAttribute('data-vertigo-run-wasm');\n\n if (typeof wasm === 'string') {\n runModule(wasm);\n } else {\n console.error('Run error', node);\n }\n });\n};\n\n(() => {\n window.addEventListener('load', findAndRunModule);\n setTimeout(findAndRunModule, 3000);\n})();\n"],"names":["decoder","TextDecoder","encoder","TextEncoder","BufferCursor","constructor","getUint8Memory","long_ptr","this","pointer","ptr","Number","size","dataView","DataView","buffer","getByte","value","getUint8","setByte","byte","setUint8","getU16","getUint16","setU16","setUint16","getU32","getUint32","setU32","setUint32","getI32","getInt32","setI32","setInt32","getU64","getBigUint64","setU64","setBigUint64","getI64","getBigInt64","setI64","setBigInt64","getF64","getFloat64","setF64","setFloat64","getBuffer","result","subarray","setBuffer","length","set","getString","decode","setString","encode","getSavedSize","JsJsonConst","jsJsonGetSize","Uint8Array","Array","isArray","sum","item","key","propertyValue","Object","entries","Error","jsJsonDecodeItem","typeId","count","list","i","push","obj","saveJsJsonToBufferItem","undefined","wasmInit","async","wasmBinPath","imports","module_instance","WebAssembly","instantiateStreaming","stream","fetch","err","console","warn","info","resp","binary","arrayBuffer","instantiate","fetchModule","cacheGetUint8Memory","instance","exports","memory","Memory","wasmCommand","vertigo_export_alloc_block","result_long_ptr","vertigo_export_wasm_command","resultBuffer","vertigo_export_free_block","EventEmitter","events","Set","on","callback","isActive","onExec","param","add","delete","trigger","eventsCopy","from","values","itemCallbackToRun","error","PromiseBoxRace","inner","resolve","promiseResolveReject","reject","isFulfilled","promise","Promise","localResolve","localReject","createPromiseValue","reconnectDelay","label","timeout_retry","timeout","setTimeout","LogContext","host","formatLog","message","SocketConnection","close","send","eventMessage","connect","log","done","socket","WebSocket","isClose","closeSocket","socketConnection","addEventListener","event","dataRaw","data","startSocket","timeout_connection","onMessage","isConnect","openSocketResult","type","catch","dispose","wireStringToJsJson","raw","JSON","parse","wasmCallback","wasm","callbackId","command","Websocket","DriverWebsocket","getWasm","websocket_register_callback","callback_id","controller","controllerList","has","assertNeverMessage","Message","websocket_unregister_callback","get","websocket_send_message","stringify","Map","getHeaders","headers","k","v","getBodyString","body","Data","processResponse","response","status","contentType","startsWith","Ok","Text","text","Json","bodyText","Err","String","Interval","timerSet","duration","kind","timerId","setInterval","TimerCall","timerClear","timerResource","clearInterval","clearTimeout","HashRouter","LocationCall","remove","new_hash","location","hash","replace","history","replaceState","window","decodeURIComponent","substr","HistoryLocation","url","pushState","pathname","search","AppLocation","target","mode","locations","newValue","Hash","History","Cookies","cname","cookie","document","split","cookieChunk","trim","cookieName","cookieValue","getJson","cvalue_str","e","cvalue","expires_in","cvalueEncoded","encodeURIComponent","d","Date","setTime","getTime","expires","toUTCString","setJson","getRandom","min","max","range","Math","floor","random","CallbackManager","callbacks","nodes","id","event_name","click","submit","input","change","blur","mousedown","mouseup","mouseenter","mouseleave","keydown","drop","load","removeEventListener","CallbackCall","preventDefault","click_event","stopPropagation","HTMLInputElement","HTMLTextAreaElement","HTMLSelectElement","_event","DragEvent","dataTransfer","files","items","file","getAsFile","then","name","getFiles","all","params","dataArray","KeyboardEvent","code","altKey","ctrlKey","shiftKey","metaKey","injects","node","appLocation","tagName","toLocaleLowerCase","href","getAttribute","scrollTo","hydrateLink","HydrationEngine","commands","depth","matched","virtualNodes","createVirtualNodes","hydrate","hydrateNode","head","toFixed","vNodeId","realNode","vNode","realChildren","childNodes","realIndex","skipTextVNodes","childVId","children","childVNode","candidate","isMatch","checkElementMatch","nodeType","Node","TEXT_NODE","checkTextMatch","removeSkippedNodes","claimNode","ELEMENT_NODE","attributes","element","setAttribute","textContent","Element","Comment","j","nodeToRemove","getVNode","CreateNode","toUpperCase","CreateText","parent","InsertBefore","childId","child","refId","ref_id","index","indexOf","splice","SetAttr","MapNodes","initNodes","getRootHead","getRootBody","style","createElement","getRootHtml","documentElement","getAnyOption","getAny","getNodeElement","HTMLElement","getNode","getText","getComment","insertCss","selector","content","createTextNode","appendChild","removeInitNodes","insertBefore","parentNode","childNode","ref_node","addStyles","hasInitNodes","SVG_TAGS","DriverDom","metadata","update","getEnabledHydration","setFocus","runCommand","focus","ev","createNode","createElementNS","setAttr","defaultValue","removeAttr","removeAttribute","removeNode","createText","removeText","updateText","RemoveNode","UpdateText","RemoveAttr","RemoveText","InsertCss","comment","createComment","CreateComment","RemoveComment","CallbackAdd","assertNeverCommand","CallbackRemove","Api","dom","websocket","interval","exec","arg","safeArg","getFetchCache","now","getTimezoneOffset","back","request","method","response2","FetchExecResponse","responseToWasm","toString","fetchExec","FetchExec","WebsocketRegister","WebsocketSendMessage","WebsocketUnregister","TimerSet","TimerClear","LocationGet","LocationCallback","LocationSet","CookieGet","CookieSet","CookieJsonGet","CookieJsonSet","GetEnv","getEnv","Log","arg2","arg3","arg4","debug","GetRandom","executeJsApiCall","JsApiCall","DomBulkUpdate","assertNever","current","Root","domId","RootElement","dom_id","Get","property","Call","args","sanitize","map","proto","getPrototypeOf","prototype","isPlainObject","out","keys","Metadata","attr","getElementById","WasmModule","vertigoEntryFunction","major","minor","vertigo_entry_function","create","wasmModule","vertigo_api","$vertigoApi","mod","panic_message","m","dom_access","responseSize","responseLongPtr","responseBuffer","moduleRun","findAndRunModule","querySelectorAll","forEach","runModule"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"wasm_run.js","sources":["src_js/buffer_cursor.ts","src_js/jsjson.ts","src_js/wasm_init.ts","src_js/api/websocket/event_emiter.ts","src_js/api/websocket/promise.ts","src_js/api/websocket/connection.ts","src_js/api/websocket/websocket.ts","src_js/assert_never.ts","src_js/api/command/fetchExec.ts","src_js/api/command/interval.ts","src_js/api/location/hashrouter.ts","src_js/api/location/historyLocation.ts","src_js/api/location/AppLocation.ts","src_js/api/command/cookies.ts","src_js/api/command/getRandom.ts","src_js/api/command/dom/callbackManager.ts","src_js/api/command/dom/dataTransfer.ts","src_js/api/command/dom/injects.ts","src_js/api/command/dom/hydration.ts","src_js/api/command/dom/map_nodes.ts","src_js/api/command/dom/dom.ts","src_js/api/api.ts","src_js/api/command/fetchCacheGet.ts","src_js/api/metadata.ts","src_js/wasm_module.ts","src_js/index.ts"],"sourcesContent":["///https://javascript.info/arraybuffer-binary-arrays#dataview\n\nconst decoder = new TextDecoder(\"utf-8\");\nconst encoder = new TextEncoder();\n\nexport class BufferCursor {\n private dataView: DataView;\n private pointer: number = 0;\n private ptr: number;\n private size: number;\n\n constructor(\n private getUint8Memory: () => Uint8Array,\n long_ptr: bigint,\n ) {\n this.ptr = Number(long_ptr >> 32n);\n this.size = Number(long_ptr % (2n ** 32n));\n\n this.dataView = new DataView(\n this.getUint8Memory().buffer,\n this.ptr,\n this.size\n );\n }\n\n public getByte(): number {\n const value = this.dataView.getUint8(this.pointer);\n this.pointer += 1;\n return value;\n }\n\n public setByte(byte: number) {\n this.dataView.setUint8(this.pointer, byte);\n this.pointer += 1;\n }\n\n public getU16(): number {\n const value = this.dataView.getUint16(this.pointer);\n this.pointer += 2;\n return value;\n }\n\n public setU16(value: number) {\n this.dataView.setUint16(this.pointer, value);\n this.pointer += 2;\n }\n\n public getU32(): number {\n const value = this.dataView.getUint32(this.pointer);\n this.pointer += 4;\n return value;\n }\n\n public setU32(value: number) {\n this.dataView.setUint32(this.pointer, value);\n this.pointer += 4;\n }\n\n public getI32(): number {\n const value = this.dataView.getInt32(this.pointer);\n this.pointer += 4;\n return value;\n }\n\n public setI32(value: number) {\n this.dataView.setInt32(this.pointer, value);\n this.pointer += 4;\n }\n\n public getU64(): bigint {\n const value = this.dataView.getBigUint64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setU64(value: bigint) {\n this.dataView.setBigUint64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getI64(): bigint {\n const value = this.dataView.getBigInt64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setI64(value: bigint) {\n this.dataView.setBigInt64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getF64(): number {\n const value = this.dataView.getFloat64(this.pointer);\n this.pointer += 8;\n return value;\n }\n\n public setF64(value: number) {\n this.dataView.setFloat64(this.pointer, value);\n this.pointer += 8;\n }\n\n public getBuffer(): Uint8Array {\n const size = this.getU32();\n const result = this\n .getUint8Memory()\n .subarray(\n this.ptr + this.pointer,\n this.ptr + this.pointer + size\n );\n\n this.pointer += size;\n return result;\n }\n\n public setBuffer(buffer: Uint8Array) {\n const size = buffer.length;\n this.setU32(size);\n\n const sub_buffer = this\n .getUint8Memory()\n .subarray(\n this.ptr + this.pointer,\n this.ptr + this.pointer + size\n );\n\n sub_buffer.set(buffer);\n\n this.pointer += size;\n }\n\n public getString(): string {\n return decoder.decode(this.getBuffer());\n }\n\n public setString(value: string) {\n const buffer = encoder.encode(value);\n this.setBuffer(buffer);\n }\n\n public getSavedSize(): number {\n return this.pointer;\n }\n}\n\nexport const getStringSize = (value: string): number => {\n return new TextEncoder().encode(value).length;\n};\n\n","import { BufferCursor } from \"./buffer_cursor\";\n\nconst JsJsonConst = {\n True: 1,\n False: 2,\n Null: 3,\n Undefined: 4,\n String: 5,\n Number: 6,\n List: 7,\n Object: 8,\n Vec: 9,\n} as const;\n\nexport type JsJsonType = boolean | null | undefined | string | number | Uint8Array | Array | { [key: string]: JsJsonType };\n\nexport const jsJsonGetSize = (value: JsJsonType): number => {\n if (value === true || value === false || value === null || value === undefined) {\n return 1;\n }\n\n if (typeof value === 'string') {\n return 1 + 4 + new TextEncoder().encode(value).length;\n }\n\n if (typeof value === 'number') {\n return 1 + 8;\n }\n\n if (value instanceof Uint8Array) {\n return 1 + 4 + value.length;\n }\n\n if (Array.isArray(value)) {\n let sum = 1 + 4;\n for (const item of value) {\n sum += jsJsonGetSize(item);\n }\n return sum;\n }\n\n if (typeof value === 'object' && value !== null) {\n let sum = 1 + 2;\n for (const [key, propertyValue] of Object.entries(value)) {\n sum += 4 + new TextEncoder().encode(key).length;\n sum += jsJsonGetSize(propertyValue);\n }\n return sum;\n }\n\n throw new Error(`jsJsonGetSize: Unknown type ${typeof value}`);\n};\n\nexport const jsJsonDecodeItem = (buffer: BufferCursor): JsJsonType => {\n const typeId = buffer.getByte();\n\n if (typeId === JsJsonConst.True) {\n return true;\n }\n\n if (typeId === JsJsonConst.False) {\n return false;\n }\n\n if (typeId === JsJsonConst.Null) {\n return null;\n }\n\n if (typeId === JsJsonConst.Undefined) {\n return undefined;\n }\n\n if (typeId === JsJsonConst.String) {\n return buffer.getString();\n }\n\n if (typeId === JsJsonConst.Number) {\n return buffer.getF64();\n }\n\n if (typeId === JsJsonConst.List) {\n const count = buffer.getU32();\n const list: Array = [];\n\n for (let i = 0; i < count; i++) {\n list.push(jsJsonDecodeItem(buffer));\n }\n\n return list;\n }\n\n if (typeId === JsJsonConst.Object) {\n const count = buffer.getU16();\n const obj: { [key: string]: JsJsonType } = {};\n\n for (let i = 0; i < count; i++) {\n const key = buffer.getString();\n const value = jsJsonDecodeItem(buffer);\n obj[key] = value;\n }\n\n return obj;\n }\n\n if (typeId === JsJsonConst.Vec) {\n return buffer.getBuffer();\n }\n\n throw new Error(`jsJsonDecodeItem: Unknown type id ${typeId}`);\n};\n\nexport const saveJsJsonToBufferItem = (value: JsJsonType, buffer: BufferCursor): void => {\n if (value === true) {\n buffer.setByte(JsJsonConst.True);\n return;\n }\n\n if (value === false) {\n buffer.setByte(JsJsonConst.False);\n return;\n }\n\n if (value === null) {\n buffer.setByte(JsJsonConst.Null);\n return;\n }\n\n if (value === undefined) {\n buffer.setByte(JsJsonConst.Undefined);\n return;\n }\n\n if (typeof value === 'string') {\n buffer.setByte(JsJsonConst.String);\n buffer.setString(value);\n return;\n }\n\n if (typeof value === 'number') {\n buffer.setByte(JsJsonConst.Number);\n buffer.setF64(value);\n return;\n }\n\n if (value instanceof Uint8Array) {\n buffer.setByte(JsJsonConst.Vec);\n buffer.setBuffer(value);\n return;\n }\n\n if (Array.isArray(value)) {\n buffer.setByte(JsJsonConst.List);\n buffer.setU32(value.length);\n\n for (const item of value) {\n saveJsJsonToBufferItem(item, buffer);\n }\n\n return;\n }\n\n if (typeof value === 'object' && value !== null) {\n const entries = Object.entries(value);\n\n buffer.setByte(JsJsonConst.Object);\n buffer.setU16(entries.length);\n\n for (const [key, propertyValue] of entries) {\n buffer.setString(key);\n saveJsJsonToBufferItem(propertyValue, buffer);\n }\n\n return;\n }\n\n throw new Error(`saveJsJsonToBufferItem: Unknown type ${typeof value}`);\n};\n","import { BufferCursor } from './buffer_cursor';\nimport { jsJsonGetSize, jsJsonDecodeItem, saveJsJsonToBufferItem, JsJsonType } from './jsjson';\n\nexport interface BaseExportType {\n vertigo_export_alloc_block: (size: number) => bigint,\n vertigo_export_free_block: (pointer: bigint) => void,\n vertigo_export_wasm_command: (value_ptr: bigint) => bigint,\n};\n\nexport interface ModuleControllerType {\n exports: ExportType,\n getUint8Memory: () => Uint8Array,\n wasmCommand: (params: JsJsonType) => JsJsonType,\n}\n\nconst fetchModule = async (wasmBinPath: string, imports: Record): Promise => {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n const stream = fetch(wasmBinPath);\n try {\n const module = await WebAssembly.instantiateStreaming(stream, imports);\n return module;\n } catch (err) {\n console.warn(\"`WebAssembly.instantiateStreaming` failed. This could happen if your server does not serve wasm with `application/wasm` MIME type, but check the original error too. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", err);\n }\n }\n\n console.info('fetchModule by WebAssembly.instantiate');\n\n const resp = await fetch(wasmBinPath);\n const binary = await resp.arrayBuffer();\n const module_instance = await WebAssembly.instantiate(binary, imports);\n return module_instance;\n};\n\nexport const wasmInit = async , ExportType extends BaseExportType>(\n wasmBinPath: string,\n imports: { mod: ImportType },\n): Promise> => {\n const module_instance = await fetchModule(wasmBinPath, imports);\n\n let cacheGetUint8Memory: Uint8Array = new Uint8Array(1);\n\n const getUint8Memory = () => {\n if (module_instance.instance.exports.memory instanceof WebAssembly.Memory) {\n if (cacheGetUint8Memory.buffer !== module_instance.instance.exports.memory.buffer) {\n cacheGetUint8Memory = new Uint8Array(module_instance.instance.exports.memory.buffer);\n }\n return cacheGetUint8Memory;\n } else {\n throw Error('Missing memory');\n }\n };\n\n //@ts-expect-error\n const exports: ExportType = module_instance.instance.exports;\n\n const wasmCommand = (value: JsJsonType): JsJsonType => {\n // Serialize JsJson\n const size = jsJsonGetSize(value);\n const long_ptr = exports.vertigo_export_alloc_block(size);\n const buffer = new BufferCursor(getUint8Memory, long_ptr);\n saveJsJsonToBufferItem(value, buffer);\n\n let result_long_ptr = exports.vertigo_export_wasm_command(long_ptr);\n\n // Decode JsJson\n if (result_long_ptr === 0n) {\n return null;\n }\n const resultBuffer = new BufferCursor(getUint8Memory, result_long_ptr);\n const result = jsJsonDecodeItem(resultBuffer);\n exports.vertigo_export_free_block(result_long_ptr);\n\n return result;\n };\n\n\n return {\n exports,\n getUint8Memory,\n wasmCommand: wasmCommand,\n };\n};\n","export class EventEmitter {\n private events: Set<(param: T) => void>;\n\n constructor() {\n this.events = new Set()\n }\n\n on(callback: (param: T) => void) {\n let isActive = true;\n\n const onExec = (param: T) => {\n if (isActive) {\n callback(param);\n }\n };\n\n this.events.add(onExec);\n\n return () => {\n isActive = false;\n this.events.delete(onExec);\n };\n }\n\n trigger(param: T) {\n const eventsCopy = Array.from(this.events.values())\n\n for (const itemCallbackToRun of eventsCopy) {\n try {\n itemCallbackToRun(param);\n } catch (err) {\n console.error(err);\n }\n }\n }\n\n get size(): number {\n return this.events.size;\n }\n}\n","type ResolveFn = (data: T) => void;\ntype RejectFn = (err: unknown) => void;\n\ninterface PromiseResolveReject {\n readonly resolve: (value: T) => void,\n readonly reject: (err: unknown) => void,\n};\n\nconst createPromiseValue = (): [PromiseResolveReject, Promise] => {\n let resolve: ResolveFn | null = null;\n let reject: RejectFn | null = null;\n\n const promise: Promise = new Promise((localResolve: ResolveFn, localReject: RejectFn) => {\n resolve = localResolve;\n reject = localReject;\n });\n\n if (resolve === null) {\n throw Error('createPromiseValue - resolve is null');\n }\n\n if (reject === null) {\n throw Error('createPromiseValue - reject is null');\n }\n\n const promiseValue = {\n resolve,\n reject,\n };\n\n return [promiseValue, promise];\n};\n\nexport class PromiseBoxRace {\n private inner: PromiseResolveReject | null = null;\n readonly promise: Promise;\n\n constructor() {\n const [promiseResolveReject, promise] = createPromiseValue();\n\n this.inner = promiseResolveReject;\n this.promise = promise;\n }\n\n resolve = (value: T) => {\n const promiseResolveReject = this.inner;\n this.inner = null;\n\n if (promiseResolveReject === null) {\n return;\n }\n\n promiseResolveReject.resolve(value);\n }\n\n reject = (err?: unknown) => {\n const promiseResolveReject = this.inner;\n this.inner = null;\n\n if (promiseResolveReject === null) {\n return;\n }\n\n promiseResolveReject.reject(err);\n }\n\n isFulfilled = (): boolean => {\n return this.inner === null;\n }\n}\n","import { EventEmitter } from \"./event_emiter\";\nimport { PromiseBoxRace } from \"./promise\";\n\nconst timeout = async (timeout: number): Promise => {\n return new Promise((resolve: (data: void) => void) => {\n setTimeout(resolve, timeout);\n });\n};\n\n\nconst reconnectDelay = async (label: string, timeout_retry: number): Promise => {\n console.info(`${label} wait ${timeout_retry}ms`);\n await timeout(timeout_retry);\n console.info(`${label} go forth`);\n};\n\nexport type SocketEventType = {\n type: 'message',\n message: string,\n} | {\n type: 'socket',\n socket: SocketConnection\n} | {\n type: 'close',\n};\n\nexport type OnMessageType = (message: SocketEventType) => void;\nexport type UnsubscribeFnType = () => void;\n\ninterface OpenSocketResult {\n socket: Promise,\n done: Promise,\n}\n\nexport interface SocketConnectionController {\n send: (message: string) => void,\n dispose: UnsubscribeFnType\n}\n\nclass LogContext {\n public constructor(private host: string) {}\n public formatLog = (message: string): string => `Socket ${this.host} ==> ${message}`;\n}\nexport class SocketConnection {\n private readonly eventMessage: EventEmitter;\n public readonly close: () => void;\n public readonly send: (message: string) => void;\n\n private constructor(\n close: () => void,\n send: (message: string) => void,\n ) {\n this.eventMessage = new EventEmitter();\n this.close = close;\n this.send = send;\n }\n\n private static connect(\n log: LogContext,\n host: string,\n timeout: number,\n ): OpenSocketResult {\n const result = new PromiseBoxRace();\n const done = new PromiseBoxRace();\n const socket = new WebSocket(host);\n let isClose: boolean = false;\n\n console.info(log.formatLog('starting ...'));\n\n const closeSocket = (): void => {\n if (isClose) {\n return;\n }\n\n console.info(log.formatLog('close'));\n\n isClose = true;\n result.resolve(null);\n done.resolve();\n socket.close();\n };\n\n\n const socketConnection = new SocketConnection(\n closeSocket,\n (message: string) => {\n if (isClose) {\n return;\n }\n socket.send(message);\n }\n );\n\n setTimeout(() => {\n if (result.isFulfilled() === false) {\n console.error(log.formatLog(`timeout (${timeout}ms)`));\n closeSocket();\n }\n }, timeout);\n\n const onOpen = (): void => {\n console.info(log.formatLog('open'));\n result.resolve(socketConnection);\n };\n\n const onError = (error: Event): void => {\n console.error(log.formatLog('error'), error);\n closeSocket();\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (isClose) {\n return;\n }\n\n const dataRaw = event.data;\n\n if (typeof dataRaw === 'string') {\n socketConnection.eventMessage.trigger(dataRaw);\n return;\n }\n\n console.error(log.formatLog('onMessage - expected string'), dataRaw);\n };\n\n socket.addEventListener('open', onOpen);\n socket.addEventListener('error', onError);\n socket.addEventListener('close', closeSocket);\n socket.addEventListener('message', onMessage);\n\n return {\n socket: result.promise,\n done: done.promise\n };\n }\n\n public static startSocket(\n host: string,\n timeout_connection: number,\n timeout_retry: number,\n onMessage: OnMessageType,\n ): SocketConnectionController {\n let isConnect: boolean = true;\n let socketConnection: SocketConnection | null = null;\n\n const log = new LogContext(host);\n\n (async (): Promise => {\n while (isConnect) {\n const openSocketResult = SocketConnection.connect(log, host, timeout_connection);\n\n const socket = await openSocketResult.socket;\n\n if (socket === null) {\n await reconnectDelay(log.formatLog('reconnect after error'), timeout_retry);\n continue;\n }\n\n socketConnection = socket;\n onMessage({\n type: 'socket',\n socket\n });\n\n socket.eventMessage.on(message => {\n onMessage({\n type: 'message',\n message\n });\n });\n\n await openSocketResult.done;\n\n onMessage({\n type: 'close'\n });\n\n if (!isConnect) {\n console.info(log.formatLog('disconnect (1)'));\n return;\n }\n\n await reconnectDelay(log.formatLog('reconnect after close'), timeout_retry);\n }\n\n console.info(log.formatLog('disconnect (2)'));\n })().catch((error) => {\n console.error(error);\n });\n\n return {\n send: (message: string): void => {\n if (socketConnection === null) {\n console.error('send fail - missing connection', message);\n } else {\n socketConnection.send(message);\n }\n },\n dispose: (): void => {\n isConnect = false;\n socketConnection?.close();\n }\n };\n }\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { SocketConnection, SocketConnectionController } from \"./connection\";\n\nconst wireStringToJsJson = (raw: string): JsJsonType => {\n try {\n return JSON.parse(raw) as JsJsonType;\n } catch {\n console.error('Failed to parse websocket message', raw);\n throw Error(raw);\n }\n};\n\nconst jsJsonToWebSocketWire = (value: JsJsonType): string => {\n return JSON.stringify(value);\n};\n\nconst assertNeverMessage = (data: never): never => {\n console.error(data);\n throw Error('unknown message');\n};\n\ntype CommandType = 'Connected' | 'Disconnected' | {\n 'Message': {\n message: JsJsonType,\n }\n}\nconst wasmCallback = (wasm: ModuleControllerType, callbackId: CallbackId, command: CommandType) => {\n wasm.wasmCommand({\n 'Websocket': {\n callback: callbackId,\n message: command,\n }\n })\n};\n\n\nexport class DriverWebsocket {\n private getWasm: () => ModuleControllerType;\n private readonly controllerList: Map;\n private readonly socket: Map;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.controllerList = new Map();\n this.socket = new Map();\n }\n\n public websocket_register_callback = (\n host: string,\n callback_id: CallbackId,\n ) => {\n const wasm = this.getWasm();\n\n let controller = SocketConnection.startSocket(\n host,\n 5000, //timeout connection\n 3000, //timeout reconnection\n (message) => {\n\n if (this.controllerList.has(callback_id) === false) {\n return;\n }\n\n if (message.type === 'socket') {\n this.socket.set(callback_id, message.socket);\n wasmCallback(wasm, callback_id, 'Connected');\n return;\n }\n\n if (message.type === 'message') {\n wasmCallback(wasm, callback_id, {\n 'Message': {\n message: wireStringToJsJson(message.message)\n }\n });\n return;\n }\n\n if (message.type === 'close') {\n this.socket.delete(callback_id);\n wasmCallback(wasm, callback_id, 'Disconnected');\n return;\n }\n\n return assertNeverMessage(message);\n }\n );\n\n this.controllerList.set(callback_id, controller);\n }\n\n public websocket_unregister_callback = (callback_id: CallbackId) => {\n const controller = this.controllerList.get(callback_id);\n\n if (controller === undefined) {\n console.error('Expected controller');\n return;\n }\n\n controller.dispose();\n this.controllerList.delete(callback_id);\n }\n\n public websocket_send_message = (\n callback_id: CallbackId,\n message: JsJsonType,\n ) => {\n const socket = this.socket.get(callback_id);\n\n if (socket === undefined) {\n console.error(`Missing socket connection for callback_id=${callback_id}`);\n } else {\n socket.send(jsJsonToWebSocketWire(message));\n }\n }\n}\n","\nexport const assertNever = (_value: never) => {\n throw Error(\"assert never\");\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\n\nexport interface FetchRequestType {\n method: string,\n url: string,\n headers: Array<{ k: string, v: string }>,\n body: 'None' | {\n Data: {\n data: JsJsonType\n }\n }\n}\n\ntype FetchResponseType = {\n Ok: {\n status: number,\n response: {\n Text: string\n } | {\n Json: JsJsonType,\n }\n }\n} | {\n Err: {\n message: string,\n }\n};\n\nconst getHeaders = (headers: Array<{ k: string, v: string }>): Record => {\n const result: Record = {};\n\n for (const { k, v } of headers) {\n result[k] = v;\n }\n\n return result;\n};\n\nconst getBodyString = (body: FetchRequestType['body']): string | undefined => {\n if (body === 'None') {\n return undefined;\n }\n\n return JSON.stringify(body.Data.data);\n};\n\n// 204/205 carry no body, and any other response with an empty body\n// would crash response.json(). Treat both as Json: null so the caller\n// sees a successful response with the real status code.\nexport const parseJsonBody = (bodyText: string): JsJsonType | null =>\n bodyText.length === 0 ? null : JSON.parse(bodyText);\n\nconst processResponse = async (response: Response): Promise => {\n const status = response.status;\n const contentType = response.headers.get(\"Content-Type\");\n\n try {\n if (contentType?.startsWith('text/plain;')) {\n return {\n Ok: {\n status,\n response: {\n Text: await response.text(),\n }\n }\n }\n }\n\n const json = parseJsonBody(await response.text());\n\n return {\n Ok: {\n status,\n response: {\n Json: json\n }\n }\n };\n } catch (error) {\n return {\n Err: {\n message: String(error),\n }\n };\n }\n};\n\n\nexport const fetchExec = async (\n getWasm: () => ModuleControllerType,\n callback_id: CallbackId,\n request: FetchRequestType\n): Promise => {\n const wasm = getWasm();\n\n try {\n const response = await fetch(request.url, {\n method: request.method,\n headers: getHeaders(request.headers),\n body: getBodyString(request.body),\n });\n\n const response2 = await processResponse(response);\n\n wasm.wasmCommand({\n 'FetchExecResponse': {\n response: response2,\n callback: callback_id,\n }\n });\n\n } catch (err) {\n console.error('fetch error (1)', err);\n const responseMessage = new String(err).toString();\n\n const responseToWasm: FetchResponseType = {\n 'Err': {\n message: responseMessage\n }\n };\n\n wasm.wasmCommand({\n 'FetchExecResponse': {\n response: responseToWasm,\n callback: callback_id,\n }\n });\n }\n};\n\n\n","import { CallbackId } from \"../types\";\nimport { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\n\ntype TimerResourceId = ReturnType;\n\ninterface TimerId {\n kind: 'Interval' | 'Timeout',\n timerId: TimerResourceId,\n}\n\nexport class Interval {\n private readonly getWasm: () => ModuleControllerType;\n private readonly data: Map;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.data = new Map();\n }\n\n timerSet = (callback: CallbackId, duration: number, kind: 'Interval' | 'Timeout') => {\n switch (kind) {\n case 'Interval': {\n const timerId = setInterval(() => {\n this.getWasm().wasmCommand({\n 'TimerCall': {\n callback,\n },\n })\n }, duration);\n\n this.data.set(callback, {\n kind: 'Interval',\n timerId,\n });\n break;\n }\n case 'Timeout': {\n const timerId = setTimeout(() => {\n this.getWasm().wasmCommand({\n 'TimerCall': {\n callback,\n },\n })\n }, duration);\n\n this.data.set(callback, {\n kind: 'Timeout',\n timerId,\n });\n break;\n }\n }\n }\n\n timerClear = (callback: CallbackId) => {\n const timerResource = this.data.get(callback);\n\n if (timerResource === undefined) {\n throw Error('panic');\n }\n\n switch (timerResource.kind) {\n case 'Interval': {\n clearInterval(timerResource.timerId);\n break;\n }\n case 'Timeout': {\n clearTimeout(timerResource.timerId);\n break;\n }\n }\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { LocationCommonType } from \"./types\";\n\nexport class HashRouter implements LocationCommonType {\n private getWasm: () => ModuleControllerType;\n private callback: Map void>;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callback = new Map();\n\n window.addEventListener(\"hashchange\", this.trigger);\n }\n\n private trigger = () => {\n for (const callback of Array.from(this.callback.values())) {\n callback();\n }\n }\n\n public add = (callback_id: CallbackId) => {\n this.callback.set(callback_id, () => {\n this.getWasm().wasmCommand({\n LocationCall: {\n callback: callback_id,\n value: this.get(),\n }\n });\n });\n }\n\n public remove = (callback_id: CallbackId) => {\n this.callback.delete(callback_id);\n }\n\n public push = (new_hash: string) => {\n if (this.get() === new_hash) {\n return;\n }\n\n location.hash = new_hash;\n this.trigger();\n }\n\n public replace = (new_hash: string) => {\n if (this.get() === new_hash) {\n return;\n }\n\n history.replaceState(null, '', `#${new_hash}`);\n }\n\n public get(): string {\n return decodeURIComponent(location.hash.substr(1));\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { LocationCommonType } from \"./types\";\n\nexport class HistoryLocation implements LocationCommonType {\n private getWasm: () => ModuleControllerType;\n private callback: Map void>;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callback = new Map();\n\n window.addEventListener(\"popstate\", this.trigger);\n }\n\n private trigger = () => {\n for (const callback of Array.from(this.callback.values())) {\n callback();\n }\n }\n\n public add = (callback_id: CallbackId) => {\n this.callback.set(callback_id, () => {\n this.getWasm().wasmCommand({\n LocationCall: {\n callback: callback_id,\n value: this.get(),\n }\n });\n });\n }\n\n public remove = (callback_id: CallbackId) => {\n this.callback.delete(callback_id);\n }\n\n public push = (url: string) => {\n if (this.get() === url) {\n return;\n }\n\n window.history.pushState(null, '', url);\n this.trigger();\n }\n\n public replace = (url: string) => {\n if (this.get() === url) {\n return;\n }\n\n window.history.replaceState(null, '', url);\n this.trigger();\n }\n\n public get(): string {\n return window.location.pathname + window.location.search + window.location.hash;\n }\n}\n","import { ModuleControllerType } from \"../../wasm_init\";\nimport { ExportType } from \"../../wasm_module\";\nimport { CallbackId } from \"../types\";\nimport { HashRouter } from \"./hashrouter\";\nimport { HistoryLocation } from \"./historyLocation\";\nimport { LocationCommonType } from \"./types\";\n\ntype LocationTarget = 'Hash' | 'History';\n\nexport class AppLocation {\n private readonly locations: Record;\n\n constructor(getWasm: () => ModuleControllerType) {\n this.locations = {\n Hash: new HashRouter(getWasm),\n History: new HistoryLocation(getWasm),\n };\n }\n\n callback = (target: LocationTarget, mode: 'Add' | 'Remove', callbackId: CallbackId) => {\n switch (mode) {\n case 'Add': {\n this.locations[target].add(callbackId);\n return;\n }\n case 'Remove': {\n this.locations[target].remove(callbackId);\n return;\n }\n }\n }\n\n set = (target: LocationTarget, mode: 'Push' | 'Replace', newValue: string) => {\n switch (mode) {\n case 'Push': {\n this.locations[target].push(newValue);\n return;\n }\n case 'Replace': {\n this.locations[target].replace(newValue);\n return;\n }\n }\n }\n\n get = (target: LocationTarget): string => {\n return this.locations[target].get();\n }\n}","import { JsJsonType } from \"../../jsjson\";\n\nexport class Cookies {\n public get = (cname: string): string => {\n for (const cookie of document.cookie.split(';')) {\n if (cookie === \"\") continue;\n\n const cookieChunk = cookie.trim().split('=');\n\n if (cookieChunk.length !== 2) {\n console.warn(`Cookies.get: Incorrect number of cookieChunk => ${cookieChunk.length} in ${cookie}`);\n continue;\n }\n\n const cookieName = cookieChunk[0];\n const cookieValue = cookieChunk[1];\n\n if (cookieName === undefined || cookieValue === undefined) {\n console.warn(`Cookies.get: Broken cookie part => ${cookie}`);\n continue;\n }\n\n if (cookieName === cname) {\n return decodeURIComponent(cookieValue);\n }\n }\n\n return '';\n }\n\n public getJson = (cname: string): JsJsonType => {\n let cvalue_str = this.get(cname);\n\n if (cvalue_str.length !== 0) {\n try {\n let cookie_value = JSON.parse(cvalue_str);\n return cookie_value;\n } catch (e) {\n console.error!(\"Error deserializing cookie\", e);\n }\n }\n return null\n }\n\n public set = (\n cname: string,\n cvalue: string,\n expires_in: number,\n ) => {\n const cvalueEncoded = cvalue == null ? \"\" : encodeURIComponent(cvalue);\n\n const d = new Date();\n d.setTime(d.getTime() + (expires_in * 1000));\n let expires = \"expires=\" + d.toUTCString();\n\n document.cookie = `${cname}=${cvalueEncoded};${expires};path=/; samesite=Strict`;\n }\n\n public setJson = (\n cname: string,\n cvalue: JsJsonType,\n expires_in: number,\n ) => {\n let cvalue_str = JSON.stringify(cvalue);\n\n this.set(cname, cvalue_str, expires_in);\n }\n}\n","export const getRandom = (min: number, max: number): number => {\n const range = max - min + 1;\n let result = Math.floor(Math.random() * range);\n return min + result;\n};\n\n","import { ExportType } from \"../../../wasm_module\";\nimport { getFiles } from \"./dataTransfer\";\nimport { JsJsonType } from \"../../../jsjson\";\nimport { ModuleControllerType } from \"../../../wasm_init\";\nimport { MapNodes } from \"./map_nodes\";\nimport { CallbackId } from \"../../types\";\n\nexport class CallbackManager {\n private readonly getWasm: () => ModuleControllerType;\n private callbacks: Map void>;\n\n public constructor(getWasm: () => ModuleControllerType) {\n this.getWasm = getWasm;\n this.callbacks = new Map();\n }\n\n public add(nodes: MapNodes, id: number, event_name: string, callback_id: CallbackId) {\n const callback = (event: Event) => {\n if (event_name === 'click') {\n return this.click(event, callback_id);\n }\n\n if (event_name === 'submit') {\n return this.submit(event, callback_id);\n }\n\n if (event_name === 'input') {\n return this.input(event, callback_id);\n }\n\n if (event_name === 'change') {\n return this.change(event, callback_id);\n }\n\n if (event_name === 'blur') {\n return this.blur(event, callback_id);\n }\n\n if (event_name === 'mousedown') {\n return this.mousedown(event, callback_id);\n }\n\n if (event_name === 'mouseup') {\n return this.mouseup(event, callback_id);\n }\n\n if (event_name === 'mouseenter') {\n return this.mouseenter(event, callback_id);\n }\n\n if (event_name === 'mouseleave') {\n return this.mouseleave(event, callback_id);\n }\n\n if (event_name === 'keydown') {\n return this.keydown(event, callback_id);\n }\n\n if (event_name === 'hook_keydown') {\n return this.keydown(event, callback_id);\n }\n\n if (event_name === 'drop') {\n return this.drop(event, callback_id);\n }\n\n if (event_name === 'load') {\n return this.load(event, callback_id);\n }\n\n if (event_name === 'change_file') {\n return this.changeFile(event, callback_id);\n }\n\n console.error(`No support for the event ${event_name}`);\n };\n\n if (this.callbacks.has(callback_id)) {\n console.error(`There was already a callback added with the callback_id=${callback_id}`);\n return;\n }\n\n this.callbacks.set(callback_id, callback);\n\n if (event_name === 'hook_keydown') {\n document.addEventListener('keydown', callback, false);\n } else {\n const node = nodes.get('callback_add', id);\n const domEventName = event_name === 'change_file' ? 'change' : event_name;\n node.addEventListener(domEventName, callback, false);\n }\n }\n\n public remove(nodes: MapNodes, id: number, event_name: string, callback_id: CallbackId) {\n const callback = this.callbacks.get(callback_id);\n this.callbacks.delete(callback_id);\n\n if (callback === undefined) {\n console.error(`The callback is missing with the id=${callback_id}`);\n return;\n }\n\n if (event_name === 'hook_keydown') {\n document.removeEventListener('keydown', callback);\n } else {\n const node = nodes.get('callback_remove', id);\n const domEventName = event_name === 'change_file' ? 'change' : event_name;\n node.removeEventListener(domEventName, callback);\n }\n }\n\n private wasmCallback(callback_id: CallbackId, value: JsJsonType): JsJsonType {\n return this.getWasm().wasmCommand({\n CallbackCall: {\n callback_id,\n value: value\n }\n });\n }\n\n private click(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n let click_event = this.wasmCallback(callback_id, undefined);\n\n // Check if click_event is an object (JsJson Object type)\n if (click_event !== null && typeof click_event === 'object' && !Array.isArray(click_event)) {\n if ('stop_propagation' in click_event && click_event['stop_propagation'] === true) {\n event.stopPropagation();\n }\n if ('prevent_default' in click_event && click_event['prevent_default'] === true) {\n event.preventDefault();\n }\n }\n }\n\n private submit(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n this.wasmCallback(callback_id, undefined);\n }\n\n private input(event: Event, callback_id: CallbackId) {\n const target = event.target;\n\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n this.wasmCallback(callback_id, target.value);\n return;\n }\n\n console.warn('event input ignore', target);\n }\n\n private change(event: Event, callback_id: CallbackId) {\n const target = event.target;\n\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement) {\n this.wasmCallback(callback_id, target.value);\n return;\n }\n\n console.warn('event input ignore', target);\n }\n\n private changeFile(event: Event, callback_id: CallbackId) {\n const target = event.target;\n\n if (target instanceof HTMLInputElement && target.files !== null && target.files.length > 0) {\n const promises: Array> = [];\n\n for (let i = 0; i < target.files.length; i++) {\n const file = target.files[i];\n if (file !== undefined) {\n promises.push(\n file.arrayBuffer().then((buf) => ({\n name: file.name,\n data: new Uint8Array(buf),\n }))\n );\n }\n }\n\n if (promises.length > 0) {\n Promise.all(promises).then((files) => {\n const params = [];\n for (const f of files) {\n params.push([f.name, Array.from(f.data)]);\n }\n this.wasmCallback(callback_id, [params]);\n }).catch((err) => console.error('changeFile ->', err));\n }\n\n target.value = '';\n return;\n }\n\n console.warn('changeFile: not a file input or no files', target);\n }\n\n private blur(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private mousedown(event: Event, callback_id: CallbackId) {\n if (this.wasmCallback(callback_id, undefined)) {\n event.preventDefault()\n }\n }\n\n private mouseup(event: Event, callback_id: CallbackId) {\n if (this.wasmCallback(callback_id, undefined)) {\n event.preventDefault()\n }\n }\n\n private mouseenter(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private mouseleave(_event: Event, callback_id: CallbackId) {\n this.wasmCallback(callback_id, undefined);\n }\n\n private drop(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n\n if (event instanceof DragEvent) {\n if (event.dataTransfer === null) {\n console.error('dom -> drop -> dataTransfer null');\n } else {\n const files = getFiles(event.dataTransfer.items);\n\n if (files.length) {\n Promise.all(files).then((files) => {\n const params = [];\n\n for (const file of files) {\n // Convert Uint8Array to array of numbers for JsJson\n const dataArray = Array.from(file.data);\n params.push([\n file.name,\n dataArray,\n ]);\n }\n\n this.wasmCallback(callback_id, [params]);\n }).catch((error) => {\n console.error('callback_drop -> promise.all -> ', error);\n });\n } else {\n console.error('No files to send');\n }\n }\n } else {\n console.warn('event drop ignore', event);\n }\n }\n\n private keydown(event: Event, callback_id: CallbackId) {\n if (event instanceof KeyboardEvent) {\n const result = this.wasmCallback(callback_id, [\n event.key,\n event.code,\n event.altKey,\n event.ctrlKey,\n event.shiftKey,\n event.metaKey\n ]);\n\n if (result === true) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n return;\n }\n\n console.warn('keydown ignore', event);\n }\n\n private load(event: Event, callback_id: CallbackId) {\n event.preventDefault();\n this.wasmCallback(callback_id, undefined);\n }\n\n}\n","interface FileItemType {\n name: string,\n data: Uint8Array,\n}\n\nexport function getFiles(items: DataTransferItemList): Array> {\n const files: Array> = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n\n if (item === undefined) {\n console.error('dom -> drop -> item - undefined');\n } else {\n const file = item.getAsFile();\n\n if (file === null) {\n console.error(`dom -> drop -> index:${i} -> It's not a file`);\n } else {\n files.push(file\n .arrayBuffer()\n .then((data): FileItemType => ({\n name: file.name,\n data: new Uint8Array(data),\n }))\n );\n }\n }\n }\n return files;\n}\n","import { AppLocation } from \"../../location/AppLocation\";\n\nexport function injects(node: Element, appLocation: AppLocation) {\n if (node.tagName.toLocaleLowerCase() === 'a') {\n hydrateLink(node, appLocation);\n }\n}\n\nfunction hydrateLink(node: Element, appLocation: AppLocation) {\n node.addEventListener('click', (e) => {\n let href = node.getAttribute('href');\n if (href === null) {\n return;\n }\n\n if (href.startsWith('#') || href.startsWith('http://') || href.startsWith('https://') || href.startsWith('//')) {\n return;\n }\n\n e.preventDefault();\n appLocation.set('History', 'Push', href);\n window.scrollTo(0, 0);\n })\n}\n","import { AppLocation } from \"../../location/AppLocation\";\nimport { CommandType } from \"./dom\";\nimport { injects } from \"./injects\";\nimport { MapNodes } from \"./map_nodes\";\n\ninterface VirtualNode {\n id: number;\n name?: string;\n value?: string;\n attributes?: Map;\n children: Array;\n}\n\nexport const hydrate = (commands: Array, nodes: MapNodes, appLocation: AppLocation) => {\n const engine = new HydrationEngine(commands, nodes, appLocation);\n engine.hydrate();\n};\n\nclass HydrationEngine {\n private nodes: MapNodes;\n private appLocation: AppLocation;\n private virtualNodes: Map;\n private depth: number = -1;\n private matched: number = 0;\n\n constructor(commands: Array, nodes: MapNodes, appLocation: AppLocation) {\n this.nodes = nodes;\n this.appLocation = appLocation;\n this.virtualNodes = this.createVirtualNodes(commands);\n }\n\n public hydrate() {\n // Start hydration from Body (id=3) and Head (id=2) if needed\n // Usually we care about Body.\n const bodyVNode = this.virtualNodes.get(3);\n if (bodyVNode) {\n this.hydrateNode(3, document.body);\n }\n\n const headVNode = this.virtualNodes.get(2);\n if (headVNode) {\n this.hydrateNode(2, document.head);\n }\n\n console.log(\n \"Hydration complete,\",\n (this.matched * 100 / this.virtualNodes.size).toFixed(2),\n \" % vnodes matched.\",\n );\n };\n\n // Traverse and Match\n private hydrateNode(vNodeId: number, realNode: Node) {\n const vNode = this.virtualNodes.get(vNodeId);\n if (!vNode) return;\n\n // console.log(`Hydration ${this.depth + 1}: Hydrate node`, vNode, realNode);\n\n // Match children\n const realChildren = Array.from(realNode.childNodes);\n let realIndex = 0;\n this.depth++;\n let skipTextVNodes = false;\n\n for (const childVId of vNode.children) {\n const childVNode = this.virtualNodes.get(childVId);\n if (!childVNode) continue;\n\n // If we are in group of text vnodes, skip them until we find a non-text vnode.\n if (skipTextVNodes && childVNode.value !== undefined) {\n // Deliberately skipped vNodes should be counted as matched\n this.matched++;\n continue;\n } else {\n skipTextVNodes = false;\n }\n\n // Find a matching real node starting from realIndex\n for (let i = realIndex; i < realChildren.length; i++) {\n const candidate = realChildren[i];\n if (!candidate) continue;\n\n let isMatch = false;\n if (childVNode.name) {\n // Element\n isMatch = this.checkElementMatch(candidate, childVNode);\n } else if (childVNode.value !== undefined) {\n // Text\n if (candidate.nodeType === Node.TEXT_NODE) {\n this.checkTextMatch(candidate, childVNode);\n isMatch = true;\n // Start skipping eventual group of text vnodes\n // as they were probably merged into one on SSR side.\n skipTextVNodes = true;\n } else {\n console.error(`Hydration ${this.depth}: Text node mismatch`, childVNode, candidate);\n }\n }\n\n if (isMatch) {\n this.removeSkippedNodes(realChildren, realIndex, i);\n this.claimNode(candidate, childVId);\n this.matched++;\n\n // Recurse if element\n if (childVNode.name) {\n this.hydrateNode(childVId, candidate);\n }\n\n // Advance realIndex to i + 1 (consume this node)\n realIndex = i + 1;\n break;\n }\n }\n }\n\n // Remove remaining real nodes\n this.removeSkippedNodes(realChildren, realIndex, realChildren.length);\n this.depth--;\n };\n\n private checkElementMatch(candidate: Node, childVNode: VirtualNode) {\n let isMatch = false;\n if (candidate.nodeType === Node.ELEMENT_NODE && (candidate as Element).tagName === childVNode.name) {\n isMatch = true;\n // Check attributes\n if (childVNode.attributes) {\n const element = candidate as Element;\n for (const [name, value] of childVNode.attributes) {\n if (element.getAttribute(name) !== value) {\n // console.info(`Hydration ${depth}: Reseting attribute`, element.getAttribute(name), \" !== \", value);\n element.setAttribute(name, value);\n }\n }\n }\n }\n return isMatch;\n };\n\n private checkTextMatch(candidate: Node, childVNode: VirtualNode) {\n // For text nodes, we might want to be lenient or exact.\n // Let's assume exact match or at least non-empty.\n // Often text nodes might have whitespace differences.\n // For now, let's just check if it's a text node.\n // Checking content might be safer.\n if (candidate.textContent?.replace('\\n', ' ').trim() !== childVNode.value?.replace('\\n', ' ').trim()) {\n // console.debug(`Hydration ${depth}: Joint text`, childVNode, candidate);\n candidate.textContent = childVNode.value || \"\";\n }\n };\n\n // Claim node and run injects\n private claimNode(candidate: Node, childVId: number) {\n if (candidate instanceof Element || candidate instanceof Comment || candidate instanceof Text) {\n this.nodes.claimNode(childVId, candidate);\n\n // Run injects\n if (candidate instanceof Element) {\n injects(candidate, this.appLocation);\n }\n }\n }\n\n // Remove nodes skipped during matching\n private removeSkippedNodes(realChildren: ChildNode[], realIndex: number, i: number) {\n for (let j = realIndex; j < i; j++) {\n const nodeToRemove = realChildren[j];\n if (nodeToRemove) {\n if (this.depth !== 0 && nodeToRemove.nodeType !== Node.TEXT_NODE) {\n console.warn(`Hydration ${this.depth}: Removing node`, nodeToRemove);\n }\n nodeToRemove.remove();\n }\n }\n }\n\n private createVirtualNodes(commands: Array): Map {\n const virtualNodes = new Map();\n\n // Helper to get or create a virtual node\n const getVNode = (id: number): VirtualNode => {\n let node = virtualNodes.get(id);\n if (!node) {\n node = { id, children: [] };\n virtualNodes.set(id, node);\n }\n return node;\n };\n\n // Build Virtual Tree from Commands\n for (const command of commands) {\n if ('CreateNode' in command) {\n const node = getVNode(command.CreateNode.id);\n node.name = command.CreateNode.name.toUpperCase();\n } else if ('CreateText' in command) {\n const node = getVNode(command.CreateText.id);\n node.value = command.CreateText.value;\n } else if ('InsertBefore' in command) {\n const parent = getVNode(command.InsertBefore.parent);\n const childId = command.InsertBefore.child;\n const refId = command.InsertBefore.ref_id;\n\n if (refId === null || refId === undefined) {\n parent.children.push(childId);\n } else {\n const index = parent.children.indexOf(refId);\n if (index !== -1) {\n parent.children.splice(index, 0, childId);\n } else {\n console.warn(`Hydration: ref_id ${refId} not found in parent ${command.InsertBefore.parent}`);\n parent.children.push(childId);\n }\n }\n } else if ('SetAttr' in command) {\n const node = getVNode(command.SetAttr.id);\n if (!node.attributes) {\n node.attributes = new Map();\n }\n node.attributes.set(command.SetAttr.name, command.SetAttr.value);\n }\n }\n\n return virtualNodes;\n };\n}\n","type NodeType = Element | Comment | Text;\nexport class MapNodes {\n private data: Map;\n private initNodes: Array | null;\n private style: HTMLStyleElement;\n\n constructor() {\n this.data = new Map();\n\n this.initNodes = [\n ...this.getRootHead().childNodes,\n ...this.getRootBody().childNodes,\n ];\n\n this.style = document.createElement('style');\n }\n\n private getRootHtml(): Element {\n return document.documentElement;\n }\n\n private getRootHead(): Element {\n return document.head;\n }\n\n private getRootBody(): Element {\n return document.body;\n }\n\n public set(id: number, value: NodeType) {\n if (id === 1 || id === 2 || id === 3) {\n //ignore\n } else {\n this.data.set(id, value);\n }\n }\n\n public getAnyOption(id: number): NodeType | undefined {\n if (id === 1) {\n return this.getRootHtml();\n }\n\n if (id === 2) {\n return this.getRootHead();\n }\n\n if (id === 3) {\n return this.getRootBody();\n }\n\n return this.data.get(id);\n }\n\n public getAny(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n\n if (item === undefined) {\n throw Error(`${label} -> item not found=${id}`);\n }\n\n return item;\n }\n\n public get(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n\n if (item === undefined) {\n throw new Error(`${label}->get: Item id not found = ${id}`);\n }\n return item;\n }\n\n public getNodeElement(label: string, id: number): HTMLElement {\n const node = this.get(label, id);\n if (node instanceof HTMLElement) {\n return node;\n } else {\n throw Error(`Expected id=${id} as HTMLElement`);\n }\n }\n\n public getNode(label: string, id: number): Element {\n const node = this.get(label, id);\n if (node instanceof Element) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Element`);\n }\n }\n\n public getText(label: string, id: number): Text {\n const node = this.get(label, id);\n if (node instanceof Text) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Text`);\n }\n }\n\n public getComment(label: string, id: number): Comment {\n const node = this.get(label, id);\n if (node instanceof Comment) {\n return node;\n } else {\n throw Error(`Expected id=${id} as Comment`);\n }\n }\n\n public delete(label: string, id: number): NodeType {\n const item = this.getAnyOption(id);\n this.data.delete(id);\n\n if (item === undefined) {\n throw new Error(`${label}->delete: Item id not found = ${id}`);\n }\n\n return item;\n }\n\n public insertCss(selector: string | null, value: string) {\n if (selector !== null) {\n // Add autocss styles\n const content = document.createTextNode(`\\n${selector} { ${value} }`);\n this.style.appendChild(content);\n } else {\n // Add bundle (i.e. a tailwind bundle)\n const content = document.createTextNode(`\\n${value}`);\n this.style.appendChild(content);\n }\n }\n\n public removeInitNodes() {\n const initNodes = this.initNodes;\n this.initNodes = null;\n\n if (initNodes === null) {\n return;\n }\n\n for (const node of initNodes) {\n node.remove();\n }\n }\n\n public insertBefore(parent: number, child: number, ref_id: number | null | undefined) {\n const parentNode = this.get(\"insert_before\", parent);\n const childNode = this.getAny(\"insert_before child\", child);\n\n if (ref_id === null || ref_id === undefined) {\n parentNode.insertBefore(childNode, null);\n } else {\n const ref_node = this.getAny('insert_before ref', ref_id);\n parentNode.insertBefore(childNode, ref_node);\n }\n }\n\n public addStyles() {\n this.getRootHead().appendChild(this.style);\n }\n\n public hasInitNodes(): boolean {\n return this.initNodes !== null;\n }\n\n public claimNode(id: number, node: NodeType) {\n this.data.set(id, node);\n\n if (this.initNodes) {\n const index = this.initNodes.indexOf(node as ChildNode);\n if (index > -1) {\n this.initNodes.splice(index, 1);\n }\n }\n }\n\n public has(id: number): boolean {\n // Root nodes always exist in real DOM\n if (id === 1 || id === 2 || id === 3) {\n return true;\n }\n\n return this.data.has(id);\n }\n}\n","import { AppLocation } from \"../../location/AppLocation\";\nimport { CallbackManager } from \"./callbackManager\";\nimport { ExportType } from \"../../../wasm_module\";\nimport { hydrate } from \"./hydration\";\nimport { injects } from \"./injects\";\nimport { MapNodes } from \"./map_nodes\";\nimport { ModuleControllerType } from \"../../../wasm_init\";\nimport { Metadata } from \"../../metadata\";\n\n// Workaround, remove when https://github.com/vertigo-web/vertigo/issues/539 is done.\nconst SVG_TAGS = new Set([\n \"animate\", \"animateMotion\", \"animateTransform\", \"circle\", \"clipPath\", \"defs\",\n \"desc\", \"discard\", \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\",\n \"feComposite\", \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\",\n \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \"feFuncG\",\n \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \"feMorphology\",\n \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \"feSpotLight\", \"feTile\",\n \"feTurbulence\", \"filter\", \"foreignObject\", \"g\", \"hatch\", \"hatchpath\", \"image\",\n \"line\", \"linearGradient\", \"marker\", \"mask\", \"metadata\", \"mpath\", \"path\", \"pattern\",\n \"polygon\", \"polyline\", \"radialGradient\", \"rect\", \"set\", \"stop\", \"svg\", \"switch\",\n \"symbol\", \"text\", \"textPath\", \"tspan\", \"use\", \"view\",\n \"svg:a\", \"svg:title\", \"svg:desc\", \"svg:script\", \"svg:style\"\n]);\n\nconst createElement = (name: string): Element => {\n if (SVG_TAGS.has(name)) {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", name.replace(\"svg:\", \"\"));\n } else {\n return document.createElement(name);\n }\n}\n\nexport type CommandType = {\n CreateNode: {\n id: number,\n name: string,\n }\n} | {\n CreateText: {\n id: number,\n value: string\n }\n} | {\n UpdateText: {\n id: number,\n value: string\n }\n} | {\n SetAttr: {\n id: number,\n name: string,\n value: string\n }\n} | {\n RemoveAttr: {\n id: number,\n name: string\n }\n} | {\n RemoveNode: {\n id: number,\n }\n} | {\n RemoveText: {\n id: number,\n }\n} | {\n InsertBefore: {\n parent: number,\n child: number,\n ref_id: number | null,\n }\n} | {\n InsertCss: {\n selector: string | null,\n value: string\n }\n} | {\n CreateComment: {\n id: number,\n value: string\n }\n} | {\n RemoveComment: {\n id: number,\n }\n} | {\n CallbackAdd: {\n id: number,\n event_name: string,\n callback_id: number,\n }\n} | {\n CallbackRemove: {\n id: number,\n event_name: string,\n callback_id: number,\n }\n};\n\nconst assertNeverCommand = (data: never): never => {\n console.error(data);\n throw Error('unknown command');\n};\n\nexport class DriverDom {\n private appLocation: AppLocation;\n public readonly nodes: MapNodes;\n private readonly callbacks: CallbackManager;\n\n public constructor(private readonly metadata: Metadata, appLocation: AppLocation, getWasm: () => ModuleControllerType) {\n this.appLocation = appLocation;\n this.nodes = new MapNodes();\n this.callbacks = new CallbackManager(getWasm);\n\n document.addEventListener('dragover', (ev): void => {\n // console.log('File(s) in drop zone');\n ev.preventDefault();\n });\n }\n\n public update = (commands: Array) => {\n if (this.nodes.hasInitNodes() && this.metadata.getEnabledHydration()) {\n hydrate(commands, this.nodes, this.appLocation);\n }\n\n const setFocus: Set = new Set();\n\n for (const command of commands) {\n try {\n this.runCommand(command);\n } catch (error) {\n console.error('bulk_update - item', error, command);\n }\n\n if ('SetAttr' in command && command.SetAttr.name.toLocaleLowerCase() === 'autofocus') {\n setFocus.add(command.SetAttr.id);\n }\n }\n\n if (setFocus.size > 0) {\n setTimeout(() => {\n for (const id of setFocus) {\n const node = this.nodes.getNodeElement(`set focus ${id}`, id);\n node.focus();\n }\n }, 0);\n }\n\n this.nodes.removeInitNodes();\n\n // Make sure that the client-side generated styles are always the last element of the head\n this.nodes.addStyles();\n }\n\n private createNode(id: number, name: string) {\n // Root nodes (html/head/body) already exist in the real DOM\n if (id === 1 || id === 2 || id === 3) {\n return;\n }\n\n if (this.nodes.has(id)) {\n return;\n }\n\n const node = createElement(name);\n this.nodes.set(id, node);\n\n injects(node, this.appLocation);\n }\n\n private setAttr(id: number, name: string, value: string) {\n const node = this.nodes.getNode(\"set_attribute\", id);\n node.setAttribute(name, value);\n\n if (name == \"value\") {\n if (node instanceof HTMLInputElement) {\n node.value = value;\n return;\n }\n\n if (node instanceof HTMLTextAreaElement) {\n node.value = value;\n node.defaultValue = value;\n return;\n }\n }\n }\n\n private removeAttr(id: number, name: string) {\n const node = this.nodes.getNode(\"remove_attribute\", id);\n node.removeAttribute(name);\n\n if (name == \"value\") {\n if (node instanceof HTMLInputElement) {\n node.value = \"\";\n return;\n }\n\n if (node instanceof HTMLTextAreaElement) {\n node.value = \"\";\n node.defaultValue = \"\";\n return;\n }\n }\n }\n\n private removeNode(id: number) {\n // Never remove real document roots\n if (id === 1 || id === 2 || id === 3) {\n return;\n }\n\n const node = this.nodes.delete(\"remove_node\", id);\n node.remove();\n }\n\n private createText(id: number, value: string) {\n if (this.nodes.has(id)) {\n return;\n }\n\n const text = document.createTextNode(value);\n this.nodes.set(id, text);\n }\n\n private removeText(id: number) {\n const text = this.nodes.delete(\"remove_node\", id);\n text.remove();\n }\n\n private updateText(id: number, value: string) {\n const text = this.nodes.getText(\"set_attribute\", id);\n text.textContent = value;\n }\n\n private runCommand(command: CommandType) {\n if ('RemoveNode' in command) {\n this.removeNode(command.RemoveNode.id);\n return;\n }\n\n if ('InsertBefore' in command) {\n this.nodes.insertBefore(command.InsertBefore.parent, command.InsertBefore.child, command.InsertBefore.ref_id === null ? null : command.InsertBefore.ref_id);\n return;\n }\n\n if ('CreateNode' in command) {\n this.createNode(command.CreateNode.id, command.CreateNode.name);\n return;\n }\n\n if ('CreateText' in command) {\n this.createText(command.CreateText.id, command.CreateText.value);\n return;\n }\n\n if ('UpdateText' in command) {\n this.updateText(command.UpdateText.id, command.UpdateText.value);\n return;\n }\n\n if ('SetAttr' in command) {\n this.setAttr(command.SetAttr.id, command.SetAttr.name, command.SetAttr.value);\n return;\n }\n\n if ('RemoveAttr' in command) {\n this.removeAttr(command.RemoveAttr.id, command.RemoveAttr.name);\n return;\n }\n\n if ('RemoveText' in command) {\n this.removeText(command.RemoveText.id);\n return;\n }\n\n if ('InsertCss' in command) {\n this.nodes.insertCss(command.InsertCss.selector, command.InsertCss.value);\n return;\n }\n\n if ('CreateComment' in command) {\n const comment = document.createComment(command.CreateComment.value);\n this.nodes.set(command.CreateComment.id, comment);\n return;\n }\n\n if ('RemoveComment' in command) {\n const comment = this.nodes.delete(\"remove_comment\", command.RemoveComment.id);\n comment.remove();\n return;\n }\n\n if ('CallbackAdd' in command) {\n this.callbacks.add(this.nodes, command.CallbackAdd.id, command.CallbackAdd.event_name, command.CallbackAdd.callback_id);\n return;\n }\n\n if ('CallbackRemove' in command) {\n this.callbacks.remove(this.nodes, command.CallbackRemove.id, command.CallbackRemove.event_name, command.CallbackRemove.callback_id);\n return;\n }\n\n return assertNeverCommand(command);\n }\n}\n","import { DriverWebsocket } from \"./websocket/websocket\";\nimport { assertNever } from \"../assert_never\";\nimport { JsJsonType } from \"../jsjson\";\nimport { ModuleControllerType } from \"../wasm_init\";\nimport { ExportType } from \"../wasm_module\";\nimport { fetchCacheGet } from \"./command/fetchCacheGet\";\nimport { fetchExec, FetchRequestType } from \"./command/fetchExec\";\nimport { CallbackId } from \"./types\";\nimport { Interval } from \"./command/interval\";\nimport { AppLocation } from './location/AppLocation';\nimport { Cookies } from \"./command/cookies\";\nimport { getRandom } from \"./command/getRandom\";\nimport { CommandType, DriverDom } from \"./command/dom/dom\";\nimport { Metadata } from \"./metadata\";\n\ntype JsApiCommandType =\n | { Root: { name: string } }\n | { RootElement: { dom_id: number } }\n | { Get: { property: string } }\n | { Set: { property: string, value: JsJsonType } }\n | { Call: { method: string, args: JsJsonType[] } };\n\ntype ExecType\n = 'FetchCacheGet'\n | 'IsBrowser'\n | 'GetDateNow'\n | 'TimezoneOffset'\n | 'HistoryBack'\n | {\n FetchExec: {\n callback: CallbackId,\n request: FetchRequestType,\n }\n }\n | {\n WebsocketRegister: {\n callback: CallbackId,\n host: string\n }\n }\n | {\n WebsocketSendMessage: {\n callback: CallbackId,\n message: JsJsonType,\n }\n }\n | {\n WebsocketUnregister: {\n callback: CallbackId,\n }\n }\n | {\n TimerSet: {\n callback: CallbackId,\n duration: number,\n kind: 'Interval' | 'Timeout',\n }\n }\n | {\n TimerClear: {\n callback: CallbackId,\n }\n }\n | {\n LocationGet: {\n target: 'Hash' | 'History',\n }\n }\n | {\n LocationCallback: {\n callback: CallbackId,\n mode: 'Add' | 'Remove',\n target: 'Hash' | 'History'\n }\n }\n | {\n LocationSet: {\n mode: 'Push' | 'Replace',\n target: 'Hash' | 'History'\n value: string\n }\n }\n | {\n CookieSet: {\n name: string,\n value: string,\n expires_in: number,\n }\n }\n | {\n CookieGet: {\n name: string,\n }\n }\n | {\n CookieJsonSet: {\n name: string,\n value: JsJsonType,\n expires_in: number,\n }\n }\n | {\n CookieJsonGet: {\n name: string,\n }\n }\n | {\n GetEnv: {\n name: string\n }\n }\n | {\n Log: {\n arg2: string, //\"color: white; padding: 0 3px; background: green;\",\n arg3: string, //\"font-weight: bold; color: inherit\",\n arg4: string, //\"background: inherit; color: inherit\",\n kind: 'Debug' | 'Info' | 'Log' | 'Warn' | 'Error',\n message: string, //\"%cINFO%c crates/vertigo/src/driver_module/api/api_fetch_cache.rs:26%c FetchCache ready\"\n }\n }\n | {\n GetRandom: {\n min: number,\n max: number,\n }\n }\n | {\n JsApiCall: {\n commands: Array\n }\n }\n | {\n DomBulkUpdate: {\n list: Array\n }\n };\n\nexport class Api {\n public readonly dom: DriverDom;\n private readonly websocket: DriverWebsocket;\n private readonly interval: Interval;\n private readonly location: AppLocation;\n private readonly cookie: Cookies;\n\n\n constructor(private readonly metadata: Metadata, private readonly getWasm: () => ModuleControllerType) {\n const appLocation = new AppLocation(getWasm);\n\n this.dom = new DriverDom(metadata, appLocation, getWasm);\n this.websocket = new DriverWebsocket(getWasm);\n this.interval = new Interval(getWasm);\n this.location = appLocation;\n this.cookie = new Cookies();\n }\n\n exec(arg: JsJsonType): JsJsonType {\n\n //@ts-expect-error - //TODO Add safe type checking\n const safeArg: ExecType = arg;\n\n // console.info('exec arg', safeArg);\n\n if (safeArg === 'FetchCacheGet') {\n return fetchCacheGet(this.metadata);\n }\n\n if (safeArg === 'IsBrowser') {\n return {\n value: true\n };\n }\n\n if (safeArg === 'GetDateNow') {\n return {\n value: Date.now(),\n };\n }\n\n if (safeArg === 'TimezoneOffset') {\n return {\n value: new Date().getTimezoneOffset()\n };\n }\n\n if (safeArg === 'HistoryBack') {\n window.history.back();\n return null;\n }\n\n if ('FetchExec' in safeArg) {\n fetchExec(this.getWasm, safeArg.FetchExec.callback, safeArg.FetchExec.request);\n return null;\n }\n\n if ('WebsocketRegister' in safeArg) {\n this.websocket.websocket_register_callback(safeArg.WebsocketRegister.host, safeArg.WebsocketRegister.callback);\n return null;\n }\n\n if ('WebsocketSendMessage' in safeArg) {\n this.websocket.websocket_send_message(safeArg.WebsocketSendMessage.callback, safeArg.WebsocketSendMessage.message);\n return null;\n }\n\n if ('WebsocketUnregister' in safeArg) {\n this.websocket.websocket_unregister_callback(safeArg.WebsocketUnregister.callback);\n return null;\n }\n\n if ('TimerSet' in safeArg) {\n this.interval.timerSet(safeArg.TimerSet.callback, safeArg.TimerSet.duration, safeArg.TimerSet.kind);\n return null;\n }\n\n if ('TimerClear' in safeArg) {\n this.interval.timerClear(safeArg.TimerClear.callback);\n return null;\n }\n\n if ('LocationGet' in safeArg) {\n return {\n value: this.location.get(safeArg.LocationGet.target)\n };\n }\n\n if ('LocationCallback' in safeArg) {\n this.location.callback(safeArg.LocationCallback.target, safeArg.LocationCallback.mode, safeArg.LocationCallback.callback);\n return null;\n }\n\n if ('LocationSet' in safeArg) {\n this.location.set(safeArg.LocationSet.target, safeArg.LocationSet.mode, safeArg.LocationSet.value);\n return null;\n }\n\n if ('CookieGet' in safeArg) {\n return {\n value: this.cookie.get(safeArg.CookieGet.name)\n };\n }\n\n if ('CookieSet' in safeArg) {\n this.cookie.set(safeArg.CookieSet.name, safeArg.CookieSet.value, safeArg.CookieSet.expires_in);\n return null;\n }\n\n if ('CookieJsonGet' in safeArg) {\n return {\n value: this.cookie.getJson(safeArg.CookieJsonGet.name)\n };\n }\n\n if ('CookieJsonSet' in safeArg) {\n this.cookie.setJson(safeArg.CookieJsonSet.name, safeArg.CookieJsonSet.value, safeArg.CookieJsonSet.expires_in);\n return null;\n }\n\n if ('GetEnv' in safeArg) {\n const name = safeArg.GetEnv.name;\n\n return {\n value: this.metadata.getEnv(name),\n }\n }\n\n if ('Log' in safeArg) {\n switch (safeArg.Log.kind) {\n case 'Info': {\n console.info(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Debug': {\n console.debug(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Error': {\n console.error(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Log': {\n console.log(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n case 'Warn': {\n console.warn(safeArg.Log.message, safeArg.Log.arg2, safeArg.Log.arg3, safeArg.Log.arg4);\n return null;\n }\n }\n }\n\n if ('GetRandom' in safeArg) {\n return {\n value: getRandom(safeArg.GetRandom.min, safeArg.GetRandom.max)\n };\n }\n\n if ('JsApiCall' in safeArg) {\n return this.executeJsApiCall(safeArg.JsApiCall.commands);\n }\n\n if ('DomBulkUpdate' in safeArg) {\n this.dom.update(safeArg.DomBulkUpdate.list);\n return null;\n }\n\n console.info('exec_command: Arg', safeArg);\n return assertNever(safeArg);\n }\n\n private executeJsApiCall(commands: Array): JsJsonType {\n let current: any = null;\n\n for (const command of commands) {\n if ('Root' in command) {\n if (command.Root.name === 'window') {\n current = window;\n } else if (command.Root.name === 'document') {\n current = document;\n } else {\n console.error(`Unknown root: ${command.Root.name}`);\n return null;\n }\n } else if ('RootElement' in command) {\n const domId = command.RootElement.dom_id;\n const node = this.dom.nodes.getAnyOption(domId);\n if (node === undefined) {\n console.error(`Element not found: ${domId}`);\n return null;\n }\n current = node;\n } else if ('Get' in command) {\n if (current === null) {\n console.error('Get called on null');\n return null;\n }\n current = current[command.Get.property];\n } else if ('Set' in command) {\n if (current === null) {\n console.error('Set called on null');\n return null;\n }\n current[command.Set.property] = command.Set.value;\n current = undefined;\n } else if ('Call' in command) {\n if (current === null) {\n console.error('Call called on null');\n return null;\n }\n current = current[command.Call.method](...command.Call.args);\n }\n }\n\n // Convert result to JsJson - sanitize host objects (Window, Element, Function, etc.)\n const isPlainObject = (obj: any): boolean => {\n if (obj === null) return false;\n if (typeof obj !== 'object') return false;\n const proto = Object.getPrototypeOf(obj);\n return proto === Object.prototype || proto === null;\n };\n\n const sanitize = (value: any): JsJsonType => {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'boolean') {\n return value;\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number') {\n return value;\n }\n if (value instanceof Uint8Array) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((v) => sanitize(v));\n }\n if (isPlainObject(value)) {\n const out: { [k: string]: JsJsonType } = {};\n for (const k of Object.keys(value)) {\n out[k] = sanitize(value[k]);\n }\n return out;\n }\n\n // Host objects (Window, Element, DOM nodes, functions, class instances, etc.)\n // are not serializable to JsJson. Return null for safety.\n return null;\n };\n\n return sanitize(current);\n }\n}\n","import { JsJsonType } from \"../../jsjson\";\nimport { Metadata } from \"../metadata\";\n\nexport const fetchCacheGet = (metadata: Metadata): JsJsonType => {\n const cache = metadata.getFetchCache();\n\n return {\n data: cache\n };\n};\n","export class Metadata {\n private readonly metadata: HTMLElement;\n\n constructor() {\n const metadata = document.getElementById('v-metadata');\n\n if (metadata === null) {\n throw Error('Expected v-metadata');\n }\n\n this.metadata = metadata;\n metadata.remove();\n }\n\n private get = (attr: string): string | null => {\n return this.metadata.getAttribute(attr) ?? null;\n }\n\n getEnv(name: string) {\n return this.get(`data-env-${name}`);\n }\n\n getFetchCache() {\n return this.get('data-fetch-cache') ?? null;\n }\n\n getEnabledHydration = (): boolean => {\n const value = this.get('data-env-disable-hydration');\n return value !== 'true';\n }\n}\n","import { wasmInit, ModuleControllerType } from './wasm_init';\nimport { BufferCursor } from './buffer_cursor';\nimport { jsJsonDecodeItem, jsJsonGetSize, saveJsJsonToBufferItem } from './jsjson';\nimport { Api } from './api/api';\nimport { Metadata } from './api/metadata';\n\n//Number -> u32 or i32\n//BigInt -> u64 or i64\n\nexport type ImportType = {\n panic_message: (long_ptr: bigint) => void,\n //call from rust\n dom_access: (long_ptr: bigint) => bigint,\n}\n\nexport type ExportType = {\n vertigo_export_alloc_block: (size: number) => bigint,\n vertigo_export_free_block: (pointer: bigint) => void,\n vertigo_export_wasm_command: (value_ptr: bigint) => bigint,\n vertigo_entry_function: (major: number, minor: number) => void,\n}\n\nexport class WasmModule {\n private readonly wasm: ModuleControllerType;\n\n private constructor(\n wasm: ModuleControllerType,\n ) {\n this.wasm = wasm;\n }\n\n public vertigoEntryFunction(major: number, minor: number) {\n this.wasm.exports.vertigo_entry_function(major, minor);\n }\n\n public static async create(wasmBinPath: string): Promise {\n let wasmModule: ModuleControllerType | null = null;\n\n const getWasm = (): ModuleControllerType => {\n if (wasmModule === null) {\n throw Error('Wasm is no initialized');\n }\n\n return wasmModule;\n };\n\n const metadata = new Metadata();\n const vertigo_api = new Api(metadata, getWasm);\n\n //@ts-expect-error\n window.$vertigoApi = vertigo_api;\n\n wasmModule = await wasmInit(wasmBinPath, {\n mod: {\n panic_message: (long_ptr: bigint) => {\n\n const size = Number(long_ptr % (2n ** 32n));\n const ptr = Number(long_ptr >> 32n);\n\n const decoder = new TextDecoder(\"utf-8\");\n const m = getWasm().getUint8Memory().subarray(ptr, ptr + size);\n const message = decoder.decode(m);\n console.error('PANIC', message);\n },\n dom_access: (long_ptr: bigint): bigint => {\n if (long_ptr === 0n) {\n console.error('dom_access - null pointer');\n return 0n;\n }\n\n // Decode JsJson\n const buffer = new BufferCursor(\n () => getWasm().getUint8Memory(),\n long_ptr\n );\n const args = jsJsonDecodeItem(buffer);\n getWasm().exports.vertigo_export_free_block(long_ptr);\n\n // Execute command (now using JsApiCall instead of array-of-arrays)\n const response = vertigo_api.exec(args);\n\n // Save JsJson response\n const responseSize = jsJsonGetSize(response);\n const responseLongPtr = getWasm().exports.vertigo_export_alloc_block(responseSize);\n const responseBuffer = new BufferCursor(\n () => getWasm().getUint8Memory(),\n responseLongPtr\n );\n saveJsJsonToBufferItem(response, responseBuffer);\n\n return responseLongPtr;\n }\n }\n });\n\n return new WasmModule(wasmModule);\n }\n}\n","import { WasmModule } from \"./wasm_module\";\n\n// vertigo-cli compatibility version, change together with package version.\nconst VERTIGO_COMPAT_VERSION_MAJOR = 0;\nconst VERTIGO_COMPAT_VERSION_MINOR = 11;\n\nconst moduleRun: Set = new Set();\n\nconst runModule = async (wasm: string) => {\n if (moduleRun.has(wasm)) {\n //ok, module is run\n return;\n }\n\n if (moduleRun.size > 0) {\n console.error('Only one wasm module can be run', { moduleRun, wasm });\n return;\n }\n\n moduleRun.add(wasm);\n\n console.info(`Wasm module: \"${wasm}\" -> start`);\n const wasmModule = await WasmModule.create(wasm);\n console.info(`Wasm module: \"${wasm}\" -> initialized`);\n wasmModule.vertigoEntryFunction(VERTIGO_COMPAT_VERSION_MAJOR, VERTIGO_COMPAT_VERSION_MINOR);\n console.info(`Wasm module: \"${wasm}\" -> launched vertigoEntryFunction with version ${VERTIGO_COMPAT_VERSION_MAJOR}.${VERTIGO_COMPAT_VERSION_MINOR}`);\n};\n\nconst findAndRunModule = async () => {\n document.querySelectorAll('*[data-vertigo-run-wasm]').forEach((node) => {\n const wasm = node.getAttribute('data-vertigo-run-wasm');\n\n if (typeof wasm === 'string') {\n runModule(wasm);\n } else {\n console.error('Run error', node);\n }\n });\n};\n\n(() => {\n window.addEventListener('load', findAndRunModule);\n setTimeout(findAndRunModule, 3000);\n})();\n"],"names":["decoder","TextDecoder","encoder","TextEncoder","BufferCursor","constructor","getUint8Memory","long_ptr","this","pointer","ptr","Number","size","dataView","DataView","buffer","getByte","value","getUint8","setByte","byte","setUint8","getU16","getUint16","setU16","setUint16","getU32","getUint32","setU32","setUint32","getI32","getInt32","setI32","setInt32","getU64","getBigUint64","setU64","setBigUint64","getI64","getBigInt64","setI64","setBigInt64","getF64","getFloat64","setF64","setFloat64","getBuffer","result","subarray","setBuffer","length","set","getString","decode","setString","encode","getSavedSize","JsJsonConst","jsJsonGetSize","Uint8Array","Array","isArray","sum","item","key","propertyValue","Object","entries","Error","jsJsonDecodeItem","typeId","count","list","i","push","obj","saveJsJsonToBufferItem","undefined","wasmInit","async","wasmBinPath","imports","module_instance","WebAssembly","instantiateStreaming","stream","fetch","err","console","warn","info","resp","binary","arrayBuffer","instantiate","fetchModule","cacheGetUint8Memory","instance","exports","memory","Memory","wasmCommand","vertigo_export_alloc_block","result_long_ptr","vertigo_export_wasm_command","resultBuffer","vertigo_export_free_block","EventEmitter","events","Set","on","callback","isActive","onExec","param","add","delete","trigger","eventsCopy","from","values","itemCallbackToRun","error","PromiseBoxRace","inner","resolve","promiseResolveReject","reject","isFulfilled","promise","Promise","localResolve","localReject","createPromiseValue","reconnectDelay","label","timeout_retry","timeout","setTimeout","LogContext","host","formatLog","message","SocketConnection","close","send","eventMessage","connect","log","done","socket","WebSocket","isClose","closeSocket","socketConnection","addEventListener","event","dataRaw","data","startSocket","timeout_connection","onMessage","isConnect","openSocketResult","type","catch","dispose","wireStringToJsJson","raw","JSON","parse","wasmCallback","wasm","callbackId","command","Websocket","DriverWebsocket","getWasm","websocket_register_callback","callback_id","controller","controllerList","has","assertNeverMessage","Message","websocket_unregister_callback","get","websocket_send_message","stringify","Map","getHeaders","headers","k","v","getBodyString","body","Data","processResponse","response","status","contentType","startsWith","Ok","Text","text","Json","bodyText","Err","String","Interval","timerSet","duration","kind","timerId","setInterval","TimerCall","timerClear","timerResource","clearInterval","clearTimeout","HashRouter","LocationCall","remove","new_hash","location","hash","replace","history","replaceState","window","decodeURIComponent","substr","HistoryLocation","url","pushState","pathname","search","AppLocation","target","mode","locations","newValue","Hash","History","Cookies","cname","cookie","document","split","cookieChunk","trim","cookieName","cookieValue","getJson","cvalue_str","e","cvalue","expires_in","cvalueEncoded","encodeURIComponent","d","Date","setTime","getTime","expires","toUTCString","setJson","getRandom","min","max","range","Math","floor","random","CallbackManager","callbacks","nodes","id","event_name","click","submit","input","change","blur","mousedown","mouseup","mouseenter","mouseleave","keydown","drop","load","changeFile","node","domEventName","removeEventListener","CallbackCall","preventDefault","click_event","stopPropagation","HTMLInputElement","HTMLTextAreaElement","HTMLSelectElement","files","promises","file","then","buf","name","all","params","f","_event","DragEvent","dataTransfer","items","getAsFile","getFiles","dataArray","KeyboardEvent","code","altKey","ctrlKey","shiftKey","metaKey","injects","appLocation","tagName","toLocaleLowerCase","href","getAttribute","scrollTo","hydrateLink","HydrationEngine","commands","depth","matched","virtualNodes","createVirtualNodes","hydrate","hydrateNode","head","toFixed","vNodeId","realNode","vNode","realChildren","childNodes","realIndex","skipTextVNodes","childVId","children","childVNode","candidate","isMatch","checkElementMatch","nodeType","Node","TEXT_NODE","checkTextMatch","removeSkippedNodes","claimNode","ELEMENT_NODE","attributes","element","setAttribute","textContent","Element","Comment","j","nodeToRemove","getVNode","CreateNode","toUpperCase","CreateText","parent","InsertBefore","childId","child","refId","ref_id","index","indexOf","splice","SetAttr","MapNodes","initNodes","getRootHead","getRootBody","style","createElement","getRootHtml","documentElement","getAnyOption","getAny","getNodeElement","HTMLElement","getNode","getText","getComment","insertCss","selector","content","createTextNode","appendChild","removeInitNodes","insertBefore","parentNode","childNode","ref_node","addStyles","hasInitNodes","SVG_TAGS","DriverDom","metadata","update","getEnabledHydration","setFocus","runCommand","focus","ev","createNode","createElementNS","setAttr","defaultValue","removeAttr","removeAttribute","removeNode","createText","removeText","updateText","RemoveNode","UpdateText","RemoveAttr","RemoveText","InsertCss","comment","createComment","CreateComment","RemoveComment","CallbackAdd","assertNeverCommand","CallbackRemove","Api","dom","websocket","interval","exec","arg","safeArg","getFetchCache","now","getTimezoneOffset","back","request","method","response2","FetchExecResponse","responseToWasm","toString","fetchExec","FetchExec","WebsocketRegister","WebsocketSendMessage","WebsocketUnregister","TimerSet","TimerClear","LocationGet","LocationCallback","LocationSet","CookieGet","CookieSet","CookieJsonGet","CookieJsonSet","GetEnv","getEnv","Log","arg2","arg3","arg4","debug","GetRandom","executeJsApiCall","JsApiCall","DomBulkUpdate","assertNever","current","Root","domId","RootElement","dom_id","Get","property","Call","args","sanitize","map","proto","getPrototypeOf","prototype","isPlainObject","out","keys","Metadata","attr","getElementById","WasmModule","vertigoEntryFunction","major","minor","vertigo_entry_function","create","wasmModule","vertigo_api","$vertigoApi","mod","panic_message","m","dom_access","responseSize","responseLongPtr","responseBuffer","moduleRun","findAndRunModule","querySelectorAll","forEach","runModule"],"mappings":"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"} \ No newline at end of file diff --git a/crates/vertigo/src/tests/dom/component_namespaces.rs b/crates/vertigo/src/tests/dom/component_namespaces.rs index 60a95861..6c803fb2 100644 --- a/crates/vertigo/src/tests/dom/component_namespaces.rs +++ b/crates/vertigo/src/tests/dom/component_namespaces.rs @@ -2,7 +2,8 @@ /// This test checks if component can be used when not in local scope /// (whole name does not start with capital letter) fn test_namespaces() { - use crate::{self as vertigo, DomNode, dom}; + use crate::dev::inspect::{DomDebugFragment, log_start}; + use crate::{self as vertigo, dom}; mod my_module { pub mod inner { @@ -16,23 +17,15 @@ fn test_namespaces() { } } - let ret = dom! { + log_start(); + let _el = dom! { }; - - match ret { - DomNode::Node { node } => { - match node.get_children().pop_back() { - // If node has text child, then component "Hello" was embedded correctly - Some(child) => match child { - DomNode::Text { node: _ } => {} - _ => panic!("Expected text child"), - }, - _ => panic!("Expected child node"), - } - } - _ => panic!("Expected DomNode::Node"), - } + let html = DomDebugFragment::from_log().to_pseudo_html(); + assert_eq!( + html, + "Hello world" + ); } #[test] @@ -48,13 +41,18 @@ fn test_pub_super() { } } - use crate::{self as vertigo, DomNode, dom}; + use crate::dev::inspect::{DomDebugFragment, log_start}; + use crate::{self as vertigo, dom}; - let ret = dom! { + log_start(); + let _el = dom! {

}; - - assert!(matches!(ret, DomNode::Node { node: _ })); + let html = DomDebugFragment::from_log().to_pseudo_html(); + assert_eq!( + html, + "

Hello world

" + ); } #[test] @@ -71,11 +69,16 @@ fn test_pub_crate() { } } - use crate::{self as vertigo, DomNode, dom}; + use crate::dev::inspect::{DomDebugFragment, log_start}; + use crate::{self as vertigo, dom}; - let ret = dom! { + log_start(); + let _el = dom! {

}; - - assert!(matches!(ret, DomNode::Node { node: _ })); + let html = DomDebugFragment::from_log().to_pseudo_html(); + assert_eq!( + html, + "

Hello world

" + ); } diff --git a/crates/vertigo/src/tests/dom/html_attrs.rs b/crates/vertigo/src/tests/dom/html_attrs.rs index 9f7830f8..1d0d9ae8 100644 --- a/crates/vertigo/src/tests/dom/html_attrs.rs +++ b/crates/vertigo/src/tests/dom/html_attrs.rs @@ -1,6 +1,6 @@ use crate as vertigo; -use crate::dev::inspect::{log_start, log_take}; -use crate::dom; +use crate::dev::inspect::{DomDebugFragment, log_start}; +use crate::{DropFileEvent, dom}; #[test] fn button_on_click() { @@ -8,11 +8,12 @@ fn button_on_click() { log_start(); - let _ = dom! { + let _el = dom! {