[APOLLO_DEVTOOLS] old repo deprecated + added playground (#307)

* [APOLLO_DEVTOOLS] added playground + original repo migrated
This commit is contained in:
vejrj 2023-05-15 07:36:16 +02:00 коммит произвёл GitHub
Родитель 3cc0e0357f
Коммит 1062b1f2d3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
41 изменённых файлов: 10207 добавлений и 119 удалений

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "major",
"comment": "added playground + original repo migrated",
"packageName": "@graphitation/rempl-apollo-devtools",
"email": "jakubvejr@microsoft.com",
"dependentChangeType": "patch"
}

4
examples/apollo-devtools-playground/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
node_modules
build
apollo-devtools.js
apollo-devtools.js.map

Просмотреть файл

@ -0,0 +1,22 @@
{
"name": "graphql-playground",
"private": true,
"scripts": {
"start": "DISABLE_ESLINT_PLUGIN=true react-scripts start"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"react-scripts": "^5.0.0"
}
}

Двоичные данные
examples/apollo-devtools-playground/public/favicon.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Просмотреть файл

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app with Ostapoff Basic Template"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<script type="text/javascript" src="%PUBLIC_URL%/apollo-devtools.js"></script>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Ostapoff Basic Template for CRA</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Двоичные данные
examples/apollo-devtools-playground/public/logo192.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичные данные
examples/apollo-devtools-playground/public/logo512.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.4 KiB

Просмотреть файл

