diff --git a/src/__tests__/common.test.ts b/src/__tests__/common.test.ts index 4423d9e..0b70826 100644 --- a/src/__tests__/common.test.ts +++ b/src/__tests__/common.test.ts @@ -20,18 +20,36 @@ const noop = function() {} describe('configure tests', () => { it('should configure work without custom settings', () => { const context = configure({}) - const { settings, ssrConfigs, isSSR, $isConfigured } = context + const { + settings, + collection: { ssrConfigs, cacheKeys }, + isSSR, + isConfigured + } = context expect(settings).toMatchObject({ ...defaultSettings, cache: new LRU() }) - expect(ssrConfigs).toEqual([]) - expect(typeof isSSR).toBe('boolean') - expect($isConfigured).toBe(true) + expect(ssrConfigs.length).toBe(0) + expect(cacheKeys.size).toBe(0) + expect(isSSR).toBe(false) + expect(isConfigured).toBe(true) + expect(settings.renderSSR()).toEqual('') + }) + + it('should configure as expected if the second argument isSSR = true', () => { + const context = configure({}, true) + const { settings, isSSR } = context + expect(settings).toMatchObject({ + ...defaultSettings, + cache: new LRU() + }) + expect(isSSR).toBe(true) }) it('should configure work with custom settings', () => { const customSSRConfig = [] + const customCacheKeys = new Set() const custom = { settings: { clientCacheVar: '__FOO_BAR__', @@ -39,24 +57,33 @@ describe('configure tests', () => { cache: new LRU(), maxRequests: 100, renderSSR: noop, - isSSR: noop, + isSSR: () => true, useCacheData: false, deleteAfterLoading: false }, - ssrConfigs: customSSRConfig, - isSSR: true, - $isConfigured: false + collection: { + ssrConfigs: customSSRConfig, + cacheKeys: customCacheKeys + }, + isSSR: false, + isConfigured: false } const context = configure(custom) - const { settings, ssrConfigs, isSSR, $isConfigured } = context + const { + settings, + collection: { ssrConfigs, cacheKeys }, + isSSR, + isConfigured + } = context expect(settings).toMatchObject({ ...defaultSettings, ...custom.settings }) expect(settings).not.toBe(defaultSettings) expect(ssrConfigs).not.toBe(customSSRConfig) - expect(isSSR).toBe(false) - expect($isConfigured).toBe(true) + expect(cacheKeys.size).toBe(0) + expect(isSSR).toBe(true) + expect(isConfigured).toBe(true) }) }) diff --git a/src/__tests__/ssr.test.ts b/src/__tests__/ssr.test.ts index 3285354..079e4a2 100644 --- a/src/__tests__/ssr.test.ts +++ b/src/__tests__/ssr.test.ts @@ -25,7 +25,8 @@ afterEach(() => { const copySettings = () => ({ ...defaultSettings, - cache: new LRU() + cache: new LRU(), + isSSR: () => true }) const testCache = new LRU() testCache.set('foo', 'bar') @@ -65,9 +66,10 @@ describe('feedRequests tests', () => { } }) const { - settings: { cache } + settings: { cache }, + collection } = context - context.ssrConfigs = ssrConfigs + collection.ssrConfigs = ssrConfigs const response = { data: { message: 'ok' @@ -75,7 +77,9 @@ describe('feedRequests tests', () => { } axiosAll.mockReset().mockResolvedValue(response) const ssrHtml = await feedRequests(context, '') + const { cacheKeys } = collection expect(ssrConfigs.length).toBe(0) + expect(cacheKeys.size).toBe(0) expect(ssrHtml).toBe('
Hello World!
') expect(cache.dump()).toEqual([ { k: 'abc', v: { response }, e: 0 }, @@ -102,9 +106,10 @@ describe('feedRequests tests', () => { } }) const { - settings: { cache } + settings: { cache }, + collection } = context - context.ssrConfigs = ssrConfigs + collection.ssrConfigs = ssrConfigs const error = { response: { data: { @@ -116,7 +121,18 @@ describe('feedRequests tests', () => { console.log = jest.fn() const ssrHtml = await feedRequests(context, '') expect(ssrConfigs.length).toBe(0) + expect(console.log).toHaveBeenCalledWith( + '[ReactUseApi][Collecting Requests]' + ) expect(console.log).toHaveBeenCalledWith('[ReactUseApi][Fetch]', 'foo') + expect(console.log).toHaveBeenCalledWith( + '[ReactUseApi][Requests Count] =', + 0 + ) + expect(console.log).toHaveBeenCalledWith( + '[ReactUseApi][Executed times] =', + 1 + ) expect(ssrHtml).toBe('
Hello World!
') expect(cache.dump()).toEqual([ { k: 'foo', v: { error: error.response }, e: 0 } @@ -141,9 +157,10 @@ describe('feedRequests tests', () => { } }) const { - settings: { cache } + settings: { cache }, + collection } = context - context.ssrConfigs = ssrConfigs + collection.ssrConfigs = ssrConfigs const error = { message: 'fail' } @@ -162,7 +179,9 @@ describe('feedRequests tests', () => { } }) console.log = jest.fn() - const { ssrConfigs } = context + const { + collection: { ssrConfigs } + } = context const ssrHtml = await feedRequests(context, '') expect(console.log).toHaveBeenCalledWith( '[ReactUseApi][Executed times] =', @@ -178,7 +197,8 @@ describe('feedRequests tests', () => { ...copySettings() } }) - context.ssrConfigs = [ + const { collection } = context + collection.ssrConfigs = [ { config: { url: '/api/v1/foo/bar' @@ -206,12 +226,13 @@ describe('injectSSRHtml tests', () => { renderSSR } }) - const { settings } = context + const { settings, isSSR } = context const { cache } = settings cache.reset = jest.fn() cache.dump = jest.fn().mockReturnValue({ foo: 'bar' }) expect.hasAssertions() const ssrHtml = await injectSSRHtml(context) + expect(isSSR).toBe(true) expect(renderSSR).toHaveBeenCalled() expect(cache.reset).toHaveBeenCalled() expect(feedRequests).toHaveBeenLastCalledWith(context, html) diff --git a/src/__tests__/useApi.test.tsx b/src/__tests__/useApi.test.tsx index f4c049f..6dd9a3d 100644 --- a/src/__tests__/useApi.test.tsx +++ b/src/__tests__/useApi.test.tsx @@ -92,7 +92,10 @@ describe('useApi tests', () => { dependencies: undefined, data: apiData }) - expect(context.ssrConfigs.length).toBe(0) + const { + collection: { ssrConfigs } + } = context + expect(ssrConfigs.length).toBe(0) rerender() @@ -277,7 +280,9 @@ describe('useApi tests', () => { }), { wrapper } ) - const { ssrConfigs } = context + const { + collection: { ssrConfigs, cacheKeys } + } = context expect(console.log).toHaveBeenCalledWith( '[ReactUseApi][Collect]', cacheKey @@ -290,6 +295,7 @@ describe('useApi tests', () => { cacheKey } ]) + expect(cacheKeys.size).toBe(1) expect(cache.has(feedKey)).toBe(false) }) }) diff --git a/src/common.ts b/src/common.ts index 79b0125..21e0aa3 100644 --- a/src/common.ts +++ b/src/common.ts @@ -22,8 +22,11 @@ export const initState = { $cacheKey: '' } -export const configure = (context: ReactUseApi.CustomContext) => { - if (context.$isConfigured) { +export const configure = ( + context: ReactUseApi.CustomContext, + isSSR = false +) => { + if (context.isConfigured) { return context as ReactUseApi.Context } const { settings: custom } = context @@ -37,11 +40,16 @@ export const configure = (context: ReactUseApi.CustomContext) => { } }) } + isSSR = + isSSR !== true && isFunction(settings.isSSR) ? !!settings.isSSR() : isSSR Object.assign(context, { settings, - ssrConfigs: [], - isSSR: isFunction(settings.isSSR) ? !!settings.isSSR() : false, - $isConfigured: true + isSSR, + isConfigured: true, + collection: { + ssrConfigs: [], + cacheKeys: new Set() + } as ReactUseApi.SSRCollection }) return context as ReactUseApi.Context } diff --git a/src/ssr.ts b/src/ssr.ts index 8ff9aec..b03f084 100644 --- a/src/ssr.ts +++ b/src/ssr.ts @@ -5,17 +5,23 @@ export const feedRequests = async ( ssrHtml: string, maxRequests = context.settings.maxRequests ) => { - const { settings, ssrConfigs } = context + const { + settings, + collection: { ssrConfigs, cacheKeys } + } = context const { cache, renderSSR, debug } = settings - if (!ssrConfigs.length) { - debug && + if (debug) { + console.log('[ReactUseApi][Requests Count] =', cacheKeys.size) console.log( '[ReactUseApi][Executed times] =', settings.maxRequests - maxRequests ) + } + cacheKeys.clear() return ssrHtml // done } + debug && console.log('[ReactUseApi][Collecting Requests]') if (maxRequests === 0) { throw new Error('Maximum executing times while fetching axios requests') } @@ -50,7 +56,7 @@ export const injectSSRHtml = async ( context: ReactUseApi.CustomContext, renderSSR?: ReactUseApi.Settings['renderSSR'] ) => { - context = configure(context) + context = configure(context, true) const { settings } = context settings.renderSSR = renderSSR || settings.renderSSR const { cache, useCacheData, clientCacheVar } = settings diff --git a/src/typings.d.ts b/src/typings.d.ts index 04a422f..3bcd747 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -18,14 +18,22 @@ declare namespace ReactUseApi { interface Context { settings?: Settings - ssrConfigs?: SSRConfig[] renderSSR?: Settings['renderSSR'] isSSR?: boolean - $isConfigured?: boolean + collection?: SSRCollection + isConfigured?: boolean } interface CustomContext extends Omit { settings?: CustomSettings } + interface SSRCollection { + ssrConfigs: SSRConfigs[] + cacheKeys: Set + } + interface SSRConfigs { + config: Config + cacheKey: string + } interface ApiProviderProps { context?: CustomContext } @@ -54,10 +62,6 @@ declare namespace ReactUseApi { prevState?: State dependencies?: Options['dependencies'] } - interface SSRConfig { - config: Config - cacheKey: string - } interface JsonObject { [key: string]: any } diff --git a/src/useApi.ts b/src/useApi.ts index e903a4d..0c90eaa 100644 --- a/src/useApi.ts +++ b/src/useApi.ts @@ -23,7 +23,7 @@ export const useApi = ( const { settings: { cache, debug }, isSSR, - ssrConfigs + collection: { ssrConfigs, cacheKeys } } = context const cacheKey = JSON.stringify(config) const options = useMemo(() => handleUseApiOptions(opt, cacheKey), [ @@ -49,7 +49,10 @@ export const useApi = ( cache.set(feedKey, true) } } else if (isSSR) { - debug && console.log('[ReactUseApi][Collect]', cacheKey) + if (!cacheKeys.has(cacheKey)) { + cacheKeys.add(cacheKey) + debug && console.log('[ReactUseApi][Collect]', cacheKey) + } ssrConfigs.push({ config, cacheKey