Repository: Kong/swrv (ts)

Issue:
Infinite loop revalidateCall
In version 0.7.0

```
Uncaught (in promise) RangeError: Maximum call stack size exceeded
    at revalidateCall (use-swrv.js?a598:187)
    at revalidateCall (use-swrv.js?a598:187)
    at revalidateCall (use-swrv.js?a598:187)
...
```

https://github.com/Kong/swrv/blob/master/src/use-swrv.ts#L221

`const revalidateCall = async () => revalidateCall();`

should probably be

`const revalidateCall = async () => revalidate();`

Pull request description:
fix(listeners) remove recursive call bug
Fixes #58 

Patch:
diff --git a/src/use-swrv.ts b/src/use-swrv.ts
index 79b75d7..0537d42 100644
--- a/src/use-swrv.ts
+++ b/src/use-swrv.ts
@@ -218,7 +218,7 @@ export default function useSWRV<Data = any, Error = any> (key: IKey, fn?: fetche
     PROMISES_CACHE.delete(keyVal)
   }
 
-  const revalidateCall = async () => revalidateCall()
+  const revalidateCall = async () => revalidate()
   let timer = null
   /**
    * Setup polling


Test patch:
diff --git a/tests/use-swrv.spec.tsx b/tests/use-swrv.spec.tsx
index c1af022..8ca9e98 100644
--- a/tests/use-swrv.spec.tsx
+++ b/tests/use-swrv.spec.tsx
@@ -346,7 +346,6 @@ describe('useSWRV', () => {
           })
 
           mutate = revalidate
-          console.log(mutate)
           return {
             data,
             isValidating
@@ -628,15 +627,15 @@ describe('useSWRV - listeners', () => {
     const f3 = jest.fn()
     const f4 = jest.fn()
 
-    document.addEventListener = f1
-    document.removeEventListener = f2
-    window.addEventListener = f3
-    window.removeEventListener = f4
+    jest.spyOn(document, 'addEventListener').mockImplementationOnce(f1)
+    jest.spyOn(document, 'removeEventListener').mockImplementationOnce(f2)
+    jest.spyOn(window, 'addEventListener').mockImplementationOnce(f3)
+    jest.spyOn(window, 'removeEventListener').mockImplementationOnce(f4)
 
     const vm = new Vue({
       template: `<div>hello, {{ data }}</div>`,
       setup  () {
-        const refs = useSWRV('cache-key-1', () => 'SWR')
+        const refs = useSWRV('cache-key-listeners-1', () => 'SWR')
         return refs
       }
     }).$mount()
@@ -649,8 +648,59 @@ describe('useSWRV - listeners', () => {
     expect(f2).toHaveBeenLastCalledWith('visibilitychange', expect.any(Function), false)
     expect(f3).toHaveBeenLastCalledWith('focus', expect.any(Function), false)
     expect(f4).toHaveBeenLastCalledWith('focus', expect.any(Function), false)
+
+    expect(f1).toHaveBeenCalledTimes(1)
+    expect(f2).toHaveBeenCalledTimes(1)
+    expect(f3).toHaveBeenCalledTimes(1)
+    expect(f4).toHaveBeenCalledTimes(1)
     done()
   })
+
+  it('events trigger revalidate - switching windows/tabs', async () => {
+    let revalidations = 0
+    const vm = new Vue({
+      template: `<div>hello, {{ data }}</div>`,
+      setup  () {
+        const refs = useSWRV('cache-key-listeners-2', () => {
+          revalidations += 1
+          return 'SWR'
+        })
+        return refs
+      }
+    }).$mount()
+
+    await tick(vm, 2)
+    expect(revalidations).toBe(1)
+
+    let evt = new Event('visibilitychange')
+    document.dispatchEvent(evt)
+
+    await tick(vm, 2)
+    expect(revalidations).toBe(2)
+  })
+
+  it('events trigger revalidate - focusing back on a window/tab', async () => {
+    let revalidations = 0
+    const vm = new Vue({
+      template: `<div>hello, {{ data }}</div>`,
+      setup  () {
+        const refs = useSWRV('cache-key-listeners-3', () => {
+          revalidations += 1
+          return 'SWR'
+        })
+        return refs
+      }
+    }).$mount()
+
+    await tick(vm, 2)
+    expect(revalidations).toBe(1)
+
+    let evt = new Event('focus')
+    window.dispatchEvent(evt)
+
+    await tick(vm, 2)
+    expect(revalidations).toBe(2)
+  })
 })
 
 describe('useSWRV - refresh', () => {