diff options
-rw-r--r-- | graffiti.js | 34 | ||||
-rw-r--r-- | plugins/vue/demo/index.html | 13 | ||||
-rw-r--r-- | plugins/vue/index.html | 34 | ||||
-rw-r--r-- | plugins/vue/plugin.js | 22 |
4 files changed, 51 insertions, 52 deletions
diff --git a/graffiti.js b/graffiti.js index 9c5b188..3cdc7fc 100644 --- a/graffiti.js +++ b/graffiti.js @@ -36,11 +36,14 @@ export default class { // Commence connection this.#connect() } - - async opened() { - if (!this.open) { + + // Wait for the connection to be + // open (state=true) or closed (state=false) + async connectionState(state) { + if (this.open != state) { await new Promise(resolve => { - this.eventTarget.addEventListener("graffitiOpen", () => resolve() ) + this.eventTarget.addEventListener( + state? "open": "closed", ()=> resolve()) }) } } @@ -59,15 +62,16 @@ export default class { } async #onClose() { - this.open = false console.error("lost connection to graffiti server, attemping reconnect soon...") + this.open = false + this.eventTarget.dispatchEvent(new Event("closed")) await new Promise(resolve => setTimeout(resolve, 2000)) this.#connect() } async #request(msg) { if (!this.open) { - throw { 'error': 'Not connected!' } + throw "Can't make request! Not connected to graffiti server" } // Create a random message ID @@ -75,7 +79,7 @@ export default class { // Create a listener for the reply const dataPromise = new Promise(resolve => { - this.eventTarget.addEventListener(messageID, (e) => { + this.eventTarget.addEventListener('$'+messageID, (e) => { resolve(e.data) }) }) @@ -101,7 +105,7 @@ export default class { if ('messageID' in data) { // It's a reply // Forward it back to the sender - const messageEvent = new Event(data.messageID) + const messageEvent = new Event('$'+data.messageID) messageEvent.data = data this.eventTarget.dispatchEvent(messageEvent) @@ -263,9 +267,13 @@ export default class { } } - // Begin subscribing in the background + // Try subscribing in the background + // but don't raise an error since + // the subscriptions will happen once connected if (subscribingTags.length) - await this.#request({ subscribe: subscribingTags }) + try { + await this.#request({ subscribe: subscribingTags }) + } catch {} } async unsubscribe(...tags) { @@ -284,13 +292,15 @@ export default class { // Unsubscribe from all remaining tags if (unsubscribingTags.length) - await this.#request({ unsubscribe: unsubscribingTags }) + try { + await this.#request({ unsubscribe: unsubscribingTags }) + } catch {} } async #onOpen() { console.log("connected to the graffiti socket") this.open = true - this.eventTarget.dispatchEvent(new Event("graffitiOpen")) + this.eventTarget.dispatchEvent(new Event("open")) // Clear data for (let tag in this.tagMap) { diff --git a/plugins/vue/demo/index.html b/plugins/vue/demo/index.html index e0c841f..7a142c1 100644 --- a/plugins/vue/demo/index.html +++ b/plugins/vue/demo/index.html @@ -7,7 +7,7 @@ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css"> <script async src="https://ga.jspm.io/npm:es-module-shims@1.6.2/dist/es-module-shims.js"></script> <script type="importmap">{ "imports": { - "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.45/vue.esm-browser.min.js", + "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.45/vue.esm-browser.prod.min.js", "graffiti-vue": "../plugin.js" }}</script> <script type="module"> @@ -27,6 +27,13 @@ <body id="app"> <!--------------------------------------------------------------> + <h1> + Connection Status + </h1> + + <p> + Connected to the Graffiti server? {{ $graffitiConnected }} + </p> <h1> Logging In @@ -38,6 +45,10 @@ </button> </p> + <p> + My Graffiti ID is "{{ $graffitiMyID }}" + </p> + <br> <h1> diff --git a/plugins/vue/index.html b/plugins/vue/index.html deleted file mode 100644 index ceea8c7..0000000 --- a/plugins/vue/index.html +++ /dev/null @@ -1,34 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <script async src="https://ga.jspm.io/npm:es-module-shims@1.6.2/dist/es-module-shims.js"></script> - <script type="importmap">{ "imports": { - "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.45/vue.esm-browser.min.js" - }}</script> - <script type="module"> - import { createApp } from 'vue' - import GraffitiVue from './plugin.js' - - createApp() - .use(GraffitiVue, {url: "http://localhost:5001"}) - .mount('#app') - </script> -</head> -<body id="app"> - {{ $graffitiID }} - - <button @click="$graffitiToggleLogIn"> - Log In - </button> - - <graffiti-objects :tags="['asdf']" v-slot="{objects}"> - <li v-for="object in objects"> - {{object._tags}} - <button @click="object._remove()"> - ❌ - </button> - </li> - </graffiti-objects> - -</body> -</html> diff --git a/plugins/vue/plugin.js b/plugins/vue/plugin.js index bfca17c..76fb0de 100644 --- a/plugins/vue/plugin.js +++ b/plugins/vue/plugin.js @@ -10,13 +10,25 @@ export default { // Initialize graffiti with reactive entries const graffiti = new Graffiti(graffitiURL, ()=>reactive({})) - // These ID need to change after opening - const myID = ref(null) - graffiti.opened().then(()=> { - myID.value = graffiti.myID + // Create a reactive variable that tracks + // connection changes + const connectionState = ref(false) + ;(function waitForState(state) { + graffiti.connectionState(state).then(()=> { + connectionState.value = state + waitForState(!state) + })})(true) + Object.defineProperty(app.config.globalProperties, "$graffitiConnected", { + get: ()=> connectionState.value }) + + // the connection state becomes true + let myID = null Object.defineProperty(app.config.globalProperties, "$graffitiMyID", { - get: ()=> myID.value + get: ()=> { + if (connectionState.value) myID = graffiti.myID + return myID + } }) // Add static functions |