From 223a7480c96ad879bc8ff07fad38b657ec132606 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:18:37 -0600 Subject: [PATCH 01/77] Add handler to get memory internals --- src/extension/rpc.ts | 6 ++++++ src/extension/tab/hook.ts | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/extension/rpc.ts b/src/extension/rpc.ts index d9596d369..39466bb55 100644 --- a/src/extension/rpc.ts +++ b/src/extension/rpc.ts @@ -7,6 +7,11 @@ import { deserializeError, serializeError } from "./errorSerialization"; import type { MessageAdapter } from "./messageAdapters"; import { MessageType, isDevtoolsMessage } from "./messages"; import type { MutationDetails, QueryDetails } from "./tab/helpers"; +import type { ApolloClient } from "@apollo/client"; + +type MemoryInternals = ReturnType< + NonNullable["getMemoryInternals"]> +>; export type RPCRequest = { getClients(): ApolloClientInfo[]; @@ -15,6 +20,7 @@ export type RPCRequest = { getMutations(clientId: string): MutationDetails[]; getCache(clientId: string): JSONObject; getErrorCodes(version: string): Promise; + getMemoryInternals(clientId: string): MemoryInternals | undefined; }; export interface RpcClient { diff --git a/src/extension/tab/hook.ts b/src/extension/tab/hook.ts index d17d42f97..7b7a11861 100755 --- a/src/extension/tab/hook.ts +++ b/src/extension/tab/hook.ts @@ -131,6 +131,12 @@ handleRpc("getCache", (clientId) => { return getClientById(clientId)?.cache.extract(true) ?? {}; }); +handleRpc("getMemoryInternals", (clientId) => { + const client = getClientById(clientId); + + return client?.getMemoryInternals?.(); +}); + function getClientById(clientId: string) { const [client] = [...knownClients.entries()].find(([, id]) => id === clientId) ?? []; From 5d95f2caac706d3351b5fc8b26e476b2d2607444 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:31:21 -0600 Subject: [PATCH 02/77] Move MemoryInternals type to types --- src/extension/rpc.ts | 12 ++++++------ src/types.ts | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/extension/rpc.ts b/src/extension/rpc.ts index 39466bb55..0a0ea6637 100644 --- a/src/extension/rpc.ts +++ b/src/extension/rpc.ts @@ -1,17 +1,17 @@ import type { ErrorCodes } from "@apollo/client/invariantErrorCodes"; import type { JSONObject } from "../application/types/json"; -import type { ApolloClientInfo, NoInfer, SafeAny } from "../types"; +import type { + ApolloClientInfo, + MemoryInternals, + NoInfer, + SafeAny, +} from "../types"; import { createId } from "../utils/createId"; import { RPC_MESSAGE_TIMEOUT } from "./errorMessages"; import { deserializeError, serializeError } from "./errorSerialization"; import type { MessageAdapter } from "./messageAdapters"; import { MessageType, isDevtoolsMessage } from "./messages"; import type { MutationDetails, QueryDetails } from "./tab/helpers"; -import type { ApolloClient } from "@apollo/client"; - -type MemoryInternals = ReturnType< - NonNullable["getMemoryInternals"]> ->; export type RPCRequest = { getClients(): ApolloClientInfo[]; diff --git a/src/types.ts b/src/types.ts index f18c0bc4a..b06968bf1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type { ApolloQueryResult } from "@apollo/client"; +import type { ApolloClient, ApolloQueryResult } from "@apollo/client"; export type QueryResult = ApolloQueryResult; @@ -26,3 +26,7 @@ export interface ApolloClientInfo { queryCount: number; mutationCount: number; } + +export type MemoryInternals = ReturnType< + NonNullable["getMemoryInternals"]> +>; From 9cd26709999233feb4857d0d51479e439f8ee4d7 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:31:46 -0600 Subject: [PATCH 03/77] Add mapping for MemoryInternals type --- codegen.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen.ts b/codegen.ts index 54b7eba57..e54b114f8 100644 --- a/codegen.ts +++ b/codegen.ts @@ -52,6 +52,7 @@ const config: CodegenConfig = { Client: "../../types.ts#ApolloClientInfo", ClientQueries: "../../types.ts#ApolloClientInfo", ClientMutations: "../../types.ts#ApolloClientInfo", + MemoryInternals: "../../types.ts#MemoryInternals", SerializedApolloError: "../../extension/tab/helpers#SerializedApolloError as RpcSerializedApolloError", SerializedError: From fa48cbb90ea833ff429d886af9b9bfecb21b546f Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:44:31 -0600 Subject: [PATCH 04/77] Add field for memoryInternals to localSchema --- src/application/localSchema.graphql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index 3d55a36bd..fb187b185 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -25,6 +25,12 @@ type Client { queries: ClientQueries! mutations: ClientMutations! cache: Cache! + memoryInternals: MemoryInternals +} + +type MemoryInternals { + limits: JSON! + sizes: JSON! } type ClientQueries { From 674622240f9cd2086cc5df002ab95738a321b58b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:44:52 -0600 Subject: [PATCH 05/77] Add resolution for memoryInternals in schema --- src/application/schema.ts | 8 ++++++++ src/application/types/resolvers.ts | 27 ++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/application/schema.ts b/src/application/schema.ts index d58a662fc..14588bb80 100644 --- a/src/application/schema.ts +++ b/src/application/schema.ts @@ -24,6 +24,14 @@ function createResolvers(client: RpcClient): Resolvers { queries: (client) => client, mutations: (client) => client, cache: (client) => rpcClient.request("getCache", client.id), + memoryInternals: async (client) => { + const memoryInternals = await rpcClient.request( + "getMemoryInternals", + client.id + ); + + return memoryInternals ?? null; + }, }, ClientQueries: { total: (client) => client.queryCount, diff --git a/src/application/types/resolvers.ts b/src/application/types/resolvers.ts index 5b0c412d8..d289d6c6a 100644 --- a/src/application/types/resolvers.ts +++ b/src/application/types/resolvers.ts @@ -7,7 +7,7 @@ import type { GraphQLScalarType, GraphQLScalarTypeConfig, } from "graphql"; -import type { ApolloClientInfo } from "../../types.ts"; +import type { ApolloClientInfo, MemoryInternals } from "../../types.ts"; import type { SerializedApolloError as RpcSerializedApolloError, SerializedError as RpcSerializedError, @@ -60,6 +60,7 @@ export type Client = { __typename?: "Client"; cache: Scalars["Cache"]["output"]; id: Scalars["String"]["output"]; + memoryInternals?: Maybe; mutations: ClientMutations; name?: Maybe; queries: ClientQueries; @@ -84,6 +85,12 @@ export type GraphQlErrorSourceLocation = { line: Scalars["Int"]["output"]; }; +export type MemoryInternals = { + __typename?: "MemoryInternals"; + limits: Scalars["JSON"]["output"]; + sizes: Scalars["JSON"]["output"]; +}; + export type Query = { __typename?: "Query"; client?: Maybe; @@ -272,6 +279,7 @@ export type ResolversTypes = { ID: ResolverTypeWrapper; Int: ResolverTypeWrapper; JSON: ResolverTypeWrapper; + MemoryInternals: ResolverTypeWrapper; Query: ResolverTypeWrapper; QueryData: ResolverTypeWrapper; QueryOptions: ResolverTypeWrapper; @@ -312,6 +320,7 @@ export type ResolversParentTypes = { ID: Scalars["ID"]["output"]; Int: Scalars["Int"]["output"]; JSON: Scalars["JSON"]["output"]; + MemoryInternals: MemoryInternals; Query: never; QueryData: Scalars["QueryData"]["output"]; QueryOptions: Scalars["QueryOptions"]["output"]; @@ -344,6 +353,11 @@ export type ClientResolvers< > = { cache?: Resolver; id?: Resolver; + memoryInternals?: Resolver< + Maybe, + ParentType, + ContextType + >; mutations?: Resolver< ResolversTypes["ClientMutations"], ParentType, @@ -403,6 +417,16 @@ export interface JsonScalarConfig name: "JSON"; } +export type MemoryInternalsResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["MemoryInternals"] = ResolversParentTypes["MemoryInternals"], +> = { + limits?: Resolver; + sizes?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type QueryResolvers< ContextType = any, ParentType extends @@ -586,6 +610,7 @@ export type Resolvers = { GraphQLErrorPath?: GraphQLScalarType; GraphQLErrorSourceLocation?: GraphQlErrorSourceLocationResolvers; JSON?: GraphQLScalarType; + MemoryInternals?: MemoryInternalsResolvers; Query?: QueryResolvers; QueryData?: GraphQLScalarType; QueryOptions?: GraphQLScalarType; From 7799245e901e4713646de811082ee593cc6ed78b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:45:12 -0600 Subject: [PATCH 06/77] Add a MemoryInternals component --- src/application/App.tsx | 7 +++ .../components/Layouts/Navigation.tsx | 1 + .../components/MemoryInternals.tsx | 47 +++++++++++++++++++ src/application/types/gql.ts | 22 +++++++++ 4 files changed, 77 insertions(+) create mode 100644 src/application/components/MemoryInternals.tsx diff --git a/src/application/App.tsx b/src/application/App.tsx index 838b84236..f5d28110a 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,6 +41,7 @@ import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; import { ExternalLink } from "./components/ExternalLink"; +import { MemoryInternals } from "./components/MemoryInternals"; const APP_QUERY: TypedDocumentNode = gql` query AppQuery { @@ -168,6 +169,7 @@ export const App = () => { Mutations ({client?.mutations.total ?? 0}) Cache + Memory Explorer
@@ -268,6 +270,11 @@ export const App = () => { /> + + + + + diff --git a/src/application/components/Layouts/Navigation.tsx b/src/application/components/Layouts/Navigation.tsx index 14b94a84a..9465d3c0f 100644 --- a/src/application/components/Layouts/Navigation.tsx +++ b/src/application/components/Layouts/Navigation.tsx @@ -5,6 +5,7 @@ export enum Screens { Queries = "queries", Mutations = "mutations", Explorer = "explorer", + Memory = "memory", } export const currentScreen = makeVar(Screens.Queries); diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx new file mode 100644 index 000000000..b2dbbcee0 --- /dev/null +++ b/src/application/components/MemoryInternals.tsx @@ -0,0 +1,47 @@ +import type { TypedDocumentNode } from "@apollo/client"; +import { gql, useQuery } from "@apollo/client"; +import { FullWidthLayout } from "./Layouts/FullWidthLayout"; +import { PageSpinner } from "./PageSpinner"; +import type { + MemoryInternalsQuery, + MemoryInternalsQueryVariables, +} from "../types/gql"; + +interface MemoryInternalsProps { + clientId: string | undefined; +} + +const MEMORY_INTERNALS_QUERY: TypedDocumentNode< + MemoryInternalsQuery, + MemoryInternalsQueryVariables +> = gql` + query MemoryInternalsQuery($clientId: ID!) { + client(id: $clientId) { + memoryInternals { + limits + sizes + } + } + } +`; + +export function MemoryInternals({ clientId }: MemoryInternalsProps) { + const { data, loading, error } = useQuery(MEMORY_INTERNALS_QUERY, { + variables: { clientId: clientId as string }, + skip: !clientId, + }); + + if (error) { + throw error; + } + + return ( + + {loading ? ( + + ) : ( +
{JSON.stringify(data?.client, null, 2)}
+ )} +
+ ); +} diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index 42a8e4788..ef40b4e40 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -47,6 +47,7 @@ export type Client = { __typename: "Client"; cache: Scalars["Cache"]["output"]; id: Scalars["String"]["output"]; + memoryInternals: Maybe; mutations: ClientMutations; name: Maybe; queries: ClientQueries; @@ -71,6 +72,12 @@ export type GraphQLErrorSourceLocation = { line: Scalars["Int"]["output"]; }; +export type MemoryInternals = { + __typename: "MemoryInternals"; + limits: Scalars["JSON"]["output"]; + sizes: Scalars["JSON"]["output"]; +}; + export type Query = { __typename: "Query"; client: Maybe; @@ -183,6 +190,21 @@ export type GetCache = { client: { __typename: "Client"; id: string; cache: Cache } | null; }; +export type MemoryInternalsQueryVariables = Exact<{ + clientId: Scalars["ID"]["input"]; +}>; + +export type MemoryInternalsQuery = { + client: { + __typename: "Client"; + memoryInternals: { + __typename: "MemoryInternals"; + limits: JSON; + sizes: JSON; + } | null; + } | null; +}; + export type GetMutationsVariables = Exact<{ id: Scalars["ID"]["input"]; }>; From 371a4dd429e9b2e4d6d3617a1c19e559b96055bc Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:57:20 -0600 Subject: [PATCH 07/77] Always overwrite results for memoryInternals field --- src/application/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/application/index.tsx b/src/application/index.tsx index 8ab408a58..7ce8568bb 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -58,6 +58,9 @@ const cache = new InMemoryCache({ cache: { merge: false, }, + memoryInternals: { + merge: false, + }, }, }, ClientQueries: { From 5abccdf95a849e8bb85ec993a4c5b19ad8c5da8d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:57:40 -0600 Subject: [PATCH 08/77] Request id on MemoryInternals tab --- src/application/components/MemoryInternals.tsx | 16 ++++++++++------ src/application/types/gql.ts | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index b2dbbcee0..3548afa97 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -17,6 +17,7 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< > = gql` query MemoryInternalsQuery($clientId: ID!) { client(id: $clientId) { + id memoryInternals { limits sizes @@ -29,6 +30,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const { data, loading, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, skip: !clientId, + pollInterval: 500, }); if (error) { @@ -36,12 +38,14 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { } return ( - - {loading ? ( - - ) : ( -
{JSON.stringify(data?.client, null, 2)}
- )} + + + {loading ? ( + + ) : ( +
{JSON.stringify(data?.client, null, 2)}
+ )} +
); } diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index ef40b4e40..a2df2fd28 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -197,6 +197,7 @@ export type MemoryInternalsQueryVariables = Exact<{ export type MemoryInternalsQuery = { client: { __typename: "Client"; + id: string; memoryInternals: { __typename: "MemoryInternals"; limits: JSON; From 340d3c00e4a1547be2e22c14b339ea85555440d1 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 22:57:51 -0600 Subject: [PATCH 09/77] Fix scroll on memory internals tab --- src/application/App.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index f5d28110a..3ebc23f76 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -270,16 +270,19 @@ export const App = () => { />
- - - - - + + + + + ); From 60239dc90bad381e5ea1d4dd040c5aafd442def0 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 23:11:10 -0600 Subject: [PATCH 10/77] Add a header to MemoryInternals --- src/application/components/MemoryInternals.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 3548afa97..1134b6d8a 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -38,8 +38,16 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { } return ( - - + +
+

+ Memory +

+

+ Learn more in the docs! +

+
+ {loading ? ( ) : ( From c4ac6e9f30d26e4d54fb9018b859ef00fe4b606a Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 23:15:23 -0600 Subject: [PATCH 11/77] Add link to docs for memory management --- src/application/components/MemoryInternals.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 1134b6d8a..7f7fc4ade 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -1,5 +1,7 @@ import type { TypedDocumentNode } from "@apollo/client"; import { gql, useQuery } from "@apollo/client"; +import IconOutlink from "@apollo/icons/default/IconOutlink.svg"; + import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; import type { @@ -44,7 +46,17 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { Memory

- Learn more in the docs! + Learn how to manage memory in the{" "} + + docs + + + .

From 67345714135f0e84f3134fab23cbee8085f74890 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 23:20:31 -0600 Subject: [PATCH 12/77] Update description for cache size limits --- src/application/components/MemoryInternals.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 7f7fc4ade..c97bbce67 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -46,7 +46,8 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { Memory

- Learn how to manage memory in the{" "} + Learn how Apollo Client manages memory and how to set custom cache + size limits in the{" "} Date: Tue, 20 Aug 2024 23:43:03 -0600 Subject: [PATCH 13/77] More robust types for memory internals --- src/application/localSchema.graphql | 59 ++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index fb187b185..e611a631c 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -18,6 +18,15 @@ type Query { client(id: ID!): Client } +type BaseCacheSizes { + fragmentQueryDocuments: CacheSize +} + +type CacheSize { + limit: Int + value: Int +} + type Client { id: String! name: String @@ -28,11 +37,6 @@ type Client { memoryInternals: MemoryInternals } -type MemoryInternals { - limits: JSON! - sizes: JSON! -} - type ClientQueries { total: Int! items: [WatchedQuery!]! @@ -43,6 +47,51 @@ type ClientMutations { items: [WatchedMutation!]! } +type DocumentTransformCacheSizes { + cache: CacheSize +} + +type FragmentRegistryCacheSizes { + lookup: CacheSize + findFragmentSpreads: CacheSize + transform: CacheSize +} + +type InMemoryCacheSizes { + maybeBroadcastWatch: CacheSize + executeSelectionSet: CacheSize + executeSubSelectedArray: CacheSize +} + +union LinkCacheSize = + | PersistedQueryLinkCacheSizes + | RemoveTypenameFromVariablesLinkCacheSizes + +type MemoryInternals { + print: CacheSize + parser: CacheSize + canonicalStringify: CacheSize + links: [LinkCacheSize!] + queryManager: QueryManagerCacheSizes! + fragmentRegistry: FragmentRegistryCacheSizes! + cache: BaseCacheSizes! + addTypenameDocumentTransform: [DocumentTransformCacheSizes!] + inMemoryCache: InMemoryCacheSizes! +} + +type QueryManagerCacheSizes { + getDocumentInfo: CacheSize + documentTransforms: [DocumentTransformCacheSizes!] +} + +type PersistedQueryLinkCacheSizes { + persistedQueryHashes: CacheSize +} + +type RemoveTypenameFromVariablesLinkCacheSizes { + getVariableDefinitions: CacheSize +} + type WatchedMutation { id: ID! name: String From 12b542a0b8087f61731bf78f0632a070d1239a1c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 23:43:30 -0600 Subject: [PATCH 14/77] Remove MemoryInternals mapping --- codegen.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/codegen.ts b/codegen.ts index e54b114f8..54b7eba57 100644 --- a/codegen.ts +++ b/codegen.ts @@ -52,7 +52,6 @@ const config: CodegenConfig = { Client: "../../types.ts#ApolloClientInfo", ClientQueries: "../../types.ts#ApolloClientInfo", ClientMutations: "../../types.ts#ApolloClientInfo", - MemoryInternals: "../../types.ts#MemoryInternals", SerializedApolloError: "../../extension/tab/helpers#SerializedApolloError as RpcSerializedApolloError", SerializedError: From 8fc9c0ec94af643606c23a4aeadd210f6ced137d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 20 Aug 2024 23:52:13 -0600 Subject: [PATCH 15/77] Add graphqlsp plugin --- package-lock.json | 42 ++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + tsconfig.json | 8 +++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c178c4cea..99379f01c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "zen-observable": "^0.10.0" }, "devDependencies": { + "@0no-co/graphqlsp": "^1.12.13", "@changesets/changelog-github": "0.5.0", "@changesets/cli": "2.27.10", "@graphql-codegen/cli": "5.0.3", @@ -110,6 +111,34 @@ "ws": "^8.18.0" } }, + "node_modules/@0no-co/graphql.web": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.7.tgz", + "integrity": "sha512-E3Qku4mTzdrlwVWGPxklDnME5ANrEGetvYw4i2GCRlppWXXE4QD66j7pwb8HelZwS6LnqEChhrSOGCXpbiu6MQ==", + "dev": true, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, + "node_modules/@0no-co/graphqlsp": { + "version": "1.12.13", + "resolved": "https://registry.npmjs.org/@0no-co/graphqlsp/-/graphqlsp-1.12.13.tgz", + "integrity": "sha512-/C9yXft+mq+VdoniBgWvA+iK5X6cB50KKThg1je4bFIhhBNccLJlNbWFxOglXseKuisq+h5oIY4ELTVKs6GhRQ==", + "dev": true, + "dependencies": { + "@gql.tada/internal": "^1.0.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "typescript": "^5.0.0" + } + }, "node_modules/@adobe/css-tools": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", @@ -3662,6 +3691,19 @@ "npm": ">=7.0.0" } }, + "node_modules/@gql.tada/internal": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@gql.tada/internal/-/internal-1.0.6.tgz", + "integrity": "sha512-K5dKMqqU0pcNWS+/i6EnoUGvA7lW2Agwl+nepZOEWbGpG80aJxXfL+yAvaHihP5VqGZFOygyc3NDBo1mm+Z4KQ==", + "dev": true, + "dependencies": { + "@0no-co/graphql.web": "^1.0.5" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "typescript": "^5.0.0" + } + }, "node_modules/@graphql-codegen/add": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-5.0.3.tgz", diff --git a/package.json b/package.json index a2a0614ae..35ce6399f 100755 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "zen-observable": "^0.10.0" }, "devDependencies": { + "@0no-co/graphqlsp": "^1.12.13", "@changesets/changelog-github": "0.5.0", "@changesets/cli": "2.27.10", "@graphql-codegen/cli": "5.0.3", diff --git a/tsconfig.json b/tsconfig.json index c358c632c..fbb27a3d0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,13 @@ "strict": true, "forceConsistentCasingInFileNames": true, "declaration": true, - "outDir": "dist" + "outDir": "dist", + "plugins": [ + { + "name": "@0no-co/graphqlsp", + "schema": "./src/application/localSchema.graphql" + } + ] }, "$schema": "https://json.schemastore.org/tsconfig", "compileOnSave": true, From bc355b8afb65bf41a29e5b213567e8eb51e372fb Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:11:30 -0600 Subject: [PATCH 16/77] Rename value to size --- src/application/localSchema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index e611a631c..3a91e4e2a 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -24,7 +24,7 @@ type BaseCacheSizes { type CacheSize { limit: Int - value: Int + size: Int } type Client { From f9436ca4a29694ca34f337f8fae9dd140713a294 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:11:35 -0600 Subject: [PATCH 17/77] Guarantee an array of link caches --- src/application/localSchema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index 3a91e4e2a..e01d7226d 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -71,7 +71,7 @@ type MemoryInternals { print: CacheSize parser: CacheSize canonicalStringify: CacheSize - links: [LinkCacheSize!] + links: [LinkCacheSize!]! queryManager: QueryManagerCacheSizes! fragmentRegistry: FragmentRegistryCacheSizes! cache: BaseCacheSizes! From f713810aa3aadeb582c662206b219ec6749209ae Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:22:31 -0600 Subject: [PATCH 18/77] Map memory internals to GraphQL types in the schema --- src/application/schema.ts | 152 +++++++++++++++- src/application/types/resolvers.ts | 279 ++++++++++++++++++++++++++++- 2 files changed, 422 insertions(+), 9 deletions(-) diff --git a/src/application/schema.ts b/src/application/schema.ts index 14588bb80..b1b57eb0c 100644 --- a/src/application/schema.ts +++ b/src/application/schema.ts @@ -1,7 +1,11 @@ import type { RpcClient } from "../extension/rpc"; import typeDefs from "./localSchema.graphql"; import { makeExecutableSchema } from "@graphql-tools/schema"; -import type { Resolvers } from "./types/resolvers"; +import type { + Resolvers, + PersistedQueryLinkCacheSizes, + RemoveTypenameFromVariablesLinkCacheSizes, +} from "./types/resolvers"; import { getOperationName } from "@apollo/client/utilities"; import { print } from "graphql"; @@ -30,7 +34,74 @@ function createResolvers(client: RpcClient): Resolvers { client.id ); - return memoryInternals ?? null; + if (!memoryInternals) { + return null; + } + + const sizes = memoryInternals.sizes; + const limits = memoryInternals.limits; + + return { + print: getCacheSize(sizes.print, limits.print), + parser: getCacheSize(sizes.parser, limits.parser), + canonicalStringify: getCacheSize( + sizes.canonicalStringify, + limits.canonicalStringify + ), + links: sizes.links + .map((linkCache) => getLinkCacheSize(linkCache, limits)) + .filter(Boolean), + queryManager: { + getDocumentInfo: getCacheSize( + sizes.queryManager.getDocumentInfo, + limits["queryManager.getDocumentInfo"] + ), + documentTransforms: getDocumentTransformCacheSizes( + sizes.queryManager.documentTransforms, + limits + ), + }, + fragmentRegistry: { + lookup: getCacheSize( + sizes.fragmentRegistry?.lookup, + limits["fragmentRegistry.lookup"] + ), + findFragmentSpreads: getCacheSize( + sizes.fragmentRegistry?.findFragmentSpreads, + limits["fragmentRegistry.findFragmentSpreads"] + ), + transform: getCacheSize( + sizes.fragmentRegistry?.transform, + limits["fragmentRegistry.transform"] + ), + }, + cache: { + fragmentQueryDocuments: getCacheSize( + sizes.cache?.fragmentQueryDocuments, + limits["cache.fragmentQueryDocuments"] + ), + }, + addTypenameDocumentTransform: sizes.addTypenameDocumentTransform + ? getDocumentTransformCacheSizes( + sizes.addTypenameDocumentTransform, + limits + ) + : null, + inMemoryCache: { + maybeBroadcastWatch: getCacheSize( + sizes.inMemoryCache?.maybeBroadcastWatch, + limits["inMemoryCache.maybeBroadcastWatch"] + ), + executeSelectionSet: getCacheSize( + sizes.inMemoryCache?.executeSelectionSet, + limits["inMemoryCache.executeSelectionSet"] + ), + executeSubSelectedArray: getCacheSize( + sizes.inMemoryCache?.executeSubSelectedArray, + limits["inMemoryCache.executeSubSelectedArray"] + ), + }, + }; }, }, ClientQueries: { @@ -87,3 +158,80 @@ function createResolvers(client: RpcClient): Resolvers { }, }; } + +type MemoryLimits = Record; + +function getCacheSize(size: number | undefined, limit: number | undefined) { + if (!size) { + return null; + } + + return { size, limit: limit ?? null }; +} + +function getDocumentTransformCacheSizes( + caches: Array<{ cache: number }>, + limits: MemoryLimits +) { + return caches.map(({ cache }) => ({ + cache: getCacheSize(cache, limits["documentTransform.cache"]), + })); +} + +interface PersistedQueryLinkCache { + PersistedQueryLink: { + persistedQueryHashes: number; + }; +} + +function isPersistedQueryLinkCache( + cache: unknown +): cache is PersistedQueryLinkCache { + return ( + typeof cache === "object" && cache !== null && "PersistedQueryLink" in cache + ); +} + +interface RemoveTypenameFromVariablesLinkCache { + removeTypenameFromVariables: { + getVariableDefinitions: number; + }; +} + +function isRemoveTypenameFromVariablesLinkCache( + cache: unknown +): cache is RemoveTypenameFromVariablesLinkCache { + return ( + typeof cache === "object" && + cache !== null && + "removeTypenameFromVariables" in cache + ); +} + +function getLinkCacheSize( + linkCache: unknown, + limits: MemoryLimits +): + | PersistedQueryLinkCacheSizes + | RemoveTypenameFromVariablesLinkCacheSizes + | null { + if (isPersistedQueryLinkCache(linkCache)) { + return { + persistedQueryHashes: { + size: linkCache.PersistedQueryLink.persistedQueryHashes, + limit: limits["PersistedQueryLink.persistedQueryHashes"], + }, + } satisfies PersistedQueryLinkCacheSizes; + } + + if (isRemoveTypenameFromVariablesLinkCache(linkCache)) { + return { + getVariableDefinitions: { + size: linkCache.removeTypenameFromVariables.getVariableDefinitions, + limit: limits["removeTypenameFromVariables.getVariableDefinitions"], + }, + } satisfies RemoveTypenameFromVariablesLinkCacheSizes; + } + + return null; +} diff --git a/src/application/types/resolvers.ts b/src/application/types/resolvers.ts index d289d6c6a..56d6c3b30 100644 --- a/src/application/types/resolvers.ts +++ b/src/application/types/resolvers.ts @@ -7,7 +7,7 @@ import type { GraphQLScalarType, GraphQLScalarTypeConfig, } from "graphql"; -import type { ApolloClientInfo, MemoryInternals } from "../../types.ts"; +import type { ApolloClientInfo } from "../../types.ts"; import type { SerializedApolloError as RpcSerializedApolloError, SerializedError as RpcSerializedError, @@ -56,6 +56,17 @@ export type Scalars = { Variables: { input: Variables; output: Variables }; }; +export type BaseCacheSizes = { + __typename?: "BaseCacheSizes"; + fragmentQueryDocuments?: Maybe; +}; + +export type CacheSize = { + __typename?: "CacheSize"; + limit?: Maybe; + size?: Maybe; +}; + export type Client = { __typename?: "Client"; cache: Scalars["Cache"]["output"]; @@ -79,16 +90,51 @@ export type ClientQueries = { total: Scalars["Int"]["output"]; }; +export type DocumentTransformCacheSizes = { + __typename?: "DocumentTransformCacheSizes"; + cache?: Maybe; +}; + +export type FragmentRegistryCacheSizes = { + __typename?: "FragmentRegistryCacheSizes"; + findFragmentSpreads?: Maybe; + lookup?: Maybe; + transform?: Maybe; +}; + export type GraphQlErrorSourceLocation = { __typename?: "GraphQLErrorSourceLocation"; column: Scalars["Int"]["output"]; line: Scalars["Int"]["output"]; }; +export type InMemoryCacheSizes = { + __typename?: "InMemoryCacheSizes"; + executeSelectionSet?: Maybe; + executeSubSelectedArray?: Maybe; + maybeBroadcastWatch?: Maybe; +}; + +export type LinkCacheSize = + | PersistedQueryLinkCacheSizes + | RemoveTypenameFromVariablesLinkCacheSizes; + export type MemoryInternals = { __typename?: "MemoryInternals"; - limits: Scalars["JSON"]["output"]; - sizes: Scalars["JSON"]["output"]; + addTypenameDocumentTransform?: Maybe>; + cache: BaseCacheSizes; + canonicalStringify?: Maybe; + fragmentRegistry: FragmentRegistryCacheSizes; + inMemoryCache: InMemoryCacheSizes; + links: Array; + parser?: Maybe; + print?: Maybe; + queryManager: QueryManagerCacheSizes; +}; + +export type PersistedQueryLinkCacheSizes = { + __typename?: "PersistedQueryLinkCacheSizes"; + persistedQueryHashes?: Maybe; }; export type Query = { @@ -101,6 +147,17 @@ export type QueryClientArgs = { id: Scalars["ID"]["input"]; }; +export type QueryManagerCacheSizes = { + __typename?: "QueryManagerCacheSizes"; + documentTransforms?: Maybe>; + getDocumentInfo?: Maybe; +}; + +export type RemoveTypenameFromVariablesLinkCacheSizes = { + __typename?: "RemoveTypenameFromVariablesLinkCacheSizes"; + getVariableDefinitions?: Maybe; +}; + export type SerializedApolloError = { __typename?: "SerializedApolloError"; clientErrors: Array; @@ -264,25 +321,43 @@ export type DirectiveResolverFn< /** Mapping of union types */ export type ResolversUnionTypes<_RefType extends Record> = { + LinkCacheSize: + | PersistedQueryLinkCacheSizes + | RemoveTypenameFromVariablesLinkCacheSizes; WatchedMutationError: RpcSerializedApolloError | RpcSerializedError; }; /** Mapping between all available schema types and the resolvers types */ export type ResolversTypes = { + BaseCacheSizes: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; Cache: ResolverTypeWrapper; + CacheSize: ResolverTypeWrapper; Client: ResolverTypeWrapper; ClientMutations: ResolverTypeWrapper; ClientQueries: ResolverTypeWrapper; + DocumentTransformCacheSizes: ResolverTypeWrapper; + FragmentRegistryCacheSizes: ResolverTypeWrapper; GraphQLErrorPath: ResolverTypeWrapper; GraphQLErrorSourceLocation: ResolverTypeWrapper; ID: ResolverTypeWrapper; + InMemoryCacheSizes: ResolverTypeWrapper; Int: ResolverTypeWrapper; JSON: ResolverTypeWrapper; - MemoryInternals: ResolverTypeWrapper; + LinkCacheSize: ResolverTypeWrapper< + ResolversUnionTypes["LinkCacheSize"] + >; + MemoryInternals: ResolverTypeWrapper< + Omit & { + links: Array; + } + >; + PersistedQueryLinkCacheSizes: ResolverTypeWrapper; Query: ResolverTypeWrapper; QueryData: ResolverTypeWrapper; + QueryManagerCacheSizes: ResolverTypeWrapper; QueryOptions: ResolverTypeWrapper; + RemoveTypenameFromVariablesLinkCacheSizes: ResolverTypeWrapper; SerializedApolloError: ResolverTypeWrapper; SerializedError: ResolverTypeWrapper; SerializedGraphQLError: ResolverTypeWrapper; @@ -310,20 +385,31 @@ export type ResolversTypes = { /** Mapping between all available schema types and the resolvers parents */ export type ResolversParentTypes = { + BaseCacheSizes: BaseCacheSizes; Boolean: Scalars["Boolean"]["output"]; Cache: Scalars["Cache"]["output"]; + CacheSize: CacheSize; Client: ApolloClientInfo; ClientMutations: ApolloClientInfo; ClientQueries: ApolloClientInfo; + DocumentTransformCacheSizes: DocumentTransformCacheSizes; + FragmentRegistryCacheSizes: FragmentRegistryCacheSizes; GraphQLErrorPath: Scalars["GraphQLErrorPath"]["output"]; GraphQLErrorSourceLocation: GraphQlErrorSourceLocation; ID: Scalars["ID"]["output"]; + InMemoryCacheSizes: InMemoryCacheSizes; Int: Scalars["Int"]["output"]; JSON: Scalars["JSON"]["output"]; - MemoryInternals: MemoryInternals; + LinkCacheSize: ResolversUnionTypes["LinkCacheSize"]; + MemoryInternals: Omit & { + links: Array; + }; + PersistedQueryLinkCacheSizes: PersistedQueryLinkCacheSizes; Query: never; QueryData: Scalars["QueryData"]["output"]; + QueryManagerCacheSizes: QueryManagerCacheSizes; QueryOptions: Scalars["QueryOptions"]["output"]; + RemoveTypenameFromVariablesLinkCacheSizes: RemoveTypenameFromVariablesLinkCacheSizes; SerializedApolloError: RpcSerializedApolloError; SerializedError: RpcSerializedError; SerializedGraphQLError: GraphQLFormattedError; @@ -341,11 +427,34 @@ export type ResolversParentTypes = { }; }; +export type BaseCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["BaseCacheSizes"] = ResolversParentTypes["BaseCacheSizes"], +> = { + fragmentQueryDocuments?: Resolver< + Maybe, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface CacheScalarConfig extends GraphQLScalarTypeConfig { name: "Cache"; } +export type CacheSizeResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["CacheSize"] = ResolversParentTypes["CacheSize"], +> = { + limit?: Resolver, ParentType, ContextType>; + size?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type ClientResolvers< ContextType = any, ParentType extends @@ -397,6 +506,38 @@ export type ClientQueriesResolvers< __isTypeOf?: IsTypeOfResolverFn; }; +export type DocumentTransformCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["DocumentTransformCacheSizes"] = ResolversParentTypes["DocumentTransformCacheSizes"], +> = { + cache?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type FragmentRegistryCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["FragmentRegistryCacheSizes"] = ResolversParentTypes["FragmentRegistryCacheSizes"], +> = { + findFragmentSpreads?: Resolver< + Maybe, + ParentType, + ContextType + >; + lookup?: Resolver< + Maybe, + ParentType, + ContextType + >; + transform?: Resolver< + Maybe, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface GraphQlErrorPathScalarConfig extends GraphQLScalarTypeConfig { name: "GraphQLErrorPath"; @@ -412,18 +553,102 @@ export type GraphQlErrorSourceLocationResolvers< __isTypeOf?: IsTypeOfResolverFn; }; +export type InMemoryCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["InMemoryCacheSizes"] = ResolversParentTypes["InMemoryCacheSizes"], +> = { + executeSelectionSet?: Resolver< + Maybe, + ParentType, + ContextType + >; + executeSubSelectedArray?: Resolver< + Maybe, + ParentType, + ContextType + >; + maybeBroadcastWatch?: Resolver< + Maybe, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface JsonScalarConfig extends GraphQLScalarTypeConfig { name: "JSON"; } +export type LinkCacheSizeResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["LinkCacheSize"] = ResolversParentTypes["LinkCacheSize"], +> = { + __resolveType: TypeResolveFn< + | "PersistedQueryLinkCacheSizes" + | "RemoveTypenameFromVariablesLinkCacheSizes", + ParentType, + ContextType + >; +}; + export type MemoryInternalsResolvers< ContextType = any, ParentType extends ResolversParentTypes["MemoryInternals"] = ResolversParentTypes["MemoryInternals"], > = { - limits?: Resolver; - sizes?: Resolver; + addTypenameDocumentTransform?: Resolver< + Maybe>, + ParentType, + ContextType + >; + cache?: Resolver; + canonicalStringify?: Resolver< + Maybe, + ParentType, + ContextType + >; + fragmentRegistry?: Resolver< + ResolversTypes["FragmentRegistryCacheSizes"], + ParentType, + ContextType + >; + inMemoryCache?: Resolver< + ResolversTypes["InMemoryCacheSizes"], + ParentType, + ContextType + >; + links?: Resolver< + Array, + ParentType, + ContextType + >; + parser?: Resolver< + Maybe, + ParentType, + ContextType + >; + print?: Resolver, ParentType, ContextType>; + queryManager?: Resolver< + ResolversTypes["QueryManagerCacheSizes"], + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PersistedQueryLinkCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["PersistedQueryLinkCacheSizes"] = ResolversParentTypes["PersistedQueryLinkCacheSizes"], +> = { + persistedQueryHashes?: Resolver< + Maybe, + ParentType, + ContextType + >; __isTypeOf?: IsTypeOfResolverFn; }; @@ -446,11 +671,42 @@ export interface QueryDataScalarConfig name: "QueryData"; } +export type QueryManagerCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["QueryManagerCacheSizes"] = ResolversParentTypes["QueryManagerCacheSizes"], +> = { + documentTransforms?: Resolver< + Maybe>, + ParentType, + ContextType + >; + getDocumentInfo?: Resolver< + Maybe, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface QueryOptionsScalarConfig extends GraphQLScalarTypeConfig { name: "QueryOptions"; } +export type RemoveTypenameFromVariablesLinkCacheSizesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["RemoveTypenameFromVariablesLinkCacheSizes"] = ResolversParentTypes["RemoveTypenameFromVariablesLinkCacheSizes"], +> = { + getVariableDefinitions?: Resolver< + Maybe, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type SerializedApolloErrorResolvers< ContextType = any, ParentType extends @@ -603,17 +859,26 @@ export type WatchedQueryResolvers< }; export type Resolvers = { + BaseCacheSizes?: BaseCacheSizesResolvers; Cache?: GraphQLScalarType; + CacheSize?: CacheSizeResolvers; Client?: ClientResolvers; ClientMutations?: ClientMutationsResolvers; ClientQueries?: ClientQueriesResolvers; + DocumentTransformCacheSizes?: DocumentTransformCacheSizesResolvers; + FragmentRegistryCacheSizes?: FragmentRegistryCacheSizesResolvers; GraphQLErrorPath?: GraphQLScalarType; GraphQLErrorSourceLocation?: GraphQlErrorSourceLocationResolvers; + InMemoryCacheSizes?: InMemoryCacheSizesResolvers; JSON?: GraphQLScalarType; + LinkCacheSize?: LinkCacheSizeResolvers; MemoryInternals?: MemoryInternalsResolvers; + PersistedQueryLinkCacheSizes?: PersistedQueryLinkCacheSizesResolvers; Query?: QueryResolvers; QueryData?: GraphQLScalarType; + QueryManagerCacheSizes?: QueryManagerCacheSizesResolvers; QueryOptions?: GraphQLScalarType; + RemoveTypenameFromVariablesLinkCacheSizes?: RemoveTypenameFromVariablesLinkCacheSizesResolvers; SerializedApolloError?: SerializedApolloErrorResolvers; SerializedError?: SerializedErrorResolvers; SerializedGraphQLError?: SerializedGraphQlErrorResolvers; From 04c5f1ecfe3f772c8b8b2adf1562eb287d4344b1 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:29:08 -0600 Subject: [PATCH 19/77] Update query used to get data in MemoryInternals --- .../components/MemoryInternals.tsx | 70 +++++++- src/application/types/gql.ts | 170 +++++++++++++++++- 2 files changed, 234 insertions(+), 6 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index c97bbce67..3307d49e8 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -21,11 +21,77 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< client(id: $clientId) { id memoryInternals { - limits - sizes + print { + ...CacheSizeFields + } + parser { + ...CacheSizeFields + } + canonicalStringify { + ...CacheSizeFields + } + links { + ... on PersistedQueryLinkCacheSizes { + persistedQueryHashes { + ...CacheSizeFields + } + } + ... on RemoveTypenameFromVariablesLinkCacheSizes { + getVariableDefinitions { + ...CacheSizeFields + } + } + } + queryManager { + getDocumentInfo { + ...CacheSizeFields + } + documentTransforms { + cache { + ...CacheSizeFields + } + } + } + fragmentRegistry { + lookup { + ...CacheSizeFields + } + findFragmentSpreads { + ...CacheSizeFields + } + transform { + ...CacheSizeFields + } + } + cache { + fragmentQueryDocuments { + ...CacheSizeFields + } + } + addTypenameDocumentTransform { + cache { + ...CacheSizeFields + } + } + inMemoryCache { + maybeBroadcastWatch { + ...CacheSizeFields + } + executeSelectionSet { + ...CacheSizeFields + } + executeSubSelectedArray { + ...CacheSizeFields + } + } } } } + + fragment CacheSizeFields on CacheSize { + size + limit + } `; export function MemoryInternals({ clientId }: MemoryInternalsProps) { diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index a2df2fd28..21c46f8a0 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -43,6 +43,17 @@ export type Scalars = { Variables: { input: Variables; output: Variables }; }; +export type BaseCacheSizes = { + __typename: "BaseCacheSizes"; + fragmentQueryDocuments: Maybe; +}; + +export type CacheSize = { + __typename: "CacheSize"; + limit: Maybe; + size: Maybe; +}; + export type Client = { __typename: "Client"; cache: Scalars["Cache"]["output"]; @@ -66,16 +77,51 @@ export type ClientQueries = { total: Scalars["Int"]["output"]; }; +export type DocumentTransformCacheSizes = { + __typename: "DocumentTransformCacheSizes"; + cache: Maybe; +}; + +export type FragmentRegistryCacheSizes = { + __typename: "FragmentRegistryCacheSizes"; + findFragmentSpreads: Maybe; + lookup: Maybe; + transform: Maybe; +}; + export type GraphQLErrorSourceLocation = { __typename: "GraphQLErrorSourceLocation"; column: Scalars["Int"]["output"]; line: Scalars["Int"]["output"]; }; +export type InMemoryCacheSizes = { + __typename: "InMemoryCacheSizes"; + executeSelectionSet: Maybe; + executeSubSelectedArray: Maybe; + maybeBroadcastWatch: Maybe; +}; + +export type LinkCacheSize = + | PersistedQueryLinkCacheSizes + | RemoveTypenameFromVariablesLinkCacheSizes; + export type MemoryInternals = { __typename: "MemoryInternals"; - limits: Scalars["JSON"]["output"]; - sizes: Scalars["JSON"]["output"]; + addTypenameDocumentTransform: Maybe>; + cache: BaseCacheSizes; + canonicalStringify: Maybe; + fragmentRegistry: FragmentRegistryCacheSizes; + inMemoryCache: InMemoryCacheSizes; + links: Array; + parser: Maybe; + print: Maybe; + queryManager: QueryManagerCacheSizes; +}; + +export type PersistedQueryLinkCacheSizes = { + __typename: "PersistedQueryLinkCacheSizes"; + persistedQueryHashes: Maybe; }; export type Query = { @@ -88,6 +134,17 @@ export type QueryclientArgs = { id: Scalars["ID"]["input"]; }; +export type QueryManagerCacheSizes = { + __typename: "QueryManagerCacheSizes"; + documentTransforms: Maybe>; + getDocumentInfo: Maybe; +}; + +export type RemoveTypenameFromVariablesLinkCacheSizes = { + __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; + getVariableDefinitions: Maybe; +}; + export type SerializedApolloError = { __typename: "SerializedApolloError"; clientErrors: Array; @@ -200,12 +257,117 @@ export type MemoryInternalsQuery = { id: string; memoryInternals: { __typename: "MemoryInternals"; - limits: JSON; - sizes: JSON; + print: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + parser: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + canonicalStringify: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + links: Array< + | { + __typename: "PersistedQueryLinkCacheSizes"; + persistedQueryHashes: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + } + | { + __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; + getVariableDefinitions: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + } + >; + queryManager: { + __typename: "QueryManagerCacheSizes"; + getDocumentInfo: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + documentTransforms: Array<{ + __typename: "DocumentTransformCacheSizes"; + cache: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }> | null; + }; + fragmentRegistry: { + __typename: "FragmentRegistryCacheSizes"; + lookup: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + findFragmentSpreads: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + transform: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; + cache: { + __typename: "BaseCacheSizes"; + fragmentQueryDocuments: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; + addTypenameDocumentTransform: Array<{ + __typename: "DocumentTransformCacheSizes"; + cache: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }> | null; + inMemoryCache: { + __typename: "InMemoryCacheSizes"; + maybeBroadcastWatch: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + executeSelectionSet: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + executeSubSelectedArray: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; } | null; } | null; }; +export type CacheSizeFields = { + __typename: "CacheSize"; + size: number | null; + limit: number | null; +}; + export type GetMutationsVariables = Exact<{ id: Scalars["ID"]["input"]; }>; From ff9ae40979b23197975fec04d26d703c2a7aad5d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:37:42 -0600 Subject: [PATCH 20/77] Use min-width for select content --- src/application/components/Select/Select.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/Select/Select.tsx b/src/application/components/Select/Select.tsx index d73c7f203..0683cd08b 100644 --- a/src/application/components/Select/Select.tsx +++ b/src/application/components/Select/Select.tsx @@ -99,7 +99,7 @@ export const Select = ({ align={align} sideOffset={6} position="popper" - className="border border-primary bg-primary dark:bg-primary-dark dark:border-primary-dark shadow-dropdown overflow-hidden rounded-lg w-80 max-h-[calc(100vh-8rem)]" + className="border border-primary bg-primary dark:bg-primary-dark dark:border-primary-dark shadow-dropdown overflow-hidden rounded-lg min-w-80 max-h-[calc(100vh-8rem)]" > Date: Wed, 21 Aug 2024 00:51:41 -0600 Subject: [PATCH 21/77] Provide raw and parsed representations of the memory internals --- src/application/localSchema.graphql | 5 + src/application/schema.ts | 115 ++++++++--------- src/application/types/gql.ts | 183 +++++++++++++++------------- src/application/types/resolvers.ts | 29 ++++- 4 files changed, 186 insertions(+), 146 deletions(-) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index e01d7226d..b86ecbb12 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -68,6 +68,11 @@ union LinkCacheSize = | RemoveTypenameFromVariablesLinkCacheSizes type MemoryInternals { + raw: JSON + caches: MemoryInternalsCaches! +} + +type MemoryInternalsCaches { print: CacheSize parser: CacheSize canonicalStringify: CacheSize diff --git a/src/application/schema.ts b/src/application/schema.ts index b1b57eb0c..a8603d400 100644 --- a/src/application/schema.ts +++ b/src/application/schema.ts @@ -42,64 +42,67 @@ function createResolvers(client: RpcClient): Resolvers { const limits = memoryInternals.limits; return { - print: getCacheSize(sizes.print, limits.print), - parser: getCacheSize(sizes.parser, limits.parser), - canonicalStringify: getCacheSize( - sizes.canonicalStringify, - limits.canonicalStringify - ), - links: sizes.links - .map((linkCache) => getLinkCacheSize(linkCache, limits)) - .filter(Boolean), - queryManager: { - getDocumentInfo: getCacheSize( - sizes.queryManager.getDocumentInfo, - limits["queryManager.getDocumentInfo"] + raw: memoryInternals, + caches: { + print: getCacheSize(sizes.print, limits.print), + parser: getCacheSize(sizes.parser, limits.parser), + canonicalStringify: getCacheSize( + sizes.canonicalStringify, + limits.canonicalStringify ), - documentTransforms: getDocumentTransformCacheSizes( - sizes.queryManager.documentTransforms, - limits - ), - }, - fragmentRegistry: { - lookup: getCacheSize( - sizes.fragmentRegistry?.lookup, - limits["fragmentRegistry.lookup"] - ), - findFragmentSpreads: getCacheSize( - sizes.fragmentRegistry?.findFragmentSpreads, - limits["fragmentRegistry.findFragmentSpreads"] - ), - transform: getCacheSize( - sizes.fragmentRegistry?.transform, - limits["fragmentRegistry.transform"] - ), - }, - cache: { - fragmentQueryDocuments: getCacheSize( - sizes.cache?.fragmentQueryDocuments, - limits["cache.fragmentQueryDocuments"] - ), - }, - addTypenameDocumentTransform: sizes.addTypenameDocumentTransform - ? getDocumentTransformCacheSizes( - sizes.addTypenameDocumentTransform, + links: sizes.links + .map((linkCache) => getLinkCacheSize(linkCache, limits)) + .filter(Boolean), + queryManager: { + getDocumentInfo: getCacheSize( + sizes.queryManager.getDocumentInfo, + limits["queryManager.getDocumentInfo"] + ), + documentTransforms: getDocumentTransformCacheSizes( + sizes.queryManager.documentTransforms, limits - ) - : null, - inMemoryCache: { - maybeBroadcastWatch: getCacheSize( - sizes.inMemoryCache?.maybeBroadcastWatch, - limits["inMemoryCache.maybeBroadcastWatch"] - ), - executeSelectionSet: getCacheSize( - sizes.inMemoryCache?.executeSelectionSet, - limits["inMemoryCache.executeSelectionSet"] - ), - executeSubSelectedArray: getCacheSize( - sizes.inMemoryCache?.executeSubSelectedArray, - limits["inMemoryCache.executeSubSelectedArray"] - ), + ), + }, + fragmentRegistry: { + lookup: getCacheSize( + sizes.fragmentRegistry?.lookup, + limits["fragmentRegistry.lookup"] + ), + findFragmentSpreads: getCacheSize( + sizes.fragmentRegistry?.findFragmentSpreads, + limits["fragmentRegistry.findFragmentSpreads"] + ), + transform: getCacheSize( + sizes.fragmentRegistry?.transform, + limits["fragmentRegistry.transform"] + ), + }, + cache: { + fragmentQueryDocuments: getCacheSize( + sizes.cache?.fragmentQueryDocuments, + limits["cache.fragmentQueryDocuments"] + ), + }, + addTypenameDocumentTransform: sizes.addTypenameDocumentTransform + ? getDocumentTransformCacheSizes( + sizes.addTypenameDocumentTransform, + limits + ) + : null, + inMemoryCache: { + maybeBroadcastWatch: getCacheSize( + sizes.inMemoryCache?.maybeBroadcastWatch, + limits["inMemoryCache.maybeBroadcastWatch"] + ), + executeSelectionSet: getCacheSize( + sizes.inMemoryCache?.executeSelectionSet, + limits["inMemoryCache.executeSelectionSet"] + ), + executeSubSelectedArray: getCacheSize( + sizes.inMemoryCache?.executeSubSelectedArray, + limits["inMemoryCache.executeSubSelectedArray"] + ), + }, }, }; }, diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index 21c46f8a0..578793223 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -108,6 +108,12 @@ export type LinkCacheSize = export type MemoryInternals = { __typename: "MemoryInternals"; + caches: MemoryInternalsCaches; + raw: Maybe; +}; + +export type MemoryInternalsCaches = { + __typename: "MemoryInternalsCaches"; addTypenameDocumentTransform: Maybe>; cache: BaseCacheSizes; canonicalStringify: Maybe; @@ -257,106 +263,109 @@ export type MemoryInternalsQuery = { id: string; memoryInternals: { __typename: "MemoryInternals"; - print: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - parser: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - canonicalStringify: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - links: Array< - | { - __typename: "PersistedQueryLinkCacheSizes"; - persistedQueryHashes: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - } - | { - __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; - getVariableDefinitions: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - } - >; - queryManager: { - __typename: "QueryManagerCacheSizes"; - getDocumentInfo: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - documentTransforms: Array<{ - __typename: "DocumentTransformCacheSizes"; - cache: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - }> | null; - }; - fragmentRegistry: { - __typename: "FragmentRegistryCacheSizes"; - lookup: { + caches: { + __typename: "MemoryInternalsCaches"; + print: { __typename: "CacheSize"; size: number | null; limit: number | null; } | null; - findFragmentSpreads: { + parser: { __typename: "CacheSize"; size: number | null; limit: number | null; } | null; - transform: { + canonicalStringify: { __typename: "CacheSize"; size: number | null; limit: number | null; } | null; - }; - cache: { - __typename: "BaseCacheSizes"; - fragmentQueryDocuments: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - }; - addTypenameDocumentTransform: Array<{ - __typename: "DocumentTransformCacheSizes"; + links: Array< + | { + __typename: "PersistedQueryLinkCacheSizes"; + persistedQueryHashes: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + } + | { + __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; + getVariableDefinitions: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + } + >; + queryManager: { + __typename: "QueryManagerCacheSizes"; + getDocumentInfo: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + documentTransforms: Array<{ + __typename: "DocumentTransformCacheSizes"; + cache: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }> | null; + }; + fragmentRegistry: { + __typename: "FragmentRegistryCacheSizes"; + lookup: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + findFragmentSpreads: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + transform: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; cache: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - }> | null; - inMemoryCache: { - __typename: "InMemoryCacheSizes"; - maybeBroadcastWatch: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - executeSelectionSet: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; - executeSubSelectedArray: { - __typename: "CacheSize"; - size: number | null; - limit: number | null; - } | null; + __typename: "BaseCacheSizes"; + fragmentQueryDocuments: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; + addTypenameDocumentTransform: Array<{ + __typename: "DocumentTransformCacheSizes"; + cache: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }> | null; + inMemoryCache: { + __typename: "InMemoryCacheSizes"; + maybeBroadcastWatch: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + executeSelectionSet: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + executeSubSelectedArray: { + __typename: "CacheSize"; + size: number | null; + limit: number | null; + } | null; + }; }; } | null; } | null; diff --git a/src/application/types/resolvers.ts b/src/application/types/resolvers.ts index 56d6c3b30..aaa8b2f2e 100644 --- a/src/application/types/resolvers.ts +++ b/src/application/types/resolvers.ts @@ -121,6 +121,12 @@ export type LinkCacheSize = export type MemoryInternals = { __typename?: "MemoryInternals"; + caches: MemoryInternalsCaches; + raw?: Maybe; +}; + +export type MemoryInternalsCaches = { + __typename?: "MemoryInternalsCaches"; addTypenameDocumentTransform?: Maybe>; cache: BaseCacheSizes; canonicalStringify?: Maybe; @@ -347,8 +353,9 @@ export type ResolversTypes = { LinkCacheSize: ResolverTypeWrapper< ResolversUnionTypes["LinkCacheSize"] >; - MemoryInternals: ResolverTypeWrapper< - Omit & { + MemoryInternals: ResolverTypeWrapper; + MemoryInternalsCaches: ResolverTypeWrapper< + Omit & { links: Array; } >; @@ -401,7 +408,8 @@ export type ResolversParentTypes = { Int: Scalars["Int"]["output"]; JSON: Scalars["JSON"]["output"]; LinkCacheSize: ResolversUnionTypes["LinkCacheSize"]; - MemoryInternals: Omit & { + MemoryInternals: MemoryInternals; + MemoryInternalsCaches: Omit & { links: Array; }; PersistedQueryLinkCacheSizes: PersistedQueryLinkCacheSizes; @@ -598,6 +606,20 @@ export type MemoryInternalsResolvers< ContextType = any, ParentType extends ResolversParentTypes["MemoryInternals"] = ResolversParentTypes["MemoryInternals"], +> = { + caches?: Resolver< + ResolversTypes["MemoryInternalsCaches"], + ParentType, + ContextType + >; + raw?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type MemoryInternalsCachesResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes["MemoryInternalsCaches"] = ResolversParentTypes["MemoryInternalsCaches"], > = { addTypenameDocumentTransform?: Resolver< Maybe>, @@ -873,6 +895,7 @@ export type Resolvers = { JSON?: GraphQLScalarType; LinkCacheSize?: LinkCacheSizeResolvers; MemoryInternals?: MemoryInternalsResolvers; + MemoryInternalsCaches?: MemoryInternalsCachesResolvers; PersistedQueryLinkCacheSizes?: PersistedQueryLinkCacheSizesResolvers; Query?: QueryResolvers; QueryData?: GraphQLScalarType; From fc28e21cb28efd9cc6e27271b52925b4f2c2421b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:53:26 -0600 Subject: [PATCH 22/77] Add caches field around query selection --- .../components/MemoryInternals.tsx | 102 +++++++++--------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 3307d49e8..32cc58a33 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -21,67 +21,69 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< client(id: $clientId) { id memoryInternals { - print { - ...CacheSizeFields - } - parser { - ...CacheSizeFields - } - canonicalStringify { - ...CacheSizeFields - } - links { - ... on PersistedQueryLinkCacheSizes { - persistedQueryHashes { - ...CacheSizeFields - } - } - ... on RemoveTypenameFromVariablesLinkCacheSizes { - getVariableDefinitions { - ...CacheSizeFields - } - } - } - queryManager { - getDocumentInfo { + caches { + print { ...CacheSizeFields } - documentTransforms { - cache { - ...CacheSizeFields - } - } - } - fragmentRegistry { - lookup { + parser { ...CacheSizeFields } - findFragmentSpreads { + canonicalStringify { ...CacheSizeFields } - transform { - ...CacheSizeFields + links { + ... on PersistedQueryLinkCacheSizes { + persistedQueryHashes { + ...CacheSizeFields + } + } + ... on RemoveTypenameFromVariablesLinkCacheSizes { + getVariableDefinitions { + ...CacheSizeFields + } + } } - } - cache { - fragmentQueryDocuments { - ...CacheSizeFields + queryManager { + getDocumentInfo { + ...CacheSizeFields + } + documentTransforms { + cache { + ...CacheSizeFields + } + } } - } - addTypenameDocumentTransform { - cache { - ...CacheSizeFields + fragmentRegistry { + lookup { + ...CacheSizeFields + } + findFragmentSpreads { + ...CacheSizeFields + } + transform { + ...CacheSizeFields + } } - } - inMemoryCache { - maybeBroadcastWatch { - ...CacheSizeFields + cache { + fragmentQueryDocuments { + ...CacheSizeFields + } } - executeSelectionSet { - ...CacheSizeFields + addTypenameDocumentTransform { + cache { + ...CacheSizeFields + } } - executeSubSelectedArray { - ...CacheSizeFields + inMemoryCache { + maybeBroadcastWatch { + ...CacheSizeFields + } + executeSelectionSet { + ...CacheSizeFields + } + executeSubSelectedArray { + ...CacheSizeFields + } } } } From 7125c9adb565872407f15003089033087ac0e1c2 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 00:54:01 -0600 Subject: [PATCH 23/77] Add select for each field in the memory internals --- .../components/MemoryInternals.tsx | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 32cc58a33..b6b513ded 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -8,6 +8,8 @@ import type { MemoryInternalsQuery, MemoryInternalsQueryVariables, } from "../types/gql"; +import { Select } from "./Select"; +import { useState } from "react"; interface MemoryInternalsProps { clientId: string | undefined; @@ -97,6 +99,7 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< `; export function MemoryInternals({ clientId }: MemoryInternalsProps) { + const [selectedCache, setSelectedCache] = useState("print"); const { data, loading, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, skip: !clientId, @@ -132,9 +135,38 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { {loading ? ( ) : ( -

{JSON.stringify(data?.client, null, 2)}
+ <> + + )}
); } + +function SelectOption({ label }: { label: string }) { + return ( + + {label} + + ); +} From 5998f432c5b8c71ebf1f21f07b408d50e16195f3 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 01:24:07 -0600 Subject: [PATCH 24/77] Add some handling for switching cache sizes --- .../components/MemoryInternals.tsx | 120 +++++++++++++----- 1 file changed, 88 insertions(+), 32 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index b6b513ded..e1e824ae4 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -1,15 +1,20 @@ import type { TypedDocumentNode } from "@apollo/client"; -import { gql, useQuery } from "@apollo/client"; +import { gql, NetworkStatus, useQuery } from "@apollo/client"; import IconOutlink from "@apollo/icons/default/IconOutlink.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; import type { + CacheSize, MemoryInternalsQuery, MemoryInternalsQueryVariables, } from "../types/gql"; import { Select } from "./Select"; +import type { ReactElement, ReactNode } from "react"; import { useState } from "react"; +import { Alert } from "./Alert"; +import { selectsField } from "../../utils/graphql"; +import { QueryManager } from "@apollo/client/core/QueryManager"; interface MemoryInternalsProps { clientId: string | undefined; @@ -100,7 +105,7 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< export function MemoryInternals({ clientId }: MemoryInternalsProps) { const [selectedCache, setSelectedCache] = useState("print"); - const { data, loading, error } = useQuery(MEMORY_INTERNALS_QUERY, { + const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, skip: !clientId, pollInterval: 500, @@ -110,6 +115,73 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { throw error; } + if (networkStatus === NetworkStatus.loading) { + return ( + + + + ); + } + + const memoryInternals = data?.client?.memoryInternals; + const caches = memoryInternals?.caches; + + if (!caches) { + return ( + +

+ Could not get memory internals for the client. This may be a result of + running your application in production mode as access to memory + internals is disabled in production builds. +

+
+ ); + } + + const cacheComponents: Record = { + print: , + parser: , + canonicalStringify: , + links: , + ["queryManager.getDocumentInfo"]: , + ["queryManager.documentTransforms"]: , + ["fragmentRegistry.lookup"]: , + ["fragmentRegistry.findFragmentSpreads"]: , + ["fragmentRegistry.transform"]: , + ["cache.fragmentQueryDocuments"]: , + ["addTypenameDocumentTransform"]: , + ["inMemoryCache.executeSelectionSet"]: , + ["inMemoryCache.executeSubSelectedArray"]: , + ["inMemoryCache.maybeBroadcastWatch"]: , + }; + + return ( + +
+ + {cacheComponents[selectedCache]} +
+
+ ); +} + +function SelectOption({ label }: { label: string }) { + return ( + + {label} + + ); +} + +function Layout({ children }: { children: ReactNode }) { return (
@@ -132,41 +204,25 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) {

- {loading ? ( - - ) : ( - <> - - - )} + {children}
); } -function SelectOption({ label }: { label: string }) { +function CacheSize({ cacheSize }: { cacheSize: CacheSize | null }) { + if (!cacheSize) { + return

No cache found

; + } + return ( - - {label} - + <> +

Limit: {cacheSize.limit}

+

Size: {cacheSize.size}

+ ); } + +function TODOCacheSize() { + return "TODO: Implement me"; +} From 007ce055ec476e020686239366c593120680741b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 01:24:41 -0600 Subject: [PATCH 25/77] Add a todo comment for future feature --- src/application/components/MemoryInternals.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index e1e824ae4..ed20ed2c9 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -126,6 +126,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const memoryInternals = data?.client?.memoryInternals; const caches = memoryInternals?.caches; + // TODO: Show a message for clients older < 3.9 if (!caches) { return ( From ddd8a9f451d24e5bb0d39db51881cc8f0767aaac Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 01:24:58 -0600 Subject: [PATCH 26/77] Remove unused imports --- src/application/components/MemoryInternals.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index ed20ed2c9..5bca858be 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -12,9 +12,6 @@ import type { import { Select } from "./Select"; import type { ReactElement, ReactNode } from "react"; import { useState } from "react"; -import { Alert } from "./Alert"; -import { selectsField } from "../../utils/graphql"; -import { QueryManager } from "@apollo/client/core/QueryManager"; interface MemoryInternalsProps { clientId: string | undefined; From ecb99ee8c3e4d12332b2bfe454f270274bd25733 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 01:27:53 -0600 Subject: [PATCH 27/77] Create a type for internal caches --- .../components/MemoryInternals.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 5bca858be..72429b0e8 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -100,8 +100,24 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< } `; +type InternalCache = + | "print" + | "parser" + | "canonicalStringify" + | "links" + | "queryManager.getDocumentInfo" + | "queryManager.documentTransforms" + | "fragmentRegistry.lookup" + | "fragmentRegistry.findFragmentSpreads" + | "fragmentRegistry.transform" + | "cache.fragmentQueryDocuments" + | "addTypenameDocumentTransform" + | "inMemoryCache.executeSelectionSet" + | "inMemoryCache.executeSubSelectedArray" + | "inMemoryCache.maybeBroadcastWatch"; + export function MemoryInternals({ clientId }: MemoryInternalsProps) { - const [selectedCache, setSelectedCache] = useState("print"); + const [selectedCache, setSelectedCache] = useState("print"); const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, skip: !clientId, @@ -136,7 +152,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { ); } - const cacheComponents: Record = { + const cacheComponents: Record = { print: , parser: , canonicalStringify: , @@ -159,7 +175,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { setSelectedCache(value as InternalCache)} - > - {Object.keys(cacheComponents).map((key) => ( - - ))} - - {cacheComponents[selectedCache]} + + +
+ {selectedView === "chart" ? ( -
+ <> - setSelectedCache(value as InternalCache) + setSelectedCache(cacheComponents[value as InternalCache]) } > - {Object.keys(cacheComponents).map((key) => ( + {Object.values(cacheComponents).map(({ key }) => ( ))} - {cacheComponents[selectedCache]} + {selectedCache.render(caches)} ) : selectedView === "raw" ? ( From 547c39a3909b079ee9d2b592333566956b62cf2e Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 21:16:19 -0600 Subject: [PATCH 39/77] Add recharts --- package-lock.json | 1003 ++++++++++++++++----------------------------- package.json | 1 + 2 files changed, 361 insertions(+), 643 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c53f21ed..f96dca742 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", "react-syntax-highlighter": "^15.5.0", + "recharts": "^2.12.7", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-github": "^12.0.0", @@ -3166,70 +3167,6 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "optional": true }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", @@ -3246,294 +3183,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -6309,323 +5958,103 @@ "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", "dev": true, "license": "MIT", - "dependencies": { - "@octokit/types": "^13.1.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/request-error/node_modules/@octokit/types": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", - "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^22.2.0" - } - }, - "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/request/node_modules/@octokit/types": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", - "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^22.2.0" - } - }, - "node_modules/@octokit/types": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", - "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^20.0.0" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", - "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.4.1", - "@parcel/watcher-darwin-arm64": "2.4.1", - "@parcel/watcher-darwin-x64": "2.4.1", - "@parcel/watcher-freebsd-x64": "2.4.1", - "@parcel/watcher-linux-arm-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-musl": "2.4.1", - "@parcel/watcher-linux-x64-glibc": "2.4.1", - "@parcel/watcher-linux-x64-musl": "2.4.1", - "@parcel/watcher-win32-arm64": "2.4.1", - "@parcel/watcher-win32-ia32": "2.4.1", - "@parcel/watcher-win32-x64": "2.4.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">= 18" } }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", - "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", - "cpu": [ - "x64" - ], + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "license": "MIT" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", + "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", - "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", - "cpu": [ - "x64" - ], + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "license": "MIT" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", + "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", - "cpu": [ - "arm64" - ], + "node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" } }, - "node_modules/@parcel/watcher-win32-ia32": { + "node_modules/@parcel/watcher": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", - "cpu": [ - "ia32" - ], + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", + "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, "engines": { "node": ">= 10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.4.1", + "@parcel/watcher-darwin-arm64": "2.4.1", + "@parcel/watcher-darwin-x64": "2.4.1", + "@parcel/watcher-freebsd-x64": "2.4.1", + "@parcel/watcher-linux-arm-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-glibc": "2.4.1", + "@parcel/watcher-linux-arm64-musl": "2.4.1", + "@parcel/watcher-linux-x64-glibc": "2.4.1", + "@parcel/watcher-linux-x64-musl": "2.4.1", + "@parcel/watcher-win32-arm64": "2.4.1", + "@parcel/watcher-win32-ia32": "2.4.1", + "@parcel/watcher-win32-x64": "2.4.1" } }, - "node_modules/@parcel/watcher-win32-x64": { + "node_modules/@parcel/watcher-darwin-arm64": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", + "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", "cpu": [ - "x64" + "arm64" ], "dev": true, "optional": true, "os": [ - "win32" + "darwin" ], "engines": { "node": ">= 10.0.0" @@ -8175,6 +7604,60 @@ "@types/har-format": "*" } }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -12752,6 +12235,116 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -12887,6 +12480,11 @@ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "dev": true }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -13195,6 +12793,15 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -14314,6 +13921,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -14472,6 +14084,14 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -16304,6 +15924,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -19628,8 +19256,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash-es": { "version": "4.17.21", @@ -23472,6 +23099,20 @@ "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -23509,6 +23150,21 @@ "react": ">= 0.14.0" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -23614,6 +23270,41 @@ "node": ">= 12.13.0" } }, + "node_modules/recharts": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.0.tgz", + "integrity": "sha512-cIvMxDfpAmqAmVgc4yb7pgm/O1tmmkl/CjrvXuW+62/+7jj/iF9Ykm+hb/UJt42TREHMyd3gb+pkgoa2MxgDIw==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -25699,6 +25390,11 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -27098,6 +26794,27 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 7c0d31263..68080871f 100755 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", "react-syntax-highlighter": "^15.5.0", + "recharts": "^2.12.7", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-github": "^12.0.0", From 56f02d9c2eb5e42ab8eb2772f3fdd91f80892b05 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 21:25:13 -0600 Subject: [PATCH 40/77] Change structure of samples --- .../components/MemoryInternals.tsx | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 5fc2b90df..fb9dbf7f2 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -108,6 +108,10 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< } `; +type Caches = NonNullable< + NonNullable["memoryInternals"] +>["caches"]; + type InternalCache = | "print" | "parser" @@ -125,22 +129,7 @@ type InternalCache = | "inMemoryCache.maybeBroadcastWatch"; const SAMPLE_RATE_MS = 5000; - -const samples: Partial< - Record> -> = { - print: [], - parser: [], - canonicalStringify: [], -}; - -type Caches = NonNullable< - NonNullable["memoryInternals"] ->["caches"]; - -const sample = throttle((caches: Caches) => { - samples.print?.push({ value: caches.print?.size ?? 0, time: new Date() }); -}, SAMPLE_RATE_MS); +const samples: Array<{ timestamp: Date; caches: Caches }> = []; const cacheComponents: Record< InternalCache, @@ -222,12 +211,6 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const memoryInternals = data?.client?.memoryInternals; const caches = memoryInternals?.caches; - useEffect(() => { - if (caches) { - sample(caches); - } - }, [caches]); - if (networkStatus === NetworkStatus.loading) { return ( From 537606c4456f97194702168371bd70515021b6ac Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 21:56:00 -0600 Subject: [PATCH 41/77] Create a sample chart --- .../components/MemoryInternals.tsx | 77 ++++++++++++++++--- 1 file changed, 68 insertions(+), 9 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index fb9dbf7f2..40a2d1d52 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -12,13 +12,23 @@ import type { MemoryInternalsQueryVariables, } from "../types/gql"; import { Select } from "./Select"; -import type { ReactElement, ReactNode } from "react"; -import { useEffect, useMemo, useState } from "react"; +import type { ReactNode } from "react"; +import { useState } from "react"; import { ButtonGroup } from "./ButtonGroup"; import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; -import throttle from "lodash.throttle"; +import { + Area, + AreaChart, + CartesianGrid, + Line, + ReferenceLine, + ResponsiveContainer, + XAxis, + YAxis, +} from "recharts"; +import { colors } from "@apollo/brand"; interface MemoryInternalsProps { clientId: string | undefined; @@ -128,8 +138,8 @@ type InternalCache = | "inMemoryCache.executeSubSelectedArray" | "inMemoryCache.maybeBroadcastWatch"; -const SAMPLE_RATE_MS = 5000; -const samples: Array<{ timestamp: Date; caches: Caches }> = []; +// const SAMPLE_RATE_MS = 5000; +// const samples: Array<{ timestamp: Date; caches: Caches }> = []; const cacheComponents: Record< InternalCache, @@ -341,10 +351,59 @@ function CacheSize({ cacheSize }: { cacheSize: CacheSize | null }) { } return ( - <> -

Limit: {cacheSize.limit}

-

Size: {cacheSize.size}

- + + + + + + + + + + + + + + + ); } From b4ec77325c340e0081260489a6a3e3460a627eb3 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 22:03:18 -0600 Subject: [PATCH 42/77] Remove need for key by using string as selected value --- .../components/MemoryInternals.tsx | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 40a2d1d52..45a685a84 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -143,70 +143,54 @@ type InternalCache = const cacheComponents: Record< InternalCache, - { key: InternalCache; render: (caches: Caches) => JSX.Element } + { render: (caches: Caches) => JSX.Element } > = { print: { - key: "print", render: (caches) => , }, parser: { - key: "parser", render: (caches) => , }, canonicalStringify: { - key: "canonicalStringify", render: (caches) => , }, - links: { key: "links", render: () => }, + links: { render: () => }, ["queryManager.getDocumentInfo"]: { - key: "queryManager.getDocumentInfo", render: () => , }, ["queryManager.documentTransforms"]: { - key: "queryManager.documentTransforms", render: () => , }, ["fragmentRegistry.lookup"]: { - key: "fragmentRegistry.lookup", render: () => , }, ["fragmentRegistry.findFragmentSpreads"]: { - key: "fragmentRegistry.findFragmentSpreads", render: () => , }, ["fragmentRegistry.transform"]: { - key: "fragmentRegistry.transform", render: () => , }, ["cache.fragmentQueryDocuments"]: { - key: "cache.fragmentQueryDocuments", render: () => , }, ["addTypenameDocumentTransform"]: { - key: "addTypenameDocumentTransform", render: () => , }, ["inMemoryCache.executeSelectionSet"]: { - key: "inMemoryCache.executeSelectionSet", render: () => , }, ["inMemoryCache.executeSubSelectedArray"]: { - key: "inMemoryCache.executeSubSelectedArray", render: () => , }, ["inMemoryCache.maybeBroadcastWatch"]: { - key: "inMemoryCache.maybeBroadcastWatch", render: () => , }, }; -type ValueOf = { [K in keyof T]: T[K] }[keyof T]; - export function MemoryInternals({ clientId }: MemoryInternalsProps) { - const [selectedCache, setSelectedCache] = useState< - ValueOf - >(cacheComponents.print); + const [selectedCache, setSelectedCache] = useState("print"); const [selectedView, setSelectedView] = useState<"raw" | "chart">("chart"); + const selectedCacheComponent = cacheComponents[selectedCache]; const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, @@ -289,16 +273,16 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { <> - {selectedCache.render(caches)} + {selectedCacheComponent.render(caches)} ) : selectedView === "raw" ? ( From 38b332640b8139c72d260690aa9f57fb159e757c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 22:16:43 -0600 Subject: [PATCH 43/77] Add max width to tooltip --- src/application/components/Tooltip/Tooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/Tooltip/Tooltip.tsx b/src/application/components/Tooltip/Tooltip.tsx index c9c6b2568..9392a9fad 100644 --- a/src/application/components/Tooltip/Tooltip.tsx +++ b/src/application/components/Tooltip/Tooltip.tsx @@ -21,7 +21,7 @@ export function Tooltip({ {content} From fd3a331c58b34ea7c7348cc640eb21fbf0ba2e5b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 22:27:45 -0600 Subject: [PATCH 44/77] Add ability to show a description for a cache component --- .../components/MemoryInternals.tsx | 67 +++++++++++++++---- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 45a685a84..37a7f23f1 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -1,8 +1,10 @@ import type { TypedDocumentNode } from "@apollo/client"; import { gql, NetworkStatus, useQuery } from "@apollo/client"; import IconOutlink from "@apollo/icons/default/IconOutlink.svg"; +import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; +import IconInfo from "@apollo/icons/default/IconInfo.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; @@ -12,7 +14,7 @@ import type { MemoryInternalsQueryVariables, } from "../types/gql"; import { Select } from "./Select"; -import type { ReactNode } from "react"; +import type { ReactElement, ReactNode } from "react"; import { useState } from "react"; import { ButtonGroup } from "./ButtonGroup"; import { Button } from "./Button"; @@ -22,7 +24,6 @@ import { Area, AreaChart, CartesianGrid, - Line, ReferenceLine, ResponsiveContainer, XAxis, @@ -143,10 +144,33 @@ type InternalCache = const cacheComponents: Record< InternalCache, - { render: (caches: Caches) => JSX.Element } + { render: (caches: Caches) => JSX.Element; description?: ReactElement } > = { print: { render: (caches) => , + description: ( + <> +

+ Cache size for the{" "} + + print + {" "} + function. +

+

+ It is called with transformed DocumentNodes. +

+

+ This method is called to transform a GraphQL query AST parsed by{" "} + gql back into a GraphQL string. +

+ + ), }, parser: { render: (caches) => , @@ -271,17 +295,32 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { {selectedView === "chart" ? ( <> - +
+ + {selectedCacheComponent.description && ( + + {selectedCacheComponent.description} +
+ } + > + + + + + )} +
{selectedCacheComponent.render(caches)} ) : selectedView === "raw" ? ( From 3c76baf91c01705af4e73d31fc5b602047469c9b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 22:49:52 -0600 Subject: [PATCH 45/77] Add a pause button --- .../components/MemoryInternals.tsx | 65 ++++++++++++------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 37a7f23f1..416dc8db6 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -5,6 +5,7 @@ import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; import IconInfo from "@apollo/icons/default/IconInfo.svg"; +import IconPause from "@apollo/icons/default/IconPause.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; @@ -30,6 +31,7 @@ import { YAxis, } from "recharts"; import { colors } from "@apollo/brand"; +import { StatusBadge } from "./StatusBadge"; interface MemoryInternalsProps { clientId: string | undefined; @@ -292,34 +294,49 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { - + {selectedView === "chart" ? ( <> -
- - {selectedCacheComponent.description && ( - - {selectedCacheComponent.description} -
+
+
+ + {selectedCacheComponent.description && ( + + {selectedCacheComponent.description} +
+ } + > + + + + + )} +
+
+ + Recording + + +
{selectedCacheComponent.render(caches)} From 38a8700d4ca62b41b3385a5b011d6621b3e3085b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 23:23:37 -0600 Subject: [PATCH 46/77] Create a useInterval hook --- src/application/hooks/useInterval.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/application/hooks/useInterval.ts diff --git a/src/application/hooks/useInterval.ts b/src/application/hooks/useInterval.ts new file mode 100644 index 000000000..a2aa532e0 --- /dev/null +++ b/src/application/hooks/useInterval.ts @@ -0,0 +1,15 @@ +import { useEffect, useLayoutEffect, useRef } from "react"; + +export function useInterval(callback: () => void, ms: number) { + const callbackRef = useRef(callback); + + useLayoutEffect(() => { + callbackRef.current = callback; + }); + + useEffect(() => { + const id = setInterval(() => callbackRef.current(), ms); + + return () => clearInterval(id); + }, [ms]); +} From cbdf3e85168c81265c21e7b2f1f20759bd7ca2f4 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 23:23:59 -0600 Subject: [PATCH 47/77] Add a working sampler for memory internals --- .../components/MemoryInternals.tsx | 101 +++++++++++------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 416dc8db6..f9eed9193 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -25,6 +25,8 @@ import { Area, AreaChart, CartesianGrid, + Line, + LineChart, ReferenceLine, ResponsiveContainer, XAxis, @@ -32,6 +34,7 @@ import { } from "recharts"; import { colors } from "@apollo/brand"; import { StatusBadge } from "./StatusBadge"; +import { useInterval } from "../hooks/useInterval"; interface MemoryInternalsProps { clientId: string | undefined; @@ -141,15 +144,26 @@ type InternalCache = | "inMemoryCache.executeSubSelectedArray" | "inMemoryCache.maybeBroadcastWatch"; -// const SAMPLE_RATE_MS = 5000; -// const samples: Array<{ timestamp: Date; caches: Caches }> = []; +const SAMPLE_RATE_MS = 1000; + +interface Sample { + timestamp: number; + caches: Caches; +} const cacheComponents: Record< InternalCache, - { render: (caches: Caches) => JSX.Element; description?: ReactElement } + { render: (samples: Sample[]) => JSX.Element; description?: ReactElement } > = { print: { - render: (caches) => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.print, + }))} + /> + ), description: ( <>

@@ -175,10 +189,10 @@ const cacheComponents: Record< ), }, parser: { - render: (caches) => , + render: () => , }, canonicalStringify: { - render: (caches) => , + render: () => , }, links: { render: () => }, ["queryManager.getDocumentInfo"]: { @@ -217,6 +231,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const [selectedCache, setSelectedCache] = useState("print"); const [selectedView, setSelectedView] = useState<"raw" | "chart">("chart"); const selectedCacheComponent = cacheComponents[selectedCache]; + const [samples, setSamples] = useState([]); const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, @@ -231,6 +246,12 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const memoryInternals = data?.client?.memoryInternals; const caches = memoryInternals?.caches; + useInterval(() => { + if (caches) { + setSamples((prev) => [...prev, { timestamp: Date.now(), caches }]); + } + }, SAMPLE_RATE_MS); + if (networkStatus === NetworkStatus.loading) { return ( @@ -338,7 +359,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { - {selectedCacheComponent.render(caches)} + {selectedCacheComponent.render(samples)} ) : selectedView === "raw" ? ( @@ -385,25 +406,34 @@ function EmptyLayout({ children }: { children: ReactNode }) { ); } -function CacheSize({ cacheSize }: { cacheSize: CacheSize | null }) { - if (!cacheSize) { - return

No cache found

; +function CacheSize({ + samples, +}: { + samples: Array<{ timestamp: number; cacheSize: CacheSize | null }>; +}) { + const baseTimestamp = samples[0]?.timestamp ?? 0; + const limit = samples[0]?.cacheSize?.limit ?? 0; + + // Don't redraw every second but instead wait until we have the next batch of + // samples. + const throttledLength = Math.floor(samples.length / 5) * 5; + + if (samples.length < 10) { + return ( +
+ Gathering data... +
+ ); } return ( - ({ + ms: sample.timestamp - baseTimestamp, + size: sample.cacheSize?.size, + limit: sample.cacheSize?.limit, + }))} > @@ -420,29 +450,28 @@ function CacheSize({ cacheSize }: { cacheSize: CacheSize | null }) { - + - - - + {limit > 0 && ( + + )} + ); } From 3b8a839daf9bc7e07365e33e6c02337de872d84a Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 23:27:03 -0600 Subject: [PATCH 48/77] Add spinner. Only show initial message if samples < 5 --- src/application/components/MemoryInternals.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index f9eed9193..6f7c21898 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -35,6 +35,7 @@ import { import { colors } from "@apollo/brand"; import { StatusBadge } from "./StatusBadge"; import { useInterval } from "../hooks/useInterval"; +import { Spinner } from "./Spinner"; interface MemoryInternalsProps { clientId: string | undefined; @@ -418,10 +419,10 @@ function CacheSize({ // samples. const throttledLength = Math.floor(samples.length / 5) * 5; - if (samples.length < 10) { + if (samples.length < 5) { return (
- Gathering data... + Gathering samples
); } From 43f8d9e357c09b7f585ade47a57cfecdc8f2aef2 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 23:36:28 -0600 Subject: [PATCH 49/77] Add more caches, chart tooltip, and show in seconds --- .../components/MemoryInternals.tsx | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 6f7c21898..be1c15f80 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -22,8 +22,6 @@ import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; import { - Area, - AreaChart, CartesianGrid, Line, LineChart, @@ -31,6 +29,7 @@ import { ResponsiveContainer, XAxis, YAxis, + Tooltip as ChartTooltip, } from "recharts"; import { colors } from "@apollo/brand"; import { StatusBadge } from "./StatusBadge"; @@ -190,10 +189,24 @@ const cacheComponents: Record< ), }, parser: { - render: () => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.parser, + }))} + /> + ), }, canonicalStringify: { - render: () => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.canonicalStringify, + }))} + /> + ), }, links: { render: () => }, ["queryManager.getDocumentInfo"]: { @@ -218,13 +231,34 @@ const cacheComponents: Record< render: () => , }, ["inMemoryCache.executeSelectionSet"]: { - render: () => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.inMemoryCache.executeSelectionSet, + }))} + /> + ), }, ["inMemoryCache.executeSubSelectedArray"]: { - render: () => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.inMemoryCache.executeSubSelectedArray, + }))} + /> + ), }, ["inMemoryCache.maybeBroadcastWatch"]: { - render: () => , + render: (samples) => ( + ({ + timestamp: sample.timestamp, + cacheSize: sample.caches.inMemoryCache.maybeBroadcastWatch, + }))} + /> + ), }, }; @@ -431,7 +465,7 @@ function CacheSize({ ({ - ms: sample.timestamp - baseTimestamp, + timestamp: Math.floor((sample.timestamp - baseTimestamp) / 60), size: sample.cacheSize?.size, limit: sample.cacheSize?.limit, }))} @@ -451,11 +485,15 @@ function CacheSize({ + [0, Math.max(max, 100)]} /> - + {limit > 0 && ( Date: Wed, 21 Aug 2024 23:45:51 -0600 Subject: [PATCH 50/77] Switch back to area chart --- src/application/components/MemoryInternals.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index be1c15f80..066ef2871 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -23,13 +23,13 @@ import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; import { CartesianGrid, - Line, - LineChart, ReferenceLine, ResponsiveContainer, XAxis, YAxis, Tooltip as ChartTooltip, + AreaChart, + Area, } from "recharts"; import { colors } from "@apollo/brand"; import { StatusBadge } from "./StatusBadge"; @@ -463,7 +463,7 @@ function CacheSize({ return ( - ({ timestamp: Math.floor((sample.timestamp - baseTimestamp) / 60), size: sample.cacheSize?.size, @@ -492,26 +492,29 @@ function CacheSize({ [0, Math.max(max, 100)]} + domain={([, dataMax]) => [0, Math.max(dataMax, 100, limit)]} /> - {limit > 0 && ( )} - + ); } From 497157a4f1deaf6766d8c7bddf874a7067fcba17 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 21 Aug 2024 23:49:45 -0600 Subject: [PATCH 51/77] Force mount memory tab to keep it running --- src/application/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/application/App.tsx b/src/application/App.tsx index 3ebc23f76..db8be3031 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -278,6 +278,7 @@ export const App = () => { From c22e6979e84922aad13f9606f4655a33d87e81fc Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 28 Aug 2024 09:00:06 -0600 Subject: [PATCH 52/77] Use the same limit variable --- src/application/components/MemoryInternals.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 066ef2871..77b2dde22 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -467,7 +467,7 @@ function CacheSize({ data={samples.slice(0, throttledLength).map((sample) => ({ timestamp: Math.floor((sample.timestamp - baseTimestamp) / 60), size: sample.cacheSize?.size, - limit: sample.cacheSize?.limit, + limit, }))} > From 14953a1dfedb7129ccd2c04b407f706956eb2330 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 10:26:42 -0700 Subject: [PATCH 53/77] Always expand memory json --- src/application/components/MemoryInternals.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 77b2dde22..e19559c57 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -397,7 +397,11 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { {selectedCacheComponent.render(samples)} ) : selectedView === "raw" ? ( - + true} + /> ) : null}
From 9f325b43c84be0a5ce55f8289d969ca907ddbabc Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 10:32:16 -0700 Subject: [PATCH 54/77] Increase poll interval to 1s --- src/application/components/MemoryInternals.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index e19559c57..21d1a3c19 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -271,7 +271,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, skip: !clientId, - pollInterval: 500, + pollInterval: 1000, }); if (error) { From b9a1c54079f14b1398554ca352ebaf5a3fb6f883 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 10:50:36 -0700 Subject: [PATCH 55/77] Add key to cache sizes and make them non-nullable --- src/application/localSchema.graphql | 29 ++++++------ src/application/schema.ts | 63 +++++++++++++++----------- src/application/types/gql.ts | 59 ++++++++++++------------ src/application/types/resolvers.ts | 70 +++++++++++++---------------- 4 files changed, 112 insertions(+), 109 deletions(-) diff --git a/src/application/localSchema.graphql b/src/application/localSchema.graphql index b86ecbb12..348d56446 100644 --- a/src/application/localSchema.graphql +++ b/src/application/localSchema.graphql @@ -19,10 +19,11 @@ type Query { } type BaseCacheSizes { - fragmentQueryDocuments: CacheSize + fragmentQueryDocuments: CacheSize! } type CacheSize { + key: String! limit: Int size: Int } @@ -48,19 +49,19 @@ type ClientMutations { } type DocumentTransformCacheSizes { - cache: CacheSize + cache: CacheSize! } type FragmentRegistryCacheSizes { - lookup: CacheSize - findFragmentSpreads: CacheSize - transform: CacheSize + lookup: CacheSize! + findFragmentSpreads: CacheSize! + transform: CacheSize! } type InMemoryCacheSizes { - maybeBroadcastWatch: CacheSize - executeSelectionSet: CacheSize - executeSubSelectedArray: CacheSize + maybeBroadcastWatch: CacheSize! + executeSelectionSet: CacheSize! + executeSubSelectedArray: CacheSize! } union LinkCacheSize = @@ -73,9 +74,9 @@ type MemoryInternals { } type MemoryInternalsCaches { - print: CacheSize - parser: CacheSize - canonicalStringify: CacheSize + print: CacheSize! + parser: CacheSize! + canonicalStringify: CacheSize! links: [LinkCacheSize!]! queryManager: QueryManagerCacheSizes! fragmentRegistry: FragmentRegistryCacheSizes! @@ -85,16 +86,16 @@ type MemoryInternalsCaches { } type QueryManagerCacheSizes { - getDocumentInfo: CacheSize + getDocumentInfo: CacheSize! documentTransforms: [DocumentTransformCacheSizes!] } type PersistedQueryLinkCacheSizes { - persistedQueryHashes: CacheSize + persistedQueryHashes: CacheSize! } type RemoveTypenameFromVariablesLinkCacheSizes { - getVariableDefinitions: CacheSize + getVariableDefinitions: CacheSize! } type WatchedMutation { diff --git a/src/application/schema.ts b/src/application/schema.ts index a8603d400..b0fe2e30b 100644 --- a/src/application/schema.ts +++ b/src/application/schema.ts @@ -44,19 +44,21 @@ function createResolvers(client: RpcClient): Resolvers { return { raw: memoryInternals, caches: { - print: getCacheSize(sizes.print, limits.print), - parser: getCacheSize(sizes.parser, limits.parser), + print: getCacheSize("print", sizes.print, limits), + parser: getCacheSize("parser", sizes.parser, limits), canonicalStringify: getCacheSize( + "canonicalStringify", sizes.canonicalStringify, - limits.canonicalStringify + limits ), links: sizes.links .map((linkCache) => getLinkCacheSize(linkCache, limits)) .filter(Boolean), queryManager: { getDocumentInfo: getCacheSize( + "queryManager.getDocumentInfo", sizes.queryManager.getDocumentInfo, - limits["queryManager.getDocumentInfo"] + limits ), documentTransforms: getDocumentTransformCacheSizes( sizes.queryManager.documentTransforms, @@ -65,22 +67,26 @@ function createResolvers(client: RpcClient): Resolvers { }, fragmentRegistry: { lookup: getCacheSize( + "fragmentRegistry.lookup", sizes.fragmentRegistry?.lookup, - limits["fragmentRegistry.lookup"] + limits ), findFragmentSpreads: getCacheSize( + "fragmentRegistry.findFragmentSpreads", sizes.fragmentRegistry?.findFragmentSpreads, - limits["fragmentRegistry.findFragmentSpreads"] + limits ), transform: getCacheSize( + "fragmentRegistry.transform", sizes.fragmentRegistry?.transform, - limits["fragmentRegistry.transform"] + limits ), }, cache: { fragmentQueryDocuments: getCacheSize( + "cache.fragmentQueryDocuments", sizes.cache?.fragmentQueryDocuments, - limits["cache.fragmentQueryDocuments"] + limits ), }, addTypenameDocumentTransform: sizes.addTypenameDocumentTransform @@ -91,16 +97,19 @@ function createResolvers(client: RpcClient): Resolvers { : null, inMemoryCache: { maybeBroadcastWatch: getCacheSize( + "inMemoryCache.maybeBroadcastWatch", sizes.inMemoryCache?.maybeBroadcastWatch, - limits["inMemoryCache.maybeBroadcastWatch"] + limits ), executeSelectionSet: getCacheSize( + "inMemoryCache.executeSelectionSet", sizes.inMemoryCache?.executeSelectionSet, - limits["inMemoryCache.executeSelectionSet"] + limits ), executeSubSelectedArray: getCacheSize( + "inMemoryCache.executeSubSelectedArray", sizes.inMemoryCache?.executeSubSelectedArray, - limits["inMemoryCache.executeSubSelectedArray"] + limits ), }, }, @@ -164,12 +173,12 @@ function createResolvers(client: RpcClient): Resolvers { type MemoryLimits = Record; -function getCacheSize(size: number | undefined, limit: number | undefined) { - if (!size) { - return null; - } - - return { size, limit: limit ?? null }; +function getCacheSize( + key: string, + size: number | undefined, + limits: MemoryLimits +) { + return { key, size: size ?? null, limit: limits[key] ?? null }; } function getDocumentTransformCacheSizes( @@ -177,7 +186,7 @@ function getDocumentTransformCacheSizes( limits: MemoryLimits ) { return caches.map(({ cache }) => ({ - cache: getCacheSize(cache, limits["documentTransform.cache"]), + cache: getCacheSize("documentTransform.cache", cache, limits), })); } @@ -220,19 +229,21 @@ function getLinkCacheSize( | null { if (isPersistedQueryLinkCache(linkCache)) { return { - persistedQueryHashes: { - size: linkCache.PersistedQueryLink.persistedQueryHashes, - limit: limits["PersistedQueryLink.persistedQueryHashes"], - }, + persistedQueryHashes: getCacheSize( + "PersistedQueryLink.persistedQueryHashes", + linkCache.PersistedQueryLink.persistedQueryHashes, + limits + ), } satisfies PersistedQueryLinkCacheSizes; } if (isRemoveTypenameFromVariablesLinkCache(linkCache)) { return { - getVariableDefinitions: { - size: linkCache.removeTypenameFromVariables.getVariableDefinitions, - limit: limits["removeTypenameFromVariables.getVariableDefinitions"], - }, + getVariableDefinitions: getCacheSize( + "removeTypenameFromVariables.getVariableDefinitions", + linkCache.removeTypenameFromVariables.getVariableDefinitions, + limits + ), } satisfies RemoveTypenameFromVariablesLinkCacheSizes; } diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index f24a910fa..fc6a026cb 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -45,11 +45,12 @@ export type Scalars = { export type BaseCacheSizes = { __typename: "BaseCacheSizes"; - fragmentQueryDocuments: Maybe; + fragmentQueryDocuments: CacheSize; }; export type CacheSize = { __typename: "CacheSize"; + key: Scalars["String"]["output"]; limit: Maybe; size: Maybe; }; @@ -79,14 +80,14 @@ export type ClientQueries = { export type DocumentTransformCacheSizes = { __typename: "DocumentTransformCacheSizes"; - cache: Maybe; + cache: CacheSize; }; export type FragmentRegistryCacheSizes = { __typename: "FragmentRegistryCacheSizes"; - findFragmentSpreads: Maybe; - lookup: Maybe; - transform: Maybe; + findFragmentSpreads: CacheSize; + lookup: CacheSize; + transform: CacheSize; }; export type GraphQLErrorSourceLocation = { @@ -97,9 +98,9 @@ export type GraphQLErrorSourceLocation = { export type InMemoryCacheSizes = { __typename: "InMemoryCacheSizes"; - executeSelectionSet: Maybe; - executeSubSelectedArray: Maybe; - maybeBroadcastWatch: Maybe; + executeSelectionSet: CacheSize; + executeSubSelectedArray: CacheSize; + maybeBroadcastWatch: CacheSize; }; export type LinkCacheSize = @@ -116,18 +117,18 @@ export type MemoryInternalsCaches = { __typename: "MemoryInternalsCaches"; addTypenameDocumentTransform: Maybe>; cache: BaseCacheSizes; - canonicalStringify: Maybe; + canonicalStringify: CacheSize; fragmentRegistry: FragmentRegistryCacheSizes; inMemoryCache: InMemoryCacheSizes; links: Array; - parser: Maybe; - print: Maybe; + parser: CacheSize; + print: CacheSize; queryManager: QueryManagerCacheSizes; }; export type PersistedQueryLinkCacheSizes = { __typename: "PersistedQueryLinkCacheSizes"; - persistedQueryHashes: Maybe; + persistedQueryHashes: CacheSize; }; export type Query = { @@ -143,12 +144,12 @@ export type QueryclientArgs = { export type QueryManagerCacheSizes = { __typename: "QueryManagerCacheSizes"; documentTransforms: Maybe>; - getDocumentInfo: Maybe; + getDocumentInfo: CacheSize; }; export type RemoveTypenameFromVariablesLinkCacheSizes = { __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; - getVariableDefinitions: Maybe; + getVariableDefinitions: CacheSize; }; export type SerializedApolloError = { @@ -270,17 +271,17 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; parser: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; canonicalStringify: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; links: Array< | { __typename: "PersistedQueryLinkCacheSizes"; @@ -288,7 +289,7 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; } | { __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; @@ -296,7 +297,7 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; } >; queryManager: { @@ -305,14 +306,14 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; documentTransforms: Array<{ __typename: "DocumentTransformCacheSizes"; cache: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; }> | null; }; fragmentRegistry: { @@ -321,17 +322,17 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; findFragmentSpreads: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; transform: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; }; cache: { __typename: "BaseCacheSizes"; @@ -339,7 +340,7 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; }; addTypenameDocumentTransform: Array<{ __typename: "DocumentTransformCacheSizes"; @@ -347,7 +348,7 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; }> | null; inMemoryCache: { __typename: "InMemoryCacheSizes"; @@ -355,17 +356,17 @@ export type MemoryInternalsQuery = { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; executeSelectionSet: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; executeSubSelectedArray: { __typename: "CacheSize"; size: number | null; limit: number | null; - } | null; + }; }; }; } | null; diff --git a/src/application/types/resolvers.ts b/src/application/types/resolvers.ts index aaa8b2f2e..774852f66 100644 --- a/src/application/types/resolvers.ts +++ b/src/application/types/resolvers.ts @@ -58,11 +58,12 @@ export type Scalars = { export type BaseCacheSizes = { __typename?: "BaseCacheSizes"; - fragmentQueryDocuments?: Maybe; + fragmentQueryDocuments: CacheSize; }; export type CacheSize = { __typename?: "CacheSize"; + key: Scalars["String"]["output"]; limit?: Maybe; size?: Maybe; }; @@ -92,14 +93,14 @@ export type ClientQueries = { export type DocumentTransformCacheSizes = { __typename?: "DocumentTransformCacheSizes"; - cache?: Maybe; + cache: CacheSize; }; export type FragmentRegistryCacheSizes = { __typename?: "FragmentRegistryCacheSizes"; - findFragmentSpreads?: Maybe; - lookup?: Maybe; - transform?: Maybe; + findFragmentSpreads: CacheSize; + lookup: CacheSize; + transform: CacheSize; }; export type GraphQlErrorSourceLocation = { @@ -110,9 +111,9 @@ export type GraphQlErrorSourceLocation = { export type InMemoryCacheSizes = { __typename?: "InMemoryCacheSizes"; - executeSelectionSet?: Maybe; - executeSubSelectedArray?: Maybe; - maybeBroadcastWatch?: Maybe; + executeSelectionSet: CacheSize; + executeSubSelectedArray: CacheSize; + maybeBroadcastWatch: CacheSize; }; export type LinkCacheSize = @@ -129,18 +130,18 @@ export type MemoryInternalsCaches = { __typename?: "MemoryInternalsCaches"; addTypenameDocumentTransform?: Maybe>; cache: BaseCacheSizes; - canonicalStringify?: Maybe; + canonicalStringify: CacheSize; fragmentRegistry: FragmentRegistryCacheSizes; inMemoryCache: InMemoryCacheSizes; links: Array; - parser?: Maybe; - print?: Maybe; + parser: CacheSize; + print: CacheSize; queryManager: QueryManagerCacheSizes; }; export type PersistedQueryLinkCacheSizes = { __typename?: "PersistedQueryLinkCacheSizes"; - persistedQueryHashes?: Maybe; + persistedQueryHashes: CacheSize; }; export type Query = { @@ -156,12 +157,12 @@ export type QueryClientArgs = { export type QueryManagerCacheSizes = { __typename?: "QueryManagerCacheSizes"; documentTransforms?: Maybe>; - getDocumentInfo?: Maybe; + getDocumentInfo: CacheSize; }; export type RemoveTypenameFromVariablesLinkCacheSizes = { __typename?: "RemoveTypenameFromVariablesLinkCacheSizes"; - getVariableDefinitions?: Maybe; + getVariableDefinitions: CacheSize; }; export type SerializedApolloError = { @@ -441,7 +442,7 @@ export type BaseCacheSizesResolvers< ResolversParentTypes["BaseCacheSizes"] = ResolversParentTypes["BaseCacheSizes"], > = { fragmentQueryDocuments?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; @@ -458,6 +459,7 @@ export type CacheSizeResolvers< ParentType extends ResolversParentTypes["CacheSize"] = ResolversParentTypes["CacheSize"], > = { + key?: Resolver; limit?: Resolver, ParentType, ContextType>; size?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; @@ -519,7 +521,7 @@ export type DocumentTransformCacheSizesResolvers< ParentType extends ResolversParentTypes["DocumentTransformCacheSizes"] = ResolversParentTypes["DocumentTransformCacheSizes"], > = { - cache?: Resolver, ParentType, ContextType>; + cache?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -529,20 +531,12 @@ export type FragmentRegistryCacheSizesResolvers< ResolversParentTypes["FragmentRegistryCacheSizes"] = ResolversParentTypes["FragmentRegistryCacheSizes"], > = { findFragmentSpreads?: Resolver< - Maybe, - ParentType, - ContextType - >; - lookup?: Resolver< - Maybe, - ParentType, - ContextType - >; - transform?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; + lookup?: Resolver; + transform?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -567,17 +561,17 @@ export type InMemoryCacheSizesResolvers< ResolversParentTypes["InMemoryCacheSizes"] = ResolversParentTypes["InMemoryCacheSizes"], > = { executeSelectionSet?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; executeSubSelectedArray?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; maybeBroadcastWatch?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; @@ -628,7 +622,7 @@ export type MemoryInternalsCachesResolvers< >; cache?: Resolver; canonicalStringify?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; @@ -647,12 +641,8 @@ export type MemoryInternalsCachesResolvers< ParentType, ContextType >; - parser?: Resolver< - Maybe, - ParentType, - ContextType - >; - print?: Resolver, ParentType, ContextType>; + parser?: Resolver; + print?: Resolver; queryManager?: Resolver< ResolversTypes["QueryManagerCacheSizes"], ParentType, @@ -667,7 +657,7 @@ export type PersistedQueryLinkCacheSizesResolvers< ResolversParentTypes["PersistedQueryLinkCacheSizes"] = ResolversParentTypes["PersistedQueryLinkCacheSizes"], > = { persistedQueryHashes?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; @@ -704,7 +694,7 @@ export type QueryManagerCacheSizesResolvers< ContextType >; getDocumentInfo?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; @@ -722,7 +712,7 @@ export type RemoveTypenameFromVariablesLinkCacheSizesResolvers< ResolversParentTypes["RemoveTypenameFromVariablesLinkCacheSizes"] = ResolversParentTypes["RemoveTypenameFromVariablesLinkCacheSizes"], > = { getVariableDefinitions?: Resolver< - Maybe, + ResolversTypes["CacheSize"], ParentType, ContextType >; From 34b407c4067292091ca01d0b8b568294ef613030 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 11:50:34 -0700 Subject: [PATCH 56/77] First pass at changing view for memory internals --- .../components/MemoryInternals.tsx | 400 +++++------------- src/application/schema.ts | 2 + src/application/types/gql.ts | 16 + 3 files changed, 133 insertions(+), 285 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 21d1a3c19..f6d66afb4 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -5,7 +5,6 @@ import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; import IconInfo from "@apollo/icons/default/IconInfo.svg"; -import IconPause from "@apollo/icons/default/IconPause.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; @@ -14,27 +13,14 @@ import type { MemoryInternalsQuery, MemoryInternalsQueryVariables, } from "../types/gql"; -import { Select } from "./Select"; -import type { ReactElement, ReactNode } from "react"; +import type { ReactNode } from "react"; import { useState } from "react"; import { ButtonGroup } from "./ButtonGroup"; import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; -import { - CartesianGrid, - ReferenceLine, - ResponsiveContainer, - XAxis, - YAxis, - Tooltip as ChartTooltip, - AreaChart, - Area, -} from "recharts"; -import { colors } from "@apollo/brand"; -import { StatusBadge } from "./StatusBadge"; -import { useInterval } from "../hooks/useInterval"; -import { Spinner } from "./Spinner"; +import type { CacheSizes } from "@apollo/client/utilities"; +import clsx from "clsx"; interface MemoryInternalsProps { clientId: string | undefined; @@ -119,6 +105,7 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< } fragment CacheSizeFields on CacheSize { + key size limit } @@ -128,145 +115,47 @@ type Caches = NonNullable< NonNullable["memoryInternals"] >["caches"]; -type InternalCache = - | "print" - | "parser" - | "canonicalStringify" - | "links" - | "queryManager.getDocumentInfo" - | "queryManager.documentTransforms" - | "fragmentRegistry.lookup" - | "fragmentRegistry.findFragmentSpreads" - | "fragmentRegistry.transform" - | "cache.fragmentQueryDocuments" - | "addTypenameDocumentTransform" - | "inMemoryCache.executeSelectionSet" - | "inMemoryCache.executeSubSelectedArray" - | "inMemoryCache.maybeBroadcastWatch"; - -const SAMPLE_RATE_MS = 1000; - -interface Sample { - timestamp: number; - caches: Caches; -} - -const cacheComponents: Record< - InternalCache, - { render: (samples: Sample[]) => JSX.Element; description?: ReactElement } -> = { - print: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.print, - }))} - /> - ), - description: ( - <> -

- Cache size for the{" "} - - print - {" "} - function. -

-

- It is called with transformed DocumentNodes. -

-

- This method is called to transform a GraphQL query AST parsed by{" "} - gql back into a GraphQL string. -

- - ), - }, - parser: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.parser, - }))} - /> - ), - }, - canonicalStringify: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.canonicalStringify, - }))} - /> - ), - }, - links: { render: () => }, - ["queryManager.getDocumentInfo"]: { - render: () => , - }, - ["queryManager.documentTransforms"]: { - render: () => , - }, - ["fragmentRegistry.lookup"]: { - render: () => , - }, - ["fragmentRegistry.findFragmentSpreads"]: { - render: () => , - }, - ["fragmentRegistry.transform"]: { - render: () => , - }, - ["cache.fragmentQueryDocuments"]: { - render: () => , - }, - ["addTypenameDocumentTransform"]: { - render: () => , - }, - ["inMemoryCache.executeSelectionSet"]: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.inMemoryCache.executeSelectionSet, - }))} - /> - ), - }, - ["inMemoryCache.executeSubSelectedArray"]: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.inMemoryCache.executeSubSelectedArray, - }))} - /> - ), - }, - ["inMemoryCache.maybeBroadcastWatch"]: { - render: (samples) => ( - ({ - timestamp: sample.timestamp, - cacheSize: sample.caches.inMemoryCache.maybeBroadcastWatch, - }))} - /> - ), - }, +const descriptions: Record = { + print: ( + <> +

+ Cache size for the{" "} + + print + {" "} + function. +

+

+ It is called with transformed DocumentNodes. +

+

+ This method is called to transform a GraphQL query AST parsed by{" "} + gql back into a GraphQL string. +

+ + ), + parser: "", + canonicalStringify: "", + "PersistedQueryLink.persistedQueryHashes": "", + "removeTypenameFromVariables.getVariableDefinitions": "", + "queryManager.getDocumentInfo": "", + "documentTransform.cache": "", + "fragmentRegistry.lookup": "", + "fragmentRegistry.findFragmentSpreads": "", + "fragmentRegistry.transform": "", + "cache.fragmentQueryDocuments": "", + "inMemoryCache.executeSelectionSet": "", + "inMemoryCache.executeSubSelectedArray": "", + "inMemoryCache.maybeBroadcastWatch": "", }; export function MemoryInternals({ clientId }: MemoryInternalsProps) { - const [selectedCache, setSelectedCache] = useState("print"); const [selectedView, setSelectedView] = useState<"raw" | "chart">("chart"); - const selectedCacheComponent = cacheComponents[selectedCache]; - const [samples, setSamples] = useState([]); const { data, networkStatus, error } = useQuery(MEMORY_INTERNALS_QUERY, { variables: { clientId: clientId as string }, @@ -281,12 +170,6 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const memoryInternals = data?.client?.memoryInternals; const caches = memoryInternals?.caches; - useInterval(() => { - if (caches) { - setSamples((prev) => [...prev, { timestamp: Date.now(), caches }]); - } - }, SAMPLE_RATE_MS); - if (networkStatus === NetworkStatus.loading) { return ( @@ -352,50 +235,37 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { {selectedView === "chart" ? ( - <> -
-
- - {selectedCacheComponent.description && ( - - {selectedCacheComponent.description} -
- } - > - - - - - )} -
-
- - Recording - - -
- - {selectedCacheComponent.render(samples)} - +
+ + {caches.queryManager.documentTransforms?.map(({ cache }, index) => ( + + ))} + + + + + + + {caches.links.map((link, index) => ( + + ))} + + + + + +
) : selectedView === "raw" ? ( - {label} - - ); -} - function EmptyLayout({ children }: { children: ReactNode }) { return ( @@ -445,84 +307,52 @@ function EmptyLayout({ children }: { children: ReactNode }) { ); } -function CacheSize({ - samples, -}: { - samples: Array<{ timestamp: number; cacheSize: CacheSize | null }>; -}) { - const baseTimestamp = samples[0]?.timestamp ?? 0; - const limit = samples[0]?.cacheSize?.limit ?? 0; - - // Don't redraw every second but instead wait until we have the next batch of - // samples. - const throttledLength = Math.floor(samples.length / 5) * 5; - - if (samples.length < 5) { - return ( -
- Gathering samples -
- ); +function CacheSize({ cacheSize }: { cacheSize: CacheSize }) { + if (cacheSize.size === null || cacheSize.limit === null) { + return null; } + const description = descriptions[cacheSize.key as keyof CacheSizes]; + const percentUsed = (cacheSize.size / cacheSize.limit) * 100; + return ( - - ({ - timestamp: Math.floor((sample.timestamp - baseTimestamp) / 60), - size: sample.cacheSize?.size, - limit, - }))} - > - - - - - - - - [0, Math.max(dataMax, 100, limit)]} - /> - - - - {limit > 0 && ( - +
+

+ {cacheSize.key} + {description && ( + {description}

} + > + + + + )} -
-
+ +
+
+ + Size + + {cacheSize.size} +
+
+ + Limit + + {cacheSize.limit} +
+
= 90, + "text-warning dark:text-warning-dark": + percentUsed >= 70 && percentUsed < 90, + "text-success dark:text-success-dark-dark": percentUsed < 70, + })} + > + {percentUsed.toFixed(1)}% +
+
+ ); } - -function TODOCacheSize() { - return "TODO: Implement me"; -} diff --git a/src/application/schema.ts b/src/application/schema.ts index b0fe2e30b..1345db416 100644 --- a/src/application/schema.ts +++ b/src/application/schema.ts @@ -229,6 +229,7 @@ function getLinkCacheSize( | null { if (isPersistedQueryLinkCache(linkCache)) { return { + __typename: "PersistedQueryLinkCacheSizes", persistedQueryHashes: getCacheSize( "PersistedQueryLink.persistedQueryHashes", linkCache.PersistedQueryLink.persistedQueryHashes, @@ -239,6 +240,7 @@ function getLinkCacheSize( if (isRemoveTypenameFromVariablesLinkCache(linkCache)) { return { + __typename: "RemoveTypenameFromVariablesLinkCacheSizes", getVariableDefinitions: getCacheSize( "removeTypenameFromVariables.getVariableDefinitions", linkCache.removeTypenameFromVariables.getVariableDefinitions, diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index fc6a026cb..c82f45925 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -269,16 +269,19 @@ export type MemoryInternalsQuery = { __typename: "MemoryInternalsCaches"; print: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; parser: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; canonicalStringify: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -287,6 +290,7 @@ export type MemoryInternalsQuery = { __typename: "PersistedQueryLinkCacheSizes"; persistedQueryHashes: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -295,6 +299,7 @@ export type MemoryInternalsQuery = { __typename: "RemoveTypenameFromVariablesLinkCacheSizes"; getVariableDefinitions: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -304,6 +309,7 @@ export type MemoryInternalsQuery = { __typename: "QueryManagerCacheSizes"; getDocumentInfo: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -311,6 +317,7 @@ export type MemoryInternalsQuery = { __typename: "DocumentTransformCacheSizes"; cache: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -320,16 +327,19 @@ export type MemoryInternalsQuery = { __typename: "FragmentRegistryCacheSizes"; lookup: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; findFragmentSpreads: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; transform: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -338,6 +348,7 @@ export type MemoryInternalsQuery = { __typename: "BaseCacheSizes"; fragmentQueryDocuments: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -346,6 +357,7 @@ export type MemoryInternalsQuery = { __typename: "DocumentTransformCacheSizes"; cache: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -354,16 +366,19 @@ export type MemoryInternalsQuery = { __typename: "InMemoryCacheSizes"; maybeBroadcastWatch: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; executeSelectionSet: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; executeSubSelectedArray: { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; @@ -375,6 +390,7 @@ export type MemoryInternalsQuery = { export type CacheSizeFields = { __typename: "CacheSize"; + key: string; size: number | null; limit: number | null; }; From f2bf67b6af690f01a8e5ba13946bc8221e88c657 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 11:51:20 -0700 Subject: [PATCH 57/77] Remove unused type --- src/application/components/MemoryInternals.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index f6d66afb4..148a38a78 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -111,10 +111,6 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< } `; -type Caches = NonNullable< - NonNullable["memoryInternals"] ->["caches"]; - const descriptions: Record = { print: ( <> From 0d1dd6a1be1fb9423addc93a356f889c9bd532c0 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 11:58:11 -0700 Subject: [PATCH 58/77] Add more descriptions --- .../components/MemoryInternals.tsx | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 148a38a78..bcbf1d72e 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -21,6 +21,7 @@ import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; import type { CacheSizes } from "@apollo/client/utilities"; import clsx from "clsx"; +import { ExternalLink } from "./ExternalLink"; interface MemoryInternalsProps { clientId: string | undefined; @@ -116,14 +117,12 @@ const descriptions: Record = { <>

Cache size for the{" "} - - print - {" "} + print + {" "} function.

@@ -135,8 +134,34 @@ const descriptions: Record = {

), - parser: "", - canonicalStringify: "", + parser: ( + <> +

+ Cache size for the{" "} + + parser + {" "} + function. +

+

+ It is called with user-provided DocumentNodes. +

+ + ), + canonicalStringify: ( +

+ Cache used by{" "} + + canonicalStringify + +

+ ), "PersistedQueryLink.persistedQueryHashes": "", "removeTypenameFromVariables.getVariableDefinitions": "", "queryManager.getDocumentInfo": "", From 96bfae1ad3e1a14b4d4a0afa4ac2d6981f778302 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 13:15:34 -0700 Subject: [PATCH 59/77] Update spacing and use icon for warning --- .../components/MemoryInternals.tsx | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index bcbf1d72e..7d485b537 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -5,6 +5,7 @@ import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; import IconInfo from "@apollo/icons/default/IconInfo.svg"; +import IconWarning from "@apollo/icons/large/IconWarning.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; @@ -213,7 +214,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { } return ( - +

@@ -256,7 +257,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) {

{selectedView === "chart" ? ( -
+
{caches.queryManager.documentTransforms?.map(({ cache }, index) => ( @@ -337,9 +338,9 @@ function CacheSize({ cacheSize }: { cacheSize: CacheSize }) { const percentUsed = (cacheSize.size / cacheSize.limit) * 100; return ( -
+

- {cacheSize.key} + {cacheSize.key} {description && ( {description}

} @@ -350,28 +351,33 @@ function CacheSize({ cacheSize }: { cacheSize: CacheSize }) { )} -
-
- +
+
+ Size {cacheSize.size}
-
- +
+ Limit {cacheSize.limit}
= 90, - "text-warning dark:text-warning-dark": - percentUsed >= 70 && percentUsed < 90, - "text-success dark:text-success-dark-dark": percentUsed < 70, - })} + className={clsx( + "text-3xl text-right flex-1 font-code flex gap-2 items-center justify-end", + { + "text-error dark:text-error-dark": percentUsed >= 90, + "text-warning dark:text-warning-dark": + percentUsed >= 70 && percentUsed < 90, + } + )} > - {percentUsed.toFixed(1)}% + {percentUsed > 70 ? ( + + ) : null} + {percentUsed < 1 ? percentUsed.toFixed(1) : Math.floor(percentUsed)}%
From e3413a2f0c6830a14af1c57477e78b1c57ca0d2d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 13:16:18 -0700 Subject: [PATCH 60/77] Move array caches to end --- src/application/components/MemoryInternals.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 7d485b537..469042572 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -259,9 +259,6 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { {selectedView === "chart" ? (
- {caches.queryManager.documentTransforms?.map(({ cache }, index) => ( - - ))} @@ -272,6 +269,14 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { cacheSize={caches.inMemoryCache.executeSubSelectedArray} /> + + + + + + {caches.queryManager.documentTransforms?.map(({ cache }, index) => ( + + ))} {caches.links.map((link, index) => ( ))} - - - - -
) : selectedView === "raw" ? ( Date: Fri, 20 Dec 2024 13:18:48 -0700 Subject: [PATCH 61/77] Use grid when on small screens --- src/application/components/MemoryInternals.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 469042572..28b670b41 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -257,7 +257,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) {
{selectedView === "chart" ? ( -
+
Date: Fri, 20 Dec 2024 14:55:59 -0700 Subject: [PATCH 62/77] Add more descriptions --- .../components/MemoryInternals.tsx | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 28b670b41..eb33da017 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -163,13 +163,57 @@ const descriptions: Record = {

), - "PersistedQueryLink.persistedQueryHashes": "", + "PersistedQueryLink.persistedQueryHashes": ( + <> +

+ A cache inside of + + PersistedQueryLink + + . +

+ +

+ It is called with transformed DocumentNodes. +

+ + ), "removeTypenameFromVariables.getVariableDefinitions": "", - "queryManager.getDocumentInfo": "", + "queryManager.getDocumentInfo": ( + <> +

+ A cache inside of{" "} + + QueryManager + + + . +

+

It is called with transformed `DocumentNode`s.

+ + ), "documentTransform.cache": "", "fragmentRegistry.lookup": "", "fragmentRegistry.findFragmentSpreads": "", - "fragmentRegistry.transform": "", + "fragmentRegistry.transform": ( + <> +

+ A cache inside of + + FragmentRegistry + + . +

+ +

+ Can be called with user-defined or already-transformed{" "} + DocumentNodes. +

+ + ), "cache.fragmentQueryDocuments": "", "inMemoryCache.executeSelectionSet": "", "inMemoryCache.executeSubSelectedArray": "", From 1ac7e97602d38c9ddfa31f060d985e5352456205 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:00:53 -0700 Subject: [PATCH 63/77] Move CacheSize component to own component file --- src/application/components/CacheSize.tsx | 171 ++++++++++++++++++ .../components/MemoryInternals.tsx | 167 +---------------- 2 files changed, 172 insertions(+), 166 deletions(-) create mode 100644 src/application/components/CacheSize.tsx diff --git a/src/application/components/CacheSize.tsx b/src/application/components/CacheSize.tsx new file mode 100644 index 000000000..4e9907bc6 --- /dev/null +++ b/src/application/components/CacheSize.tsx @@ -0,0 +1,171 @@ +import type { ReactNode } from "react"; +import IconOutlink from "@apollo/icons/small/IconOutlink.svg"; +import IconInfo from "@apollo/icons/default/IconInfo.svg"; +import IconWarning from "@apollo/icons/large/IconWarning.svg"; +import { ExternalLink } from "./ExternalLink"; +import { Tooltip } from "./Tooltip"; +import type { CacheSizes } from "@apollo/client/utilities"; +import type { CacheSize as CacheSizeType } from "../types/gql"; +import clsx from "clsx"; + +const DESCRIPTIONS: Record = { + print: ( + <> +

+ Cache size for the{" "} + + print + {" "} + function. +

+

+ It is called with transformed DocumentNodes. +

+

+ This method is called to transform a GraphQL query AST parsed by{" "} + gql back into a GraphQL string. +

+ + ), + parser: ( + <> +

+ Cache size for the{" "} + + parser + {" "} + function. +

+

+ It is called with user-provided DocumentNodes. +

+ + ), + canonicalStringify: ( +

+ Cache used by{" "} + + canonicalStringify + +

+ ), + "PersistedQueryLink.persistedQueryHashes": ( + <> +

+ A cache inside of + + PersistedQueryLink + + . +

+ +

+ It is called with transformed DocumentNodes. +

+ + ), + "removeTypenameFromVariables.getVariableDefinitions": "", + "queryManager.getDocumentInfo": ( + <> +

+ A cache inside of{" "} + + QueryManager + + + . +

+

It is called with transformed `DocumentNode`s.

+ + ), + "documentTransform.cache": "", + "fragmentRegistry.lookup": "", + "fragmentRegistry.findFragmentSpreads": "", + "fragmentRegistry.transform": ( + <> +

+ A cache inside of + + FragmentRegistry + + . +

+ +

+ Can be called with user-defined or already-transformed{" "} + DocumentNodes. +

+ + ), + "cache.fragmentQueryDocuments": "", + "inMemoryCache.executeSelectionSet": "", + "inMemoryCache.executeSubSelectedArray": "", + "inMemoryCache.maybeBroadcastWatch": "", +}; + +export function CacheSize({ cacheSize }: { cacheSize: CacheSizeType }) { + if (cacheSize.size === null || cacheSize.limit === null) { + return null; + } + + const description = DESCRIPTIONS[cacheSize.key as keyof CacheSizes]; + const percentUsed = (cacheSize.size / cacheSize.limit) * 100; + + return ( +
+

+ {cacheSize.key} + {description && ( + {description}

} + > + + + + + )} + +
+
+ + Size + + {cacheSize.size} +
+
+ + Limit + + {cacheSize.limit} +
+
= 90, + "text-warning dark:text-warning-dark": + percentUsed >= 70 && percentUsed < 90, + } + )} + > + {percentUsed > 70 ? ( + + ) : null} + {percentUsed < 1 ? percentUsed.toFixed(1) : Math.floor(percentUsed)}% +
+
+
+ ); +} diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index eb33da017..7d672469a 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -4,13 +4,10 @@ import IconOutlink from "@apollo/icons/default/IconOutlink.svg"; import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; -import IconInfo from "@apollo/icons/default/IconInfo.svg"; -import IconWarning from "@apollo/icons/large/IconWarning.svg"; import { FullWidthLayout } from "./Layouts/FullWidthLayout"; import { PageSpinner } from "./PageSpinner"; import type { - CacheSize, MemoryInternalsQuery, MemoryInternalsQueryVariables, } from "../types/gql"; @@ -21,8 +18,8 @@ import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; import type { CacheSizes } from "@apollo/client/utilities"; -import clsx from "clsx"; import { ExternalLink } from "./ExternalLink"; +import { CacheSize } from "./CacheSize"; interface MemoryInternalsProps { clientId: string | undefined; @@ -113,113 +110,6 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< } `; -const descriptions: Record = { - print: ( - <> -

- Cache size for the{" "} - - print - {" "} - function. -

-

- It is called with transformed DocumentNodes. -

-

- This method is called to transform a GraphQL query AST parsed by{" "} - gql back into a GraphQL string. -

- - ), - parser: ( - <> -

- Cache size for the{" "} - - parser - {" "} - function. -

-

- It is called with user-provided DocumentNodes. -

- - ), - canonicalStringify: ( -

- Cache used by{" "} - - canonicalStringify - -

- ), - "PersistedQueryLink.persistedQueryHashes": ( - <> -

- A cache inside of - - PersistedQueryLink - - . -

- -

- It is called with transformed DocumentNodes. -

- - ), - "removeTypenameFromVariables.getVariableDefinitions": "", - "queryManager.getDocumentInfo": ( - <> -

- A cache inside of{" "} - - QueryManager - - - . -

-

It is called with transformed `DocumentNode`s.

- - ), - "documentTransform.cache": "", - "fragmentRegistry.lookup": "", - "fragmentRegistry.findFragmentSpreads": "", - "fragmentRegistry.transform": ( - <> -

- A cache inside of - - FragmentRegistry - - . -

- -

- Can be called with user-defined or already-transformed{" "} - DocumentNodes. -

- - ), - "cache.fragmentQueryDocuments": "", - "inMemoryCache.executeSelectionSet": "", - "inMemoryCache.executeSubSelectedArray": "", - "inMemoryCache.maybeBroadcastWatch": "", -}; - export function MemoryInternals({ clientId }: MemoryInternalsProps) { const [selectedView, setSelectedView] = useState<"raw" | "chart">("chart"); @@ -372,58 +262,3 @@ function EmptyLayout({ children }: { children: ReactNode }) { ); } - -function CacheSize({ cacheSize }: { cacheSize: CacheSize }) { - if (cacheSize.size === null || cacheSize.limit === null) { - return null; - } - - const description = descriptions[cacheSize.key as keyof CacheSizes]; - const percentUsed = (cacheSize.size / cacheSize.limit) * 100; - - return ( -
-

- {cacheSize.key} - {description && ( - {description}

} - > - - - - - )} - -
-
- - Size - - {cacheSize.size} -
-
- - Limit - - {cacheSize.limit} -
-
= 90, - "text-warning dark:text-warning-dark": - percentUsed >= 70 && percentUsed < 90, - } - )} - > - {percentUsed > 70 ? ( - - ) : null} - {percentUsed < 1 ? percentUsed.toFixed(1) : Math.floor(percentUsed)}% -
-
-
- ); -} From 7f5c15ef116b345bdcd30374e9e090c6a9cbf416 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:03:31 -0700 Subject: [PATCH 64/77] Create TooltipLink to abstract common link props for the tooltip --- src/application/components/CacheSize.tsx | 58 ++++++++++++------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/application/components/CacheSize.tsx b/src/application/components/CacheSize.tsx index 4e9907bc6..6cd018af0 100644 --- a/src/application/components/CacheSize.tsx +++ b/src/application/components/CacheSize.tsx @@ -13,12 +13,9 @@ const DESCRIPTIONS: Record = { <>

Cache size for the{" "} - - print - {" "} + + print + {" "} function.

@@ -34,12 +31,9 @@ const DESCRIPTIONS: Record = { <>

Cache size for the{" "} - - parser - {" "} + + parser + {" "} function.

@@ -50,21 +44,18 @@ const DESCRIPTIONS: Record = { canonicalStringify: (

Cache used by{" "} - - canonicalStringify - + + canonicalStringify +

), "PersistedQueryLink.persistedQueryHashes": ( <>

A cache inside of - + PersistedQueryLink - + .

@@ -78,13 +69,9 @@ const DESCRIPTIONS: Record = { <>

A cache inside of{" "} - + QueryManager - - + .

It is called with transformed `DocumentNode`s.

@@ -97,9 +84,9 @@ const DESCRIPTIONS: Record = { <>

A cache inside of - + FragmentRegistry - + .

@@ -169,3 +156,18 @@ export function CacheSize({ cacheSize }: { cacheSize: CacheSizeType }) {
); } + +function TooltipLink({ + children, + href, +}: { + children: ReactNode; + href: string; +}) { + return ( + + {children} + + + ); +} From e7ccdc9c2c583edb1ac9862ae7e9c429756b6682 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:15:30 -0700 Subject: [PATCH 65/77] Add the remaining descriptions --- src/application/components/CacheSize.tsx | 134 +++++++++++++++++++++-- 1 file changed, 123 insertions(+), 11 deletions(-) diff --git a/src/application/components/CacheSize.tsx b/src/application/components/CacheSize.tsx index 6cd018af0..9b534c059 100644 --- a/src/application/components/CacheSize.tsx +++ b/src/application/components/CacheSize.tsx @@ -58,13 +58,25 @@ const DESCRIPTIONS: Record = { .

-

It is called with transformed DocumentNodes.

), - "removeTypenameFromVariables.getVariableDefinitions": "", + "removeTypenameFromVariables.getVariableDefinitions": ( + <> +

+ Cache used in + + removeTypenameFromVariables + + . +

+

+ This function is called transformed DocumentNodes. +

+ + ), "queryManager.getDocumentInfo": ( <>

@@ -74,12 +86,56 @@ const DESCRIPTIONS: Record = { .

-

It is called with transformed `DocumentNode`s.

+

+ It is called with transformed DocumentNodes. +

+ + ), + "documentTransform.cache": ( + <> +

+ Cache size for the cache of + + DocumentTransform + {" "} + instances with the cache option set to true. +

+

+ Can be called with user-defined or already-transformed{" "} + DocumentNodes. +

+ + ), + "fragmentRegistry.lookup": ( + <> +

+ A cache inside of + + FragmentRegistry + + . +

+

+ This function is called with fragment names in the form of a string. +

+ + ), + "fragmentRegistry.findFragmentSpreads": ( + <> +

+ Cache size for the findFragmentSpreads method of + + FragmentRegistry + + . +

+

+ This function is called with transformed DocumentNodes, as + well as recursively with every fragment spread referenced within that, + or a fragment referenced by a fragment spread. +

), - "documentTransform.cache": "", - "fragmentRegistry.lookup": "", - "fragmentRegistry.findFragmentSpreads": "", "fragmentRegistry.transform": ( <>

@@ -89,17 +145,73 @@ const DESCRIPTIONS: Record = { .

-

Can be called with user-defined or already-transformed{" "} DocumentNodes.

), - "cache.fragmentQueryDocuments": "", - "inMemoryCache.executeSelectionSet": "", - "inMemoryCache.executeSubSelectedArray": "", - "inMemoryCache.maybeBroadcastWatch": "", + "cache.fragmentQueryDocuments": ( + <> +

+ Cache size for the getFragmentDoc method of + + ApolloCache + + . +

+

This function is called with user-provided fragment definitions.

+ + ), + "inMemoryCache.executeSelectionSet": ( + <> +

+ Cache size for the executeSelectionSet method on{" "} + + StoreReader + + . +

+

+ Note: executeSelectionSet will be set to the{" "} + resultCacheMaxSize option and will fall back to this + configuration value if the option is not set. +

+ + ), + "inMemoryCache.executeSubSelectedArray": ( + <> +

+ Cache size for the executeSubSelectedArray method on{" "} + + StoreReader + + . +

+ +

+ Note: executeSubSelectedArray will be set to the{" "} + resultCacheMaxSize option and will fall back to this + configuration value if the option is not set. +

+ + ), + "inMemoryCache.maybeBroadcastWatch": ( + <> +

+ Cache size for the maybeBroadcastWatch method on{" "} + + InMemoryCache + + . +

+

+ Note: maybeBroadcastWatch will be set to the{" "} + resultCacheMaxSize option and will fall back to this + configuration value if the option is not set. +

+ + ), }; export function CacheSize({ cacheSize }: { cacheSize: CacheSizeType }) { From 6cddf8163d5919710bb404a5f8f2370584bb3fff Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:18:38 -0700 Subject: [PATCH 66/77] Remove unused imports --- src/application/components/MemoryInternals.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 7d672469a..2c7a79bd6 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -1,7 +1,6 @@ import type { TypedDocumentNode } from "@apollo/client"; import { gql, NetworkStatus, useQuery } from "@apollo/client"; import IconOutlink from "@apollo/icons/default/IconOutlink.svg"; -import IconOutlinkSm from "@apollo/icons/small/IconOutlink.svg"; import IconOperations from "@apollo/icons/default/IconOperations.svg"; import IconObserve from "@apollo/icons/default/IconObserve.svg"; @@ -17,8 +16,6 @@ import { ButtonGroup } from "./ButtonGroup"; import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; -import type { CacheSizes } from "@apollo/client/utilities"; -import { ExternalLink } from "./ExternalLink"; import { CacheSize } from "./CacheSize"; interface MemoryInternalsProps { From 2aae65d8b1145ca0430b605cde5e2e6e4aa2fe14 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:34:09 -0700 Subject: [PATCH 67/77] Show message when using older version of Apollo Client --- .../components/MemoryInternals.tsx | 38 ++++++++++++++++--- src/application/types/gql.ts | 1 + 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 2c7a79bd6..6a84f526d 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -17,6 +17,9 @@ import { Button } from "./Button"; import { Tooltip } from "./Tooltip"; import { JSONTreeViewer } from "./JSONTreeViewer"; import { CacheSize } from "./CacheSize"; +import { lt } from "semver"; +import { ExternalLink } from "./ExternalLink"; +import { PageError } from "./PageError"; interface MemoryInternalsProps { clientId: string | undefined; @@ -29,6 +32,7 @@ const MEMORY_INTERNALS_QUERY: TypedDocumentNode< query MemoryInternalsQuery($clientId: ID!) { client(id: $clientId) { id + version memoryInternals { raw caches { @@ -122,6 +126,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { const memoryInternals = data?.client?.memoryInternals; const caches = memoryInternals?.caches; + const version = data?.client?.version; if (networkStatus === NetworkStatus.loading) { return ( @@ -131,7 +136,32 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { ); } - // TODO: Show a message for clients older < 3.9 + if (version && lt(version, "3.9.0")) { + return ( + + + + Memory management not available + +

+ Memory management is available in Apollo Client{" "} + + 3.9.0 + + {" "} + or greater. Please upgrade your Apollo Client version to use + this feature. +

+
+
+
+
+ ); + } + if (!caches) { return ( @@ -241,15 +271,13 @@ function EmptyLayout({ children }: { children: ReactNode }) {

Learn how Apollo Client manages memory and how to set custom cache size limits in the{" "} - docs - + .

diff --git a/src/application/types/gql.ts b/src/application/types/gql.ts index c82f45925..f5561d2ca 100644 --- a/src/application/types/gql.ts +++ b/src/application/types/gql.ts @@ -262,6 +262,7 @@ export type MemoryInternalsQuery = { client: { __typename: "Client"; id: string; + version: string; memoryInternals: { __typename: "MemoryInternals"; raw: JSON | null; From f8233a71dbcb661251e40861128c7e1d81b97171 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:35:48 -0700 Subject: [PATCH 68/77] Don't show decimal for 0% --- src/application/components/CacheSize.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/application/components/CacheSize.tsx b/src/application/components/CacheSize.tsx index 9b534c059..a89190f7d 100644 --- a/src/application/components/CacheSize.tsx +++ b/src/application/components/CacheSize.tsx @@ -262,7 +262,10 @@ export function CacheSize({ cacheSize }: { cacheSize: CacheSizeType }) { {percentUsed > 70 ? ( ) : null} - {percentUsed < 1 ? percentUsed.toFixed(1) : Math.floor(percentUsed)}% + {percentUsed > 0 && percentUsed < 1 + ? percentUsed.toFixed(1) + : Math.floor(percentUsed)} + %
From 6d00546f760ec5c4f9a84fd3c645fd55a45cdd1d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:39:12 -0700 Subject: [PATCH 69/77] Remove unused deps --- package-lock.json | 309 +--------------------------------------------- package.json | 3 - 2 files changed, 2 insertions(+), 310 deletions(-) diff --git a/package-lock.json b/package-lock.json index f96dca742..0fa5703f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "framer-motion": "^11.0.3", "graphql": "^16.0.0", "graphql-tag": "^2.11.0", - "lodash.throttle": "^4.1.1", "polished": "^4.1.1", "prism-react-renderer": "^2.0.0", "react": "^18.2.0", @@ -41,7 +40,6 @@ "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", "react-syntax-highlighter": "^15.5.0", - "recharts": "^2.12.7", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-github": "^12.0.0", @@ -70,7 +68,6 @@ "@types/chrome": "0.0.283", "@types/eslint__js": "8.42.3", "@types/jest": "29.5.14", - "@types/lodash.throttle": "^4.1.9", "@types/react": "18.3.12", "@types/react-copy-to-clipboard": "5.0.7", "@types/react-dom": "18.3.1", @@ -7604,60 +7601,6 @@ "@types/har-format": "*" } }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==" - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -7851,15 +7794,6 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==" }, - "node_modules/@types/lodash.throttle": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.9.tgz", - "integrity": "sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -12235,116 +12169,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -12480,11 +12304,6 @@ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "dev": true }, - "node_modules/decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -12793,15 +12612,6 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -13921,11 +13731,6 @@ "node": ">=6" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -14084,14 +13889,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-equals": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -15924,14 +15721,6 @@ "node": ">= 0.4" } }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" - } - }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -19256,7 +19045,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash-es": { "version": "4.17.21", @@ -19293,11 +19083,6 @@ "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", "dev": true }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -23099,20 +22884,6 @@ "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/react-smooth": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", - "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", - "dependencies": { - "fast-equals": "^5.0.1", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -23150,21 +22921,6 @@ "react": ">= 0.14.0" } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -23270,41 +23026,6 @@ "node": ">= 12.13.0" } }, - "node_modules/recharts": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.0.tgz", - "integrity": "sha512-cIvMxDfpAmqAmVgc4yb7pgm/O1tmmkl/CjrvXuW+62/+7jj/iF9Ykm+hb/UJt42TREHMyd3gb+pkgoa2MxgDIw==", - "dependencies": { - "clsx": "^2.0.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.21", - "react-is": "^18.3.1", - "react-smooth": "^4.0.0", - "recharts-scale": "^0.4.4", - "tiny-invariant": "^1.3.1", - "victory-vendor": "^36.6.8" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", - "dependencies": { - "decimal.js-light": "^2.4.1" - } - }, - "node_modules/recharts/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -25390,11 +25111,6 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -26794,27 +26510,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/victory-vendor": { - "version": "36.9.2", - "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", - "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", - "dependencies": { - "@types/d3-array": "^3.0.3", - "@types/d3-ease": "^3.0.0", - "@types/d3-interpolate": "^3.0.1", - "@types/d3-scale": "^4.0.2", - "@types/d3-shape": "^3.1.0", - "@types/d3-time": "^3.0.0", - "@types/d3-timer": "^3.0.0", - "d3-array": "^3.1.6", - "d3-ease": "^3.0.1", - "d3-interpolate": "^3.0.1", - "d3-scale": "^4.0.2", - "d3-shape": "^3.1.0", - "d3-time": "^3.0.0", - "d3-timer": "^3.0.1" - } - }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index 68080871f..35ce6399f 100755 --- a/package.json +++ b/package.json @@ -53,7 +53,6 @@ "framer-motion": "^11.0.3", "graphql": "^16.0.0", "graphql-tag": "^2.11.0", - "lodash.throttle": "^4.1.1", "polished": "^4.1.1", "prism-react-renderer": "^2.0.0", "react": "^18.2.0", @@ -64,7 +63,6 @@ "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", "react-syntax-highlighter": "^15.5.0", - "recharts": "^2.12.7", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "remark-github": "^12.0.0", @@ -93,7 +91,6 @@ "@types/chrome": "0.0.283", "@types/eslint__js": "8.42.3", "@types/jest": "29.5.14", - "@types/lodash.throttle": "^4.1.9", "@types/react": "18.3.12", "@types/react-copy-to-clipboard": "5.0.7", "@types/react-dom": "18.3.1", From 887418dd710a9c75f6a32d32718e61d2e9c6c1a0 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:43:07 -0700 Subject: [PATCH 70/77] Add handler to vscode --- src/extension/vscode/client.ts | 4 ++++ src/extension/vscode/server.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/extension/vscode/client.ts b/src/extension/vscode/client.ts index deee8fe9d..2017709ae 100644 --- a/src/extension/vscode/client.ts +++ b/src/extension/vscode/client.ts @@ -110,8 +110,12 @@ function registerClient( function getMutationsForClient() { return getMutations(getClient()?.queryManager.mutationStore ?? {}); } + function getMemoryInternalsForClient() { + return getClient()?.getMemoryInternals?.(); + } wsRpcHandler("getQueries", getQueriesForClient, { signal }); wsRpcHandler("getMutations", getMutationsForClient, { signal }); + wsRpcHandler("getMemoryInternals", getMemoryInternalsForClient, { signal }); wsRpcHandler("getCache", () => getClient()?.cache.extract(true) ?? {}, { signal, }); diff --git a/src/extension/vscode/server.ts b/src/extension/vscode/server.ts index d31c16df8..113d7c31e 100644 --- a/src/extension/vscode/server.ts +++ b/src/extension/vscode/server.ts @@ -45,6 +45,10 @@ export function runServer( clients.get(id)!.rpcClient.request("getCache", id) ); + handleRpc("getMemoryInternals", (id) => + clients.get(id)!.rpcClient.request("getMemoryInternals", id) + ); + server.on("connection", function connection(ws) { let id: string | undefined; const wsAdapter = createSocketMessageAdapter(ws); From e251cb75b5ac970a56b2d08a616947ee4b5b6d69 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:45:01 -0700 Subject: [PATCH 71/77] Add changeset --- .changeset/forty-hats-tickle.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/forty-hats-tickle.md diff --git a/.changeset/forty-hats-tickle.md b/.changeset/forty-hats-tickle.md new file mode 100644 index 000000000..0d5b1422e --- /dev/null +++ b/.changeset/forty-hats-tickle.md @@ -0,0 +1,6 @@ +--- +"apollo-client-devtools": minor +"@apollo/client-devtools-vscode": minor +--- + +Add a memory panel to monitor internal Apollo Client caches. From 448cad1461c5a1227765c12bd6ecdbbe3e27b03a Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:47:37 -0700 Subject: [PATCH 72/77] Minor tweak to error description --- src/application/components/MemoryInternals.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index 6a84f526d..fbbba78cd 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -167,7 +167,7 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) {

Could not get memory internals for the client. This may be a result of - running your application in production mode as access to memory + running your application in production mode. Access to memory internals is disabled in production builds.

From 653944826dd0a1858fc53c3d936ec38e7d841c69 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:51:04 -0700 Subject: [PATCH 73/77] Use error message to show mesage for memory internals --- .../components/MemoryInternals.tsx | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/application/components/MemoryInternals.tsx b/src/application/components/MemoryInternals.tsx index fbbba78cd..15a2ee2ac 100644 --- a/src/application/components/MemoryInternals.tsx +++ b/src/application/components/MemoryInternals.tsx @@ -143,18 +143,16 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { Memory management not available -

- Memory management is available in Apollo Client{" "} - - 3.9.0 - - {" "} - or greater. Please upgrade your Apollo Client version to use - this feature. -

+ Memory management is available in Apollo Client{" "} + + 3.9.0 + + {" "} + or greater. Please upgrade your Apollo Client version to use this + feature.
@@ -165,11 +163,16 @@ export function MemoryInternals({ clientId }: MemoryInternalsProps) { if (!caches) { return ( -

- Could not get memory internals for the client. This may be a result of - running your application in production mode. Access to memory - internals is disabled in production builds. -

+ + + Unable to get memory internals + + Could not get memory internals for the client. This could be a + result of running your application in production mode since access + to memory internals is only available in development builds. + + +
); } From 0909c6374051b1fbfc16040393aafac39a246ae2 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:53:27 -0700 Subject: [PATCH 74/77] Remove unneeded forceMount --- src/application/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index db8be3031..3ebc23f76 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -278,7 +278,6 @@ export const App = () => { From f39547168569e3518c6c95cf9e2b2d69501e6b62 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:57:23 -0700 Subject: [PATCH 75/77] Remove unused utils and hooks --- src/application/hooks/useInterval.ts | 15 --------------- src/application/utilities/debounce.ts | 14 -------------- 2 files changed, 29 deletions(-) delete mode 100644 src/application/hooks/useInterval.ts delete mode 100644 src/application/utilities/debounce.ts diff --git a/src/application/hooks/useInterval.ts b/src/application/hooks/useInterval.ts deleted file mode 100644 index a2aa532e0..000000000 --- a/src/application/hooks/useInterval.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { useEffect, useLayoutEffect, useRef } from "react"; - -export function useInterval(callback: () => void, ms: number) { - const callbackRef = useRef(callback); - - useLayoutEffect(() => { - callbackRef.current = callback; - }); - - useEffect(() => { - const id = setInterval(() => callbackRef.current(), ms); - - return () => clearInterval(id); - }, [ms]); -} diff --git a/src/application/utilities/debounce.ts b/src/application/utilities/debounce.ts deleted file mode 100644 index 1264cee8c..000000000 --- a/src/application/utilities/debounce.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -export function debounce void>( - this: any, - ms: number, - fn: T -): T { - let timer: NodeJS.Timeout; - - return ((...args: any[]) => { - clearTimeout(timer); - - timer = setTimeout(() => fn.call(this, ...args), ms); - }) as T; -} From 439da033e1ec4664fbc7a1e31aa0d317c62d90be Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 20 Dec 2024 15:58:13 -0700 Subject: [PATCH 76/77] Inline the client --- src/extension/tab/hook.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/extension/tab/hook.ts b/src/extension/tab/hook.ts index 7b7a11861..7fc00ae52 100755 --- a/src/extension/tab/hook.ts +++ b/src/extension/tab/hook.ts @@ -132,9 +132,7 @@ handleRpc("getCache", (clientId) => { }); handleRpc("getMemoryInternals", (clientId) => { - const client = getClientById(clientId); - - return client?.getMemoryInternals?.(); + return getClientById(clientId)?.getMemoryInternals?.(); }); function getClientById(clientId: string) { From 49e1a6c03e7df6ce5c3671193d83d8b2d6965114 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sun, 5 Jan 2025 11:43:46 -0700 Subject: [PATCH 77/77] Better output when value is < 0.1 --- src/application/components/CacheSize.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/application/components/CacheSize.tsx b/src/application/components/CacheSize.tsx index a89190f7d..47a4176b6 100644 --- a/src/application/components/CacheSize.tsx +++ b/src/application/components/CacheSize.tsx @@ -263,7 +263,9 @@ export function CacheSize({ cacheSize }: { cacheSize: CacheSizeType }) { ) : null} {percentUsed > 0 && percentUsed < 1 - ? percentUsed.toFixed(1) + ? percentUsed.toFixed(1) === "0.0" + ? "<0.1" + : percentUsed.toFixed(1) : Math.floor(percentUsed)} %