@ -0,0 +1,25 @@
{
"short_name": "Ostapoff Basic",
"name": "Ostapoff Basic Template for CRA",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Просмотреть файл

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

Просмотреть файл

@ -0,0 +1,26 @@
import { ApolloProvider } from "@apollo/client";
import { buildClient } from "data/data-builder";
import ChatContainer from "./chat/chat-container";
import { FluentProvider, teamsLightTheme } from "@fluentui/react-components";
const client = buildClient();
const client2 = buildClient();
if ((window as any) && !(window as any).__APOLLO_CLIENTS__?.length) {
(window as any).__APOLLO_CLIENTS__ = [
{ client, clientId: "main" },
{ client: client2, clientId: "emptyClient" },
];
}
const App = () => {
return (
<FluentProvider theme={teamsLightTheme}>
<ApolloProvider client={client}>
<ChatContainer />
</ApolloProvider>
</FluentProvider>
);
};
export default App;

Просмотреть файл

@ -0,0 +1,114 @@
import React from "react";
import { useApolloClient } from "@apollo/client/react";
import { useQuery, gql, useMutation } from "@apollo/client";
import { ChatRenderer } from "./chat-renderer";
const CHAT = gql`
query Chat {
chat {
messages {
id
}
}
}
`;
const ADD_MESSAGES = gql`
mutation addMessage($message: String!) {
addMessage(message: $message) {
id
message
}
}
`;
const REMOVE_MESSAGE = gql`
mutation removeMessage($id: ID!) {
removeMessage(id: $id)
}
`;
const ChatContainer = () => {
const client = useApolloClient();
const cache = client.cache as any;
const { data } = useQuery(CHAT);
const [addMessage] = useMutation(ADD_MESSAGES);
const [removeMessage] = useMutation(REMOVE_MESSAGE);
const addMessageFunction = React.useCallback((message: string) => {
addMessage({
variables: { message },
update(cache, mutationResult) {
cache.modify({
fields: {
chat: (previous, { toReference }) => {
return [
...(previous?.messages || []),
toReference(mutationResult.data.addMessage),
];
},
},
});
},
});
}, []);
const removeMessageFunction = React.useCallback((id) => {
removeMessage({
variables: { id },
update(cache) {
cache.modify({
fields: {
chat: (previous) => {
return [
previous.messages.filter(
({ messageId }: { messageId: string[] }) => messageId !== id,
),
];
},
},
});
const normalizedId = cache.identify({ id, __typename: "Message" });
cache.evict({ id: normalizedId });
cache.gc();
},
});
}, []);
React.useEffect(() => {
const defaultData = ["test2", "test", "test", "test", "test2"];
for (const message of defaultData) {
addMessage({
variables: { message },
update(cache, mutationResult) {
cache.modify({
fields: {
chat: (previous, { toReference }) => {
return [
...(previous?.messages || []),
toReference(mutationResult.data.addMessage),
];
},
},
});
},
});
}
}, []);
if (!cache) {
return null;
}
return (
<div>
<ChatRenderer
ids={data?.chat?.messages?.map(({ id }: { id: string }) => id) || []}
removeMessage={removeMessageFunction}
addMessage={addMessageFunction}
/>
</div>
);
};
export default ChatContainer;

Просмотреть файл

@ -0,0 +1,25 @@
import { makeStyles, shorthands, tokens } from "@fluentui/react-components";
export const useChatRendererStyles = makeStyles({
title: {
...shorthands.padding("15px"),
},
inputContainer: {
display: "flex",
...shorthands.padding("15px"),
},
input: {
display: "inline-block",
boxSizing: "border-box",
width: "300px",
height: "32px",
marginRight: "20px",
...shorthands.padding(0, 0, 0, "5px"),
...shorthands.border("1px", "solid", tokens.colorNeutralBackground2Pressed),
...shorthands.borderRadius("6px"),
outlineStyle: "none",
"&:focus": {
...shorthands.borderColor("#97CBFF"),
},
},
});

Просмотреть файл

@ -0,0 +1,39 @@
import React from "react";
import { Messages } from "./messages";
import { Title2, Button } from "@fluentui/react-components";
import { useChatRendererStyles } from "./chat-renderer.styles";
interface IChatRenderer {
ids: string[];
removeMessage: (id: string) => void;
addMessage: (message: string) => void;
}
export const ChatRenderer = ({
ids,
removeMessage,
addMessage,
}: IChatRenderer) => {
const [messageText, setMessageText] = React.useState("");
const styles = useChatRendererStyles();
return (
<>
<Title2 block className={styles.title}>
Chat example
</Title2>
<div className={styles.inputContainer}>
<input
className={styles.input}
placeholder="Message"
onChange={(e: React.SyntheticEvent) => {
const input = e.target as HTMLInputElement;
setMessageText(input.value);
}}
/>
<Button onClick={() => addMessage(messageText)}>Add Message</Button>
</div>
<Messages ids={ids} removeMessage={removeMessage} />
</>
);
};

Просмотреть файл

@ -0,0 +1,17 @@
import React from "react";
import { useQuery, gql } from "@apollo/client";
const MESSAGE = gql`
query message($id: ID) {
message(id: $id) {
id
message
}
}
`;
export default ({ id }: { id: string }) => {
const { data } = useQuery(MESSAGE, { variables: { id } });
return <div>{data?.message?.message}</div>;
};

Просмотреть файл

@ -0,0 +1,24 @@
import { makeStyles, shorthands } from "@fluentui/react-components";
export const useMessagesStyles = makeStyles({
itemContainer: {
display: "grid",
gridTemplateColumns: "auto 450px 150px",
alignItems: "center",
...shorthands.padding("10px", "20px"),
...shorthands.borderBottom("1px", "solid", "#F5F5F5"),
"&:hover": {
backgroundColor: "#F5F5F6",
},
},
idColumn: {
...shorthands.overflow("hidden"),
textOverflow: "ellipsis",
whiteSpace: "nowrap",
},
button: {
minWidth: "auto",
height: "auto",
...shorthands.padding("3px", "12px"),
},
});

Просмотреть файл

@ -0,0 +1,46 @@
import { Button, Text } from "@fluentui/react-components";
import Message from "./message";
import { useMessagesStyles } from "./messages.styles";
interface IMessages {
ids: string[];
removeMessage: (id: string) => void;
}
export const Messages = ({ ids, removeMessage }: IMessages) => {
const classes = useMessagesStyles();
const buildMessages = () => (id: string) =>
(
<div className={classes.itemContainer} key={id}>
<div className={classes.idColumn}>{id}</div>
<Message id={id} />
<div>
<Button
appearance="primary"
className={classes.button}
size="small"
onClick={() => {
removeMessage(id);
}}
>
Remove message
</Button>
</div>
</div>
);
return (
<div>
<div className={classes.itemContainer}>
<Text size={200} weight="semibold">
ID
</Text>
<Text size={200} weight="semibold">
Value
</Text>
</div>
{ids.map(buildMessages())}
</div>
);
};

Просмотреть файл

@ -0,0 +1,57 @@
import {
ApolloClient,
from,
NormalizedCacheObject,
InMemoryCache,
Resolvers as ApolloResolvers,
} from "@apollo/client";
import { makeExecutableSchema } from "@graphql-tools/schema";
import {
messageResolver,
addMessageResolver,
removeMessageResolver,
chatResolver,
} from "./resolver/resolvers";
import createGraphQLContext, { IGraphQLContext } from "./graphql-context";
import typeDefs from "./typeDefs";
import { SchemaLink } from "@apollo/client/link/schema";
export const buildClient: () => ApolloClient<NormalizedCacheObject> = () => {
const schema = makeExecutableSchema<IGraphQLContext>({
typeDefs,
resolvers: buildResolvers(),
});
return new ApolloClient({
cache: new InMemoryCache({}),
connectToDevTools: true,
link: from([
new SchemaLink({
schema: schema,
context: createGraphQLContext(),
}),
]),
});
};
const queryResolvers = {
message: messageResolver,
chat: chatResolver,
};
const mutationResolvers = {
addMessage: addMessageResolver,
removeMessage: removeMessageResolver,
};
const buildResolvers: () => ApolloResolvers = () => {
const resolvers = {
Query: queryResolvers,
Mutation: mutationResolvers,
};
return resolvers as ApolloResolvers;
};

Просмотреть файл

@ -0,0 +1,48 @@
import { v4 as uid } from "uuid";
type Message = {
id: string;
message: string;
};
export type Chat = {
messages: Message[];
};
export interface IGraphQLContext {
message: (id: string) => Message;
addMessage: (message: string) => Message;
chat: () => Chat;
removeMessage: (id: string) => boolean;
}
const createGraphQLContext: () => IGraphQLContext = () => {
return new GraphQLContext();
};
export default createGraphQLContext;
class GraphQLContext implements IGraphQLContext {
private static messages: Message[] = [];
addMessage = (message: string) => {
const id = uid();
GraphQLContext.messages.push({ id, message });
const newMessage = GraphQLContext.messages.find((value) => id === value.id);
return newMessage as Message;
};
chat = () => {
return {
messages: GraphQLContext.messages,
};
};
message = (id: string) => {
const message = GraphQLContext.messages.find((value) => id === value.id);
return message as Message;
};
removeMessage = (id: string) => {
const messages = GraphQLContext.messages.filter((value) => id !== value.id);
GraphQLContext.messages = messages;
return true;
};
}

Просмотреть файл

@ -0,0 +1,33 @@
import { IGraphQLContext } from "data/graphql-context";
export const chatResolver = (
_: object,
parameters: any,
context: IGraphQLContext,
) => {
return context.chat();
};
export const addMessageResolver = (
_: object,
{ message }: any,
context: IGraphQLContext,
) => {
return context.addMessage(message);
};
export const messageResolver = (
_: object,
{ id }: any,
context: IGraphQLContext,
) => {
return context.message(id);
};
export const removeMessageResolver = (
_: object,
{ id }: any,
context: IGraphQLContext,
) => {
return context.removeMessage(id);
};

Просмотреть файл

@ -0,0 +1,22 @@
const typeDefs = `
type Message {
id: ID!
message: String!
}
type Chat {
messages: [Message]!
}
type Query {
message(id: ID!): Message!
chat: Chat!
}
type Mutation {
addMessage(message: String!): Message!
removeMessage(id: ID!): Boolean!
}
`;
export default typeDefs;

Просмотреть файл

@ -0,0 +1,3 @@
export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

Просмотреть файл

@ -0,0 +1,8 @@
/** @jsxImportSource @emotion/react */
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/app";
ReactDOM.render(<App />, document.getElementById("root"));

1
examples/apollo-devtools-playground/src/react-app-env.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
/// <reference types="react-scripts" />

Просмотреть файл

@ -0,0 +1,149 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === "localhost" ||
// [::1] is the IPv6 localhost address.
window.location.hostname === "[::1]" ||
// 127.0.0.0/8 are considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
),
);
type Config = {
onSuccess?: (registration: ServiceWorkerRegistration) => void;
onUpdate?: (registration: ServiceWorkerRegistration) => void;
};
export function register(config?: Config) {
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(
process.env.PUBLIC_URL || "",
window.location.href,
);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener("load", () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
"This web app is being served cache-first by a service " +
"worker. To learn more, visit https://bit.ly/CRA-PWA",
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl: string, config?: Config) {
navigator.serviceWorker
.register(swUrl)
.then((registration) => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === "installed") {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
"New content is available and will be used when all " +
"tabs for this page are closed. See https://bit.ly/CRA-PWA.",
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log("Content is cached for offline use.");
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch((error) => {
console.error("Error during service worker registration:", error);
});
}
function checkValidServiceWorker(swUrl: string, config?: Config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl, {
headers: { "Service-Worker": "script" },
})
.then((response) => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get("content-type");
if (
response.status === 404 ||
(contentType != null && contentType.indexOf("javascript") === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
"No internet connection found. App is running in offline mode.",
);
});
}
export function unregister() {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.ready
.then((registration) => {
registration.unregister();
})
.catch((error) => {
console.error(error.message);
});
}
}

