diff --git a/packages/desktop/src/js/hash.txt b/packages/desktop/src/js/hash.txt index 92bf35c55..03d64c662 100644 --- a/packages/desktop/src/js/hash.txt +++ b/packages/desktop/src/js/hash.txt @@ -1 +1 @@ -[14101548031762241351] \ No newline at end of file +[16018260687765471498] \ No newline at end of file diff --git a/packages/desktop/src/js/native_eval.js b/packages/desktop/src/js/native_eval.js index 50c6026ab..fa3bd679f 100644 --- a/packages/desktop/src/js/native_eval.js +++ b/packages/desktop/src/js/native_eval.js @@ -1 +1 @@ -class Channel{pending;waiting;constructor(){this.pending=[],this.waiting=[]}send(data){if(this.waiting.length>0){this.waiting.shift()(data);return}this.pending.push(data)}async recv(){return new Promise((resolve,_reject)=>{if(this.pending.length>0){resolve(this.pending.shift());return}this.waiting.push(resolve)})}}class WeakDioxusChannel{inner;constructor(channel){this.inner=new WeakRef(channel)}rustSend(data){let channel=this.inner.deref();if(channel)channel.rustSend(data)}async rustRecv(){let channel=this.inner.deref();if(channel)return await channel.rustRecv()}}class DioxusChannel{weak(){return new WeakDioxusChannel(this)}}class QueryParams{id;data;constructor(id,method,data){this.id=id,this.data={method,data}}}window.__msg_queues=window.__msg_queues||[];window.finalizationRegistry=window.finalizationRegistry||new FinalizationRegistry(({id})=>{window.ipc.postMessage(JSON.stringify({method:"query",params:new QueryParams(id,"drop")}))});window.getQuery=function(request_id){return window.__msg_queues[request_id]};window.createQuery=function(request_id){return new NativeDioxusChannel(request_id)};class NativeDioxusChannel extends DioxusChannel{rust_to_js;request_id;constructor(request_id){super();this.rust_to_js=new Channel,this.request_id=request_id,window.__msg_queues[request_id]=this.weak(),window.finalizationRegistry.register(this,{id:request_id})}async recv(){return await this.rust_to_js.recv()}send(data){window.ipc.postMessage(JSON.stringify({method:"query",params:new QueryParams(this.request_id,"send",data)}))}rustSend(data){this.rust_to_js.send(data)}async rustRecv(){}}export{NativeDioxusChannel}; +class Channel{pending;waiting;constructor(){this.pending=[],this.waiting=[]}send(data){if(this.waiting.length>0){this.waiting.shift()(data);return}this.pending.push(data)}async recv(){return new Promise((resolve,_reject)=>{if(this.pending.length>0){resolve(this.pending.shift());return}this.waiting.push(resolve)})}}class WeakDioxusChannel{inner;constructor(channel){this.inner=new WeakRef(channel)}rustSend(data){let channel=this.inner.deref();if(channel)channel.rustSend(data)}async rustRecv(){let channel=this.inner.deref();if(channel)return await channel.rustRecv()}}class DioxusChannel{weak(){return new WeakDioxusChannel(this)}}class QueryParams{id;data;constructor(id,method,data){this.id=id,this.data={method,data}}}window.__msg_queues=window.__msg_queues||[];window.finalizationRegistry=window.finalizationRegistry||new FinalizationRegistry(({id})=>{window.ipc.postMessage(JSON.stringify({method:"query",params:new QueryParams(id,"drop")}))});window.getQuery=function(request_id){return window.__msg_queues[request_id]};window.createQuery=function(request_id){return new NativeDioxusChannel(request_id)};class NativeDioxusChannel extends DioxusChannel{rust_to_js;request_id;constructor(request_id){super();this.rust_to_js=new Channel,this.request_id=request_id,window.__msg_queues[request_id]=this,window.finalizationRegistry.register(this,{id:request_id})}async recv(){return await this.rust_to_js.recv()}send(data){window.ipc.postMessage(JSON.stringify({method:"query",params:new QueryParams(this.request_id,"send",data)}))}rustSend(data){this.rust_to_js.send(data)}async rustRecv(){}close(){window.__msg_queues[this.request_id]=null}}export{NativeDioxusChannel}; diff --git a/packages/desktop/src/query.rs b/packages/desktop/src/query.rs index 8f7267ae5..da5034d92 100644 --- a/packages/desktop/src/query.rs +++ b/packages/desktop/src/query.rs @@ -80,6 +80,7 @@ impl QueryEngine { let promise = (new AsyncFunction("dioxus", {script:?}))(dioxus); promise .then((result)=>{{ + dioxus.close(); let returned_value = {{ "method": "query", "params": {{ @@ -96,6 +97,7 @@ impl QueryEngine { }}) .catch(err => post_error(`Error running JS: ${{err}}`)); }} catch (error) {{ + dioxus.close(); post_error(`Invalid JS: ${{error}}`); }} }})();"# diff --git a/packages/desktop/src/ts/native_eval.ts b/packages/desktop/src/ts/native_eval.ts index e2880bb4d..c42c6228f 100644 --- a/packages/desktop/src/ts/native_eval.ts +++ b/packages/desktop/src/ts/native_eval.ts @@ -60,7 +60,7 @@ export class NativeDioxusChannel extends DioxusChannel { this.rust_to_js = new Channel(); this.request_id = request_id; - window.__msg_queues[request_id] = this.weak(); + window.__msg_queues[request_id] = this; window.finalizationRegistry.register(this, { id: request_id }); } @@ -87,4 +87,9 @@ export class NativeDioxusChannel extends DioxusChannel { // Receive data sent from javascript in rust. This is a no-op in the native interpreter because the rust code runs remotely async rustRecv(): Promise { } + + // Close the channel, dropping it. + close(): void { + window.__msg_queues[this.request_id] = null; + } } diff --git a/packages/document/src/js/hash.txt b/packages/document/src/js/hash.txt index faaeb89f2..1e1d33f2c 100644 --- a/packages/document/src/js/hash.txt +++ b/packages/document/src/js/hash.txt @@ -1 +1 @@ -[206827801705263822, 8375185156499858125] \ No newline at end of file +[5568016277461366671, 8375185156499858125] \ No newline at end of file diff --git a/packages/document/src/ts/eval.ts b/packages/document/src/ts/eval.ts index 4440fe9df..40f705792 100644 --- a/packages/document/src/ts/eval.ts +++ b/packages/document/src/ts/eval.ts @@ -67,4 +67,7 @@ export abstract class DioxusChannel { // Receive data sent from javascript in rust abstract rustRecv(): Promise; + + // Close the channel, dropping it. + abstract close(): void; } diff --git a/packages/web/src/document.rs b/packages/web/src/document.rs index b97402e7e..3eb253bd9 100644 --- a/packages/web/src/document.rs +++ b/packages/web/src/document.rs @@ -136,6 +136,8 @@ impl Document for WebDocument { const PROMISE_WRAPPER: &str = r#" return (async function(){ {JS_CODE} + + dioxus.close(); })(); "#; diff --git a/packages/web/src/js/eval.js b/packages/web/src/js/eval.js index 111158c3e..7a0560351 100644 --- a/packages/web/src/js/eval.js +++ b/packages/web/src/js/eval.js @@ -1 +1 @@ -class Channel{pending;waiting;constructor(){this.pending=[],this.waiting=[]}send(data){if(this.waiting.length>0){this.waiting.shift()(data);return}this.pending.push(data)}async recv(){return new Promise((resolve,_reject)=>{if(this.pending.length>0){resolve(this.pending.shift());return}this.waiting.push(resolve)})}}class WeakDioxusChannel{inner;constructor(channel){this.inner=new WeakRef(channel)}rustSend(data){let channel=this.inner.deref();if(channel)channel.rustSend(data)}async rustRecv(){let channel=this.inner.deref();if(channel)return await channel.rustRecv()}}class DioxusChannel{weak(){return new WeakDioxusChannel(this)}}class WebDioxusChannel extends DioxusChannel{js_to_rust;rust_to_js;owner;constructor(owner){super();this.owner=owner,this.js_to_rust=new Channel,this.rust_to_js=new Channel}weak(){return new WeakDioxusChannel(this)}async recv(){return await this.rust_to_js.recv()}send(data){this.js_to_rust.send(data)}rustSend(data){this.rust_to_js.send(data)}async rustRecv(){return await this.js_to_rust.recv()}}export{WebDioxusChannel}; +class Channel{pending;waiting;constructor(){this.pending=[],this.waiting=[]}send(data){if(this.waiting.length>0){this.waiting.shift()(data);return}this.pending.push(data)}async recv(){return new Promise((resolve,_reject)=>{if(this.pending.length>0){resolve(this.pending.shift());return}this.waiting.push(resolve)})}}class WeakDioxusChannel{inner;constructor(channel){this.inner=new WeakRef(channel)}rustSend(data){let channel=this.inner.deref();if(channel)channel.rustSend(data)}async rustRecv(){let channel=this.inner.deref();if(channel)return await channel.rustRecv()}}class DioxusChannel{weak(){return new WeakDioxusChannel(this)}}window.__nextChannelId=0;window.__channels=[];class WebDioxusChannel extends DioxusChannel{js_to_rust;rust_to_js;owner;id;constructor(owner){super();this.owner=owner,this.js_to_rust=new Channel,this.rust_to_js=new Channel,this.id=window.__nextChannelId,window.__channels[this.id]=this,window.__nextChannelId+=1}weak(){return new WeakDioxusChannel(this)}async recv(){return await this.rust_to_js.recv()}send(data){this.js_to_rust.send(data)}rustSend(data){this.rust_to_js.send(data)}async rustRecv(){return await this.js_to_rust.recv()}close(){window.__channels[this.id]=null}}export{WebDioxusChannel}; diff --git a/packages/web/src/js/hash.txt b/packages/web/src/js/hash.txt index 5002e6c9a..8cbce7765 100644 --- a/packages/web/src/js/hash.txt +++ b/packages/web/src/js/hash.txt @@ -1 +1 @@ -[1614426347475783279] +[857504888396904142] \ No newline at end of file diff --git a/packages/web/src/ts/eval.ts b/packages/web/src/ts/eval.ts index 51396b63a..8b67fcd34 100644 --- a/packages/web/src/ts/eval.ts +++ b/packages/web/src/ts/eval.ts @@ -4,16 +4,24 @@ import { WeakDioxusChannel, } from "../../../document/src/ts/eval"; +window.__nextChannelId = 0; +window.__channels = []; + export class WebDioxusChannel extends DioxusChannel { js_to_rust: Channel; rust_to_js: Channel; owner: any; + id: number; constructor(owner: any) { super(); this.owner = owner; this.js_to_rust = new Channel(); this.rust_to_js = new Channel(); + + this.id = window.__nextChannelId; + window.__channels[this.id] = this; + window.__nextChannelId += 1; } // Return a weak reference to this channel @@ -40,4 +48,9 @@ export class WebDioxusChannel extends DioxusChannel { async rustRecv(): Promise { return await this.js_to_rust.recv(); } + + // Close the channel, dropping it. + close(): void { + window.__channels[this.id] = null; + } }