Skip to content

Commit

Permalink
feat: aggregate key and isValidate cache data
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 committed Feb 13, 2021
1 parent 65544f2 commit 864d6c3
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 29 deletions.
6 changes: 5 additions & 1 deletion examples/swr-devtools-demo/pages/api/hello.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction


let counter = 1;

export default (req, res) => {
res.status(200).json({ name: 'John Doe' })
++counter;
res.status(200).json({ name: `Hello World ${counter}`})
}
24 changes: 13 additions & 11 deletions examples/swr-devtools-demo/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import useSWR from "swr";
import { useEffect } from 'react';

export default function Home() {
const { data } = useSWR("/api/hello");
const { data, mutate } = useSWR("/api/hello");
const { data: data2 } = useSWR("/api/hello?foo");

useEffect(() => {
const timerId = setInterval(() => {
mutate();
}, 5000)
return () => clearInterval(timerId)
}, [])

return (
<div className={styles.container}>
Expand All @@ -19,18 +28,11 @@ export default function Home() {

<h2>SWR</h2>
<div>{data ? data.name : '...loading'}</div>
<div>{data2 ? data2.name : '...loading'}</div>

</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{' '}
<img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
<footer>
<p>SWR DevTools</p>
</footer>
</div>
)
Expand Down
38 changes: 22 additions & 16 deletions packages/swr-devtools/src/SWRDevTool.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import React from "react";
import * as CSS from "csstype";
import { CacheInterface } from "swr";

import { useSWRCache } from "./cache";

const style: CSS.Properties = {
position: 'fixed',
Expand All @@ -12,23 +12,29 @@ const style: CSS.Properties = {
backgroundColor: '#EEE',
}

export const SWRDevTools = ({ cache }: { cache: CacheInterface }) => {
const [cacheData, setCacheData] = useState<Array<{ key: string, data : object }>>([]);
useEffect(() => {
cache.subscribe(() => {
// validating@{key} is a key for the validating status corresponding with the key
// err@{key} is a key for the error that corresponding with the key
setCacheData(cache.keys().map(key => ({ key, data: cache.get(key)})))
})
}, [cache]);
const DataPanel = () => {
const cacheData = useSWRCache()
return (
<ul>
{cacheData.map(({ key, data, timestampString, isValidating, error }) => (
<li key={key}>
{key} ({timestampString})
<ul>
<li>data: {JSON.stringify(data)}</li>
<li>isValidating: {isValidating.toString()}</li>
<li>error: {error || 'null'}</li>
</ul>
</li>
))}
</ul>
)
}

export const SWRDevTools = ({ cache }: { cache: CacheInterface }) => {
return (
<div style={style}>
<ul>
{cacheData.map(({ key, data }) => (
<li key={key}>[{key}]: {JSON.stringify(data)}</li>
))}
</ul>
<DataPanel />
</div>
)

}
46 changes: 46 additions & 0 deletions packages/swr-devtools/src/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useState, useEffect } from "react";
import { cache } from "swr";

type CacheData = {
key: string,
data: any,
isValidating: boolean,
error: string,
timestamp: Date,
timestampString: string
}

const formatTime = (date: Date) => (
`${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`
);

const retrieveCache = (): CacheData[] => {
const date = new Date();
return cache.keys()
.filter(key => !key.startsWith("validating@") && !key.startsWith("err@"))
.map(key => {
const isValidating = cache.get(`validating@${key}`);
const error = cache.get(`err@${key}`);
const data = cache.get(key);
return {
key,
data,
isValidating,
error,
timestamp: date,
timestampString: formatTime(date)
}
})
}

export const useSWRCache = (): CacheData[] => {
const [cacheData, setCacheData] = useState<CacheData[]>([]);
useEffect(() => {
const unsubscribe = cache.subscribe(() => {
setCacheData(retrieveCache())
})
return () => unsubscribe();
}, [cache]);
return cacheData;
}

2 changes: 1 addition & 1 deletion packages/swr-devtools/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"lib": ["dom", "es2015"], /* Specify library files to be included in the compilation. */
"lib": ["dom", "es2017"], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
Expand Down

0 comments on commit 864d6c3

Please sign in to comment.