Просмотреть файл

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom/extend-expect";

Просмотреть файл

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": "src",
"noFallthroughCasesInSwitch": true
},
"include": [
"src"
]
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,3 +1,99 @@
# Rempl Apollo devtools
# Apollo Devtools
Original repository https://github.com/microsoft/rempl-graphql-devtools
## Features
Rempl Apollo Devtools allows you to debug multiple apollo clients. This tool contains the following features:
### Cache inspector
- Allow seeing the content of the cache and allows you to remove a specific object from the cache. Possibility to record only recent changes.
![plot](./docs/cache-inspector.png)
### Watched Query and Mutation inspector
Observe active queries, or recently fired mutations.
![plot](./docs/operations-monitor.png)
### Recent Activity
[EXPERIMENTAL FEATURE - Results may not be 100% accurate] It monitors changes in cache, fired mutations and activated/deactivated queries.
![plot](./docs/recent-activity.png)
### Operations Tracker
It records all the operations done via Apollo client. [More info](./docs/operations-tracker.md)
### GraphiQL
Allows sending custom queries (using https://github.com/graphql/graphiql)
![plot](./docs/graphiql.png)
## Playground
You can try the devtools using `yarn playground`
## Installation
1. First off, you need to include the bundled library's script into your site.
```
yarn add rempl-graphql-devtools
```
include `dist/apollo-devtools.js` in Webpack
```
webpackConfig.entry["apollodevtools"] = PROJECT_ROOT("node_modules/rempl-graphql-devtools/dist/apollo-devtools.js");
```
OR
build the library and include `<script>` with `dist/apollo-devtools.js`in your HTML page.
`<script src="path/apollo-devtools.js"></script>`
2. In your project, you need to attach the apollo client(s) instance into the global variable **APOLLO_CLIENTS**
```
const client = new ApolloClient({
uri: 'https://48p1r2roz4.sse.codesandbox.io',
cache: new InMemoryCache()
});
window.__APOLLO_CLIENTS__ = [{client, clientId: "custom_name"}]
```
## Usage
### Mac
To open devtools press cmd+option+shift+0
### Windows
To open devtools press ctrl+alt+shift+0
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.

Двоичные данные
packages/rempl-apollo-devtools/docs/affected-queries-view.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 208 KiB

Двоичные данные
packages/rempl-apollo-devtools/docs/cache-inspector.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 231 KiB

Двоичные данные
packages/rempl-apollo-devtools/docs/graphiql.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 343 KiB

Двоичные данные
packages/rempl-apollo-devtools/docs/operation-tracker-result.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 428 KiB

Двоичные данные
packages/rempl-apollo-devtools/docs/operations-monitor.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 144 KiB

Двоичные данные
packages/rempl-apollo-devtools/docs/operations-tracker-copy.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 78 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 293 KiB

Просмотреть файл

@ -0,0 +1,81 @@
# Operations Tracker
Records all operations being executed via Apollo client in a given time and shows info about each operation.
![plot](./operation-tracker-result.png)
## What kind of issues can be debugged using the tool
- Helps figuring out `unwanted operations` being fired in render phase
- Help in figuring out the reasons for `multiple re-renders` of the same watch query
- Help figuring out issues with `conflicting queries`
- Shows field name in case `missing field error`
- Detailed time info lets you figure out if queries are being fired in `Waterfall model` or not.
- Helps figuring out if `data is taking too much time` to get written to cache.
## Built in features
- Tracks all operations Query, Mutation, subscription, client.readQuery, client.writeQuery, cache.readQuery, cache.writeQuery, client.readFragment, client.writeFragment, cache.readFragment, cache.writeFragment.
- For each operations, below info is available
- Operation Name
- Operation Type
- Failure or Succeded
- Fetch policy
- Total execution time
- Operation queued at time
- Size in KB of the result of the Operation
- There are filters present using which, one can filter operations list
- Operation type filter (Query/Mutation/Subscription)
- Results from filter (Cache/Network)
- Operation Status (Succeeded/Failed)
- It also shows which all operations are responsible for re-rendering of an query in `Affected Queries` view
- It allows you copy operations data in JSON format.
## How to use
1. Go to Operations tracker
2. Click on Record button
3. Do some changes in UI.
4. Click on Stop button
![plot](./operation-tracker-result.png) 5. Click on a operation to see detailed view
![plot](./operations-tracker-detailed-view.png)
6. One can select operation to copy by checking the checkboxes for each operation.
## Filter options
- Supports comma separate search text to search multiple operations
- Filter by Operation type (Query/Mutation/Subscription)
- Filter by from where the result is being fetched (Cache/Network)
- Filter by operation status (Succeded/Failed)
## Copy options
![plot](./operations-tracker-copy.png)
### Copy All Operations
It copies all the operations which have been recorded
### Copy Filtered Operations
It copies only the current view of the operations
### Copy Checked Operations
It copies only those operations, whose check boxes are checked
### Copy currently Opened Operatio
It copies the operation, which is currently opened in the detailed view
### Copy Whole Apollo Cache
It copies the whole Apollo Cache object
## Affected Queries view
This view shows what operations led to re-render of a given query.
On the left side is the list of queries which have been re-rendered and on the right side, it shows what all operation caused it.
![plot](./affected-queries-view.png)

Двоичные данные
packages/rempl-apollo-devtools/docs/recent-activity.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 53 KiB

Просмотреть файл

@ -9,6 +9,7 @@
"directory": "packages/apollo-devtools"
},
"scripts": {
"playground": "watch 'node scripts/playground' ./src & (cd ../../examples/apollo-devtools-playground && yarn && yarn start)",
"build": "node scripts/build-single-bundle && node scripts/build-separated-bundles",
"watch": "watch 'node scripts/build.js'",
"lint": "monorepo-scripts lint",
@ -18,10 +19,12 @@
},
"devDependencies": {
"@apollo/client": "^3.4.11",
"@emotion/react": "^11.8.1",
"@fluentui/react-components": "^9.0.0-rc.15",
"@fluentui/react-data-grid-react-window": "^9.0.0-beta.14",
"@fluentui/react-icons": "2.0.166-rc.3",
"@fluentui/react-tabster": "^9.0.0-rc.14",
"@graphql-tools/schema": "^7.1.5",
"@types/lodash.debounce": "^4.0.6",
"@types/lodash.isequal": "^4.5.5",
"@types/react": "^17.0.2",
@ -30,8 +33,8 @@
"@types/react-router-dom": "^5.3.3",
"@types/uuid": "^8.3.4",
"apollo-inspector": "^1.16.3",
"eslint-plugin-react": "^7.25.2",
"graphiql": "^2.0.9",
"graphql": "^15.6.1",
"hotkeys-js": "^3.8.7",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0",
@ -41,7 +44,9 @@
"react-dom": "^17.0.2",
"react-router-dom": "^5.3.3",
"rempl": "^1.0.0-alpha.24",
"uuid": "^8.3.2"
"scheduler": "^0.20.2",
"uuid": "^8.3.2",
"watch": "^1.0.2"
},
"publishConfig": {
"main": "./dist/apollo-devtools.js",

Просмотреть файл

@ -0,0 +1,48 @@
const esbuild = require("esbuild");
var { readFileSync } = require("fs");
var { resolve } = require("path");
if (require.main === module) {
(async () => {
const __APOLLO_DEVTOOLS_SUBSCRIBER__ = (
await esbuild.build({
entryPoints: ["src/subscriber/index.tsx"],
write: false,
minify: false,
bundle: true,
format: "iife",
sourcemap: true,
define: {
__GRAPHIQL_CSS__: JSON.stringify(
readFileSync(
resolve(process.cwd(), "scripts/graphiql.min.css"),
"utf8",
),
),
__GLOBAL_CSS__: JSON.stringify(
readFileSync(
resolve(process.cwd(), "src/subscriber/styles.css"),
"utf8",
),
),
},
})
).outputFiles[0].text;
return esbuild.build({
entryPoints: ["src/publisher/index.ts"],
write: true,
bundle: true,
minify: false,
sourcemap: false,
outfile:
"../../examples/apollo-devtools-playground/public/apollo-devtools.js",
format: "iife",
define: {
__APOLLO_DEVTOOLS_SUBSCRIBER__: JSON.stringify(
__APOLLO_DEVTOOLS_SUBSCRIBER__,
),
},
});
})();
}

Просмотреть файл

@ -23,6 +23,13 @@ export class RemplWrapper {
constructor(enableRemplHotkey: string) {
this.publisher = createPublisher("apollo-devtools", () => {
if (
!browserWindow.__REMPL_APOLLO_DEVTOOLS_URL__ &&
__APOLLO_DEVTOOLS_SUBSCRIBER__
) {
return { type: "script", value: __APOLLO_DEVTOOLS_SUBSCRIBER__ };
}
return {
type: "url",
value: browserWindow.__REMPL_APOLLO_DEVTOOLS_URL__ || "",

266
yarn.lock
Просмотреть файл

@ -1146,6 +1146,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/template@^7.12.13", "@babel/template@^7.3.3":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
@ -1343,11 +1350,99 @@
is-absolute "^1.0.0"
is-negated-glob "^1.0.0"
"@emotion/babel-plugin@^11.11.0":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c"
integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
dependencies:
"@babel/helper-module-imports" "^7.16.7"
"@babel/runtime" "^7.18.3"
"@emotion/hash" "^0.9.1"
"@emotion/memoize" "^0.8.1"
"@emotion/serialize" "^1.1.2"
babel-plugin-macros "^3.1.0"
convert-source-map "^1.5.0"
escape-string-regexp "^4.0.0"
find-root "^1.1.0"
source-map "^0.5.7"
stylis "4.2.0"
"@emotion/cache@^11.11.0":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff"
integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
dependencies:
"@emotion/memoize" "^0.8.1"
"@emotion/sheet" "^1.2.2"
"@emotion/utils" "^1.2.1"
"@emotion/weak-memoize" "^0.3.1"
stylis "4.2.0"
"@emotion/hash@^0.9.0":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7"
integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==
"@emotion/hash@^0.9.1":
version "0.9.1"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
"@emotion/memoize@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
"@emotion/react@^11.8.1":
version "11.11.0"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02"
integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw==
dependencies:
"@babel/runtime" "^7.18.3"
"@emotion/babel-plugin" "^11.11.0"
"@emotion/cache" "^11.11.0"
"@emotion/serialize" "^1.1.2"
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
"@emotion/utils" "^1.2.1"
"@emotion/weak-memoize" "^0.3.1"
hoist-non-react-statics "^3.3.1"
"@emotion/serialize@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51"
integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==
dependencies:
"@emotion/hash" "^0.9.1"
"@emotion/memoize" "^0.8.1"
"@emotion/unitless" "^0.8.1"
"@emotion/utils" "^1.2.1"
csstype "^3.0.2"
"@emotion/sheet@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec"
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
"@emotion/unitless@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
"@emotion/utils@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4"
integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
"@emotion/weak-memoize@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
"@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d"
@ -4295,17 +4390,6 @@ array-each@^1.0.0, array-each@^1.0.1:
resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
array-includes@^3.1.4, array-includes@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.4"
es-abstract "^1.19.5"
get-intrinsic "^1.1.1"
is-string "^1.0.7"
array-initial@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795"
@ -4336,7 +4420,7 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
array.prototype.flatmap@^1.2.4, array.prototype.flatmap@^1.3.0:
array.prototype.flatmap@^1.2.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
@ -4459,6 +4543,15 @@ babel-plugin-jest-hoist@^29.2.0:
"@types/babel__core" "^7.1.14"
"@types/babel__traverse" "^7.0.6"
babel-plugin-macros@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
dependencies:
"@babel/runtime" "^7.12.5"
cosmiconfig "^7.0.0"
resolve "^1.19.0"
babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0:
version "7.0.0-beta.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf"
@ -5364,6 +5457,11 @@ constant-case@^3.0.4:
tslib "^2.0.3"
upper-case "^2.0.2"
convert-source-map@^1.5.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
@ -5689,13 +5787,6 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
dependencies:
esutils "^2.0.2"
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@ -5820,7 +5911,7 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5:
es-abstract@^1.19.0, es-abstract@^1.19.2, es-abstract@^1.19.5:
version "1.20.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
@ -5961,26 +6052,6 @@ eslint-plugin-prettier@^4.0.0:
dependencies:
prettier-linter-helpers "^1.0.0"
eslint-plugin-react@^7.25.2:
version "7.30.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz#8e7b1b2934b8426ac067a0febade1b13bd7064e3"
integrity sha512-RgwH7hjW48BleKsYyHK5vUAvxtE9SMPDKmcPRQgtRCYaZA0XQPt5FSkrU3nhz5ifzMZcA8opwmRJ2cmOO8tr5A==
dependencies:
array-includes "^3.1.5"
array.prototype.flatmap "^1.3.0"
doctrine "^2.1.0"
estraverse "^5.3.0"
jsx-ast-utils "^2.4.1 || ^3.0.0"
minimatch "^3.1.2"
object.entries "^1.1.5"
object.fromentries "^2.0.5"
object.hasown "^1.1.1"
object.values "^1.1.5"
prop-types "^15.8.1"
resolve "^2.0.0-next.3"
semver "^6.3.0"
string.prototype.matchall "^4.0.7"
eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
@ -6093,11 +6164,6 @@ estraverse@^5.1.0, estraverse@^5.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
estraverse@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@ -6118,6 +6184,13 @@ events@^3.0.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
exec-sh@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==
dependencies:
merge "^1.2.0"
execa@^4.0.0, execa@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
@ -6418,6 +6491,11 @@ filter-obj@^1.1.0:
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
@ -7103,7 +7181,7 @@ history@^4.9.0:
tiny-warning "^1.0.0"
value-equal "^1.0.1"
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -8261,14 +8339,6 @@ jsonwebtoken@^8.5.1:
ms "^2.1.1"
semver "^5.6.0"
"jsx-ast-utils@^2.4.1 || ^3.0.0":
version "3.3.0"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz#e624f259143b9062c92b6413ff92a164c80d3ccb"
integrity sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==
dependencies:
array-includes "^3.1.4"
object.assign "^4.1.2"
just-debounce@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf"
@ -8776,6 +8846,11 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
merge@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
meros@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/meros/-/meros-1.1.4.tgz#c17994d3133db8b23807f62bec7f0cb276cfd948"
@ -8870,7 +8945,7 @@ minimatch@4.2.1, minimatch@^4.0.0:
dependencies:
brace-expansion "^1.1.7"
minimatch@^3.1.1, minimatch@^3.1.2:
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@ -9207,32 +9282,6 @@ object.defaults@^1.0.0, object.defaults@^1.1.0:
for-own "^1.0.0"
isobject "^3.0.0"
object.entries@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.1"
object.fromentries@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.1"
object.hasown@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3"
integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==
dependencies:
define-properties "^1.1.4"
es-abstract "^1.19.5"
object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
@ -9248,15 +9297,6 @@ object.reduce@^1.0.0:
for-own "^1.0.0"
make-iterator "^1.0.0"
object.values@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.1"
once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@ -9703,7 +9743,7 @@ prompts@~2.1.0:
kleur "^3.0.2"
sisteransi "^1.0.0"
prop-types@^15.6.2, prop-types@^15.8.1:
prop-types@^15.6.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -9985,6 +10025,11 @@ redeyed@~2.1.0:
dependencies:
esprima "~4.0.0"
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.13.4:
version "0.13.7"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
@ -9998,7 +10043,7 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3:
regexp.prototype.flags@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
@ -10181,14 +10226,6 @@ resolve@^1.20.0:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^2.0.0-next.3:
version "2.0.0-next.3"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==
dependencies:
is-core-module "^2.2.0"
path-parse "^1.0.6"
resolve@~1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
@ -10563,7 +10600,7 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@^0.5.0, source-map@^0.5.6:
source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
@ -10687,20 +10724,6 @@ string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string.prototype.matchall@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
es-abstract "^1.19.1"
get-intrinsic "^1.1.1"
has-symbols "^1.0.3"
internal-slot "^1.0.3"
regexp.prototype.flags "^1.4.1"
side-channel "^1.0.4"
string.prototype.trimend@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
@ -10793,6 +10816,11 @@ strip-outer@^1.0.1:
dependencies:
escape-string-regexp "^1.0.2"
stylis@4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51"
integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
stylis@^4.0.13:
version "4.1.1"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12"
@ -11555,6 +11583,14 @@ walker@^1.0.8:
dependencies:
makeerror "1.0.12"
watch@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c"
integrity sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==
dependencies:
exec-sh "^0.2.0"
minimist "^1.2.0"
wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"