Skip to content

Commit 9488d7e

Browse files
Darren Jenningsdarrenjennings
Darren Jennings
authored andcommitted
feat(config) add default fetcher, webPresets (#120)
* chore(eslint) add eol rules * feat(config) add default fetcher, webPresets * test(compat) fix version pinning for compat-all
1 parent b52739e commit 9488d7e

File tree

10 files changed

+77
-23
lines changed

10 files changed

+77
-23
lines changed

.eslintrc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ module.exports = {
1111
rules: {
1212
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
1313
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
14-
'promise/param-names': 'off'
14+
'promise/param-names': 'off',
15+
'no-multiple-empty-lines': ['error', { 'max': 1, 'maxEOF': 1 }],
16+
'no-trailing-spaces': 'error',
17+
'eol-last': 'error'
1518
},
1619
parserOptions: {
1720
parser: '@typescript-eslint/parser'

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
3+
setupFiles: ['<rootDir>/tests/setupJest.ts'],
34
testMatch: [
45
'<rootDir>/tests/**/*.spec.[jt]s?(x)'
56
]

src/lib/is-document-visible.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/lib/is-online.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/lib/web-preset.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function isOnline (): boolean {
2+
if (typeof navigator.onLine !== 'undefined') {
3+
return navigator.onLine
4+
}
5+
// always assume it's online
6+
return true
7+
}
8+
9+
function isDocumentVisible (): boolean {
10+
if (
11+
typeof document !== 'undefined' &&
12+
typeof document.visibilityState !== 'undefined'
13+
) {
14+
return document.visibilityState !== 'hidden'
15+
}
16+
// always assume it's visible
17+
return true
18+
}
19+
20+
const fetcher = url => fetch(url).then(res => res.json())
21+
22+
export default {
23+
isOnline,
24+
isDocumentVisible,
25+
fetcher
26+
}
27+

src/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import SWRVCache from './lib/cache'
33

44
export type fetcherFn<Data> = (...args: any) => Data | Promise<Data>
55

6-
export interface IConfig {
6+
export interface IConfig<
7+
Data = any,
8+
Fn extends fetcherFn<Data> = fetcherFn<Data>
9+
> {
710
refreshInterval?: number
811
cache?: SWRVCache
912
dedupingInterval?: number
@@ -14,6 +17,9 @@ export interface IConfig {
1417
shouldRetryOnError?: boolean
1518
errorRetryInterval?: number
1619
errorRetryCount?: number
20+
fetcher?: Fn,
21+
isOnline?: () => boolean
22+
isDocumentVisible?: () => boolean
1723
}
1824

1925
export interface IResponse<Data = any, Error = any> {

src/use-swrv.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import {
2929
onUnmounted,
3030
getCurrentInstance
3131
} from 'vue'
32-
import isDocumentVisible from './lib/is-document-visible'
33-
import isOnline from './lib/is-online'
32+
import webPreset from './lib/web-preset'
3433
import SWRVCache from './lib/cache'
3534
import { IConfig, IKey, IResponse, fetcherFn, revalidateOptions } from './types'
3635

@@ -48,7 +47,10 @@ const defaultConfig: IConfig = {
4847
revalidateDebounce: 0,
4948
shouldRetryOnError: true,
5049
errorRetryInterval: 5000,
51-
errorRetryCount: 5
50+
errorRetryCount: 5,
51+
fetcher: webPreset.fetcher,
52+
isOnline: webPreset.isOnline,
53+
isDocumentVisible: webPreset.isDocumentVisible
5254
}
5355

5456
/**
@@ -66,7 +68,7 @@ function setRefCache (key: string, theRef: StateRef<any, any>, ttl: number) {
6668
}
6769

6870
function onErrorRetry (revalidate: (any, opts: revalidateOptions) => void, errorRetryCount: number, config: IConfig): void {
69-
if (!isDocumentVisible()) {
71+
if (!config.isDocumentVisible()) {
7072
return
7173
}
7274

@@ -153,7 +155,8 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
153155
let unmounted = false
154156
let isHydrated = false
155157

156-
const vm = getCurrentInstance() as any
158+
const instance = getCurrentInstance() as any
159+
const vm = instance
157160
const IS_SERVER = vm.$isServer
158161

159162
// #region ssr
@@ -183,6 +186,11 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
183186
const ttl = IS_SERVER ? config.serverTTL : config.ttl
184187
const keyRef = typeof key === 'function' ? (key as any) : ref(key)
185188

189+
if (typeof fn === 'undefined') {
190+
// use the global fetcher
191+
fn = config.fetcher
192+
}
193+
186194
let stateRef = null as StateRef<Data, Error>
187195

188196
// #region ssr
@@ -230,7 +238,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
230238
}
231239

232240
const fetcher = data || fn
233-
if (!fetcher || !isDocumentVisible() || (opts?.forceRevalidate !== undefined && !opts?.forceRevalidate)) {
241+
if (!fetcher || !config.isDocumentVisible() || (opts?.forceRevalidate !== undefined && !opts?.forceRevalidate)) {
234242
stateRef.isValidating = false
235243
return
236244
}
@@ -289,7 +297,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
289297
// if this is the case, but continue to revalidate since promises can't
290298
// be cancelled and new hook instances might rely on promise/data cache or
291299
// from pre-fetch
292-
if (!stateRef.error && isOnline()) {
300+
if (!stateRef.error && config.isOnline()) {
293301
// if API request errored, we stop polling in this round
294302
// and let the error retry function handle it
295303
await revalidate()

tests/setupJest.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import 'whatwg-fetch'

tests/use-swrv.spec.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,23 @@ describe('useSWRV', () => {
612612

613613
done()
614614
})
615+
616+
it('should use fetch api as default fetcher', async () => {
617+
const users = [{ name: 'bob' }, { name: 'sue' }]
618+
const mockFetch = body => Promise.resolve({ json: () => Promise.resolve(body) } as any)
619+
jest.spyOn(window, 'fetch').mockImplementation(() => mockFetch(users))
620+
621+
const vm = new Vue({
622+
template: `<div v-if="data">hello, {{ data.map(u => u.name).join(' and ') }}</div>`,
623+
setup () {
624+
return useSWRV('http://localhost:3000/api/users')
625+
}
626+
}).$mount()
627+
628+
await tick(vm, 4)
629+
630+
expect(vm.$el.textContent).toBe('hello, bob and sue')
631+
})
615632
})
616633

617634
describe('useSWRV - loading', () => {

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10984,6 +10984,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
1098410984
dependencies:
1098510985
iconv-lite "0.4.24"
1098610986

10987+
whatwg-fetch@^3.5.0:
10988+
version "3.5.0"
10989+
resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868"
10990+
integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==
10991+
1098710992
whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
1098810993
version "2.3.0"
1098910994
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"

0 commit comments

Comments
 (0)