Repository: mercurius-js/mercurius
Pull request #1037 (2023-10-19 13:59:15)

make url dynamic so even if the graphiql is deployed on baseUrl it can work.
fix - https://github.com/mercurius-js/mercurius/issues/1003 issue. 

The graphiql failed to load schema when it's been deployed on https://foo.com/bar/graphiql, it will look for the schema at https://foo.com/graphql but it's actually running on https://foo.com/bar/graphql, which is an invalid graphql endpoint as it is missing window.baseUrl. So we are addressing this in the PR. 


![image](https://github.com/mercurius-js/mercurius/assets/111346255/9b965276-55d3-4e9e-8799-4fe464ccc54a)


Thank you @ddai1  for help here. 


glg-satish-tripathi: Thank you @ddai for help here. 
glg-satish-tripathi: @mcollina  please review and approve this, i am working on a graphql api and without these changes i can not deploy the setup. i am not an expert on javascript, so not very sure where unit test needs to be added if any. 

Patch:
diff --git a/lib/subscriber.js b/lib/subscriber.js
index a97d32d..5d52cde 100644
--- a/lib/subscriber.js
+++ b/lib/subscriber.js
@@ -25,7 +25,8 @@ class PubSub {
 
         resolve()
       })
-      queue.close = close
+      if (!queue.close) queue.close = []
+      queue.close.push(close)
     })
   }
 
@@ -68,8 +69,8 @@ class SubscriptionContext {
   close () {
     // In rare cases when `subscribe()` not called (e.g. some network error)
     // `close` will be `undefined`.
-    if (typeof this.queue.close === 'function') {
-      this.queue.close()
+    if (Array.isArray(this.queue.close)) {
+      this.queue.close.map((close) => close())
     }
     this.queue.push(null)
   }
diff --git a/static/main.js b/static/main.js
index 4d257f1..8274de9 100644
--- a/static/main.js
+++ b/static/main.js
@@ -97,11 +97,16 @@ function fetcherWrapper (fetcher, cbs = []) {
 
 function render () {
   const host = window.location.host
-
   const websocketProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
-
-  const url = `${window.location.protocol}//${host}${window.GRAPHQL_ENDPOINT}`
-  const subscriptionUrl = `${websocketProtocol}//${host}${window.GRAPHQL_ENDPOINT}`
+  let url = ''
+  let subscriptionUrl = ''
+  if (window.baseurl) {
+    url = `${window.location.protocol}//${host}${window.baseurl}${window.GRAPHQL_ENDPOINT}`
+    subscriptionUrl = `${websocketProtocol}//${host}${window.baseurl}${window.GRAPHQL_ENDPOINT}`
+  } else {
+    url = `${window.location.protocol}//${host}${window.GRAPHQL_ENDPOINT}`
+    subscriptionUrl = `${websocketProtocol}//${host}${window.GRAPHQL_ENDPOINT}`
+  }
 
   const availablePlugins = window.GRAPHIQL_PLUGIN_LIST
     .map(plugin => window[`GRAPIHQL_PLUGIN_${plugin.toUpperCase()}`])


Test patch:
diff --git a/test/subscriber.js b/test/subscriber.js
index 661752a..98fab81 100644
--- a/test/subscriber.js
+++ b/test/subscriber.js
@@ -78,9 +78,10 @@ test('subscription context publish event returns a promise reject on error', asy
 })
 
 test('subscription context can handle multiple topics', t => {
-  t.plan(2)
+  t.plan(4)
 
-  const pubsub = new PubSub(mq())
+  const q = mq()
+  const pubsub = new PubSub(q)
   const sc = new SubscriptionContext({ pubsub })
 
   sc.subscribe(['TOPIC1', 'TOPIC2'])
@@ -96,4 +97,8 @@ test('subscription context can handle multiple topics', t => {
   }).then(() => {
     t.pass()
   })
+
+  t.equal(q._matcher._trie.size, 2, 'Two listeners not found')
+  sc.close()
+  setImmediate(() => { t.equal(q._matcher._trie.size, 0, 'All listeners not removed') })
 })