Skip to content

Commit 8ddf777

Browse files
authored
feat(devtools): history representation (#610)
* history in devtools * ignore build artefacts * cleanup * Change files * fix lint * add test * remove history from benchmark
1 parent 16bae33 commit 8ddf777

File tree

77 files changed

+5089
-3528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+5089
-3528
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Add exports and fix missing fields array to not contain empty entries.",
4+
"packageName": "@graphitation/apollo-forest-run",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "major",
3+
"comment": "History for operations. Dependency on ForestRun",
4+
"packageName": "@graphitation/rempl-apollo-devtools",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

examples/apollo-devtools-playground/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
build
33
apollo-devtools.js
44
apollo-devtools.js.map
5+
public/apollo-devtools-*

examples/apollo-devtools-playground/public/apollo-devtools-publisher.js

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

examples/apollo-devtools-playground/public/apollo-devtools-subscriber.js

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

examples/apollo-devtools-playground/src/components/app.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from "react";
22
import { ApolloProvider } from "@apollo/client";
33
import { buildClient } from "data/data-builder";
44
import ChatContainer from "./chat/chat-container";
5+
import { OptimisticUpdateDemo } from "./optimistic-update-demo";
56
import { FluentProvider, teamsLightTheme } from "@fluentui/react-components";
67

78
const client = buildClient();
@@ -20,6 +21,7 @@ const App = () => {
2021
return (
2122
<FluentProvider theme={teamsLightTheme}>
2223
<ApolloProvider client={client}>
24+
<OptimisticUpdateDemo />
2325
<ChatContainer />
2426
</ApolloProvider>
2527
</FluentProvider>

examples/apollo-devtools-playground/src/components/chat/chat-container.tsx

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
11
import * as React from "react";
2-
import { useQuery, gql, useMutation } from "@apollo/client";
2+
import { useQuery, gql, useMutation, useApolloClient } from "@apollo/client";
33
import { ChatRenderer } from "./chat-renderer";
44

55
const CHAT = gql`
6-
query Chat {
6+
query Chat($history: Int) @cache(history: $history) {
77
chat {
88
messages {
9+
text
10+
id
11+
}
12+
}
13+
}
14+
`;
15+
16+
const CHAT_MANUAL = gql`
17+
query ChatManul {
18+
chat {
19+
messages {
20+
text
921
id
1022
}
1123
}
1224
}
1325
`;
1426

1527
const ADD_MESSAGES = gql`
16-
mutation addMessage($message: String!) {
17-
addMessage(message: $message) {
28+
mutation addMessage($text: String!) {
29+
addMessage(text: $text) {
1830
id
19-
message
31+
text
2032
}
2133
}
2234
`;
@@ -27,15 +39,25 @@ const REMOVE_MESSAGE = gql`
2739
}
2840
`;
2941

42+
const SHUFFLE_MESSAGES = gql`
43+
mutation shuffleMessages {
44+
shuffleMessages
45+
}
46+
`;
47+
3048
const ChatContainer = () => {
31-
const { data, refetch } = useQuery(CHAT);
49+
const client = useApolloClient();
50+
const { data, refetch, ...rest } = useQuery(CHAT, {
51+
variables: { history: 15 },
52+
});
3253
const [addMessage] = useMutation(ADD_MESSAGES);
3354
const [removeMessage] = useMutation(REMOVE_MESSAGE);
55+
const [shuffleMessages] = useMutation(SHUFFLE_MESSAGES);
3456

3557
const addMessageFunction = React.useCallback(
36-
async (message: string) => {
58+
async (text: string) => {
3759
await addMessage({
38-
variables: { message },
60+
variables: { text },
3961
});
4062
refetch();
4163
},
@@ -52,12 +74,47 @@ const ChatContainer = () => {
5274
[removeMessage, refetch],
5375
);
5476

77+
const shuffleMessagesFunction = React.useCallback(async () => {
78+
await shuffleMessages();
79+
refetch();
80+
}, [shuffleMessages, refetch]);
81+
82+
// Manual cache write that only writes id (missing `text` field).
83+
// This will cause reads of CHAT to report a missing `text` field for the newly written items.
84+
const addIdOnlyMessageFunction = React.useCallback(() => {
85+
const id = String(Date.now());
86+
const existing = data?.chat?.messages ?? [];
87+
const newMsg = {
88+
id,
89+
__typename: "Message",
90+
// intentionally omit `text` to demonstrate a missing field when reading
91+
} as any;
92+
93+
client.writeQuery({
94+
query: CHAT_MANUAL,
95+
data: {
96+
chat: {
97+
__typename: "Chat",
98+
messages: [...existing, newMsg],
99+
},
100+
},
101+
});
102+
}, [client, data]);
103+
55104
return (
56105
<div>
106+
<button onClick={addIdOnlyMessageFunction}>
107+
Add Message with missing text field
108+
</button>
57109
<ChatRenderer
58-
ids={data?.chat?.messages?.map(({ id }: { id: string }) => id) || []}
110+
ids={
111+
data?.chat?.messages?.map(
112+
(message: { id: string } | null) => message?.id,
113+
) || []
114+
}
59115
removeMessage={removeMessageFunction}
60116
addMessage={addMessageFunction}
117+
shuffleMessages={shuffleMessagesFunction}
61118
/>
62119
</div>
63120
);

examples/apollo-devtools-playground/src/components/chat/chat-renderer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ interface IChatRenderer {
77
ids: string[];
88
removeMessage: (id: string) => void;
99
addMessage: (message: string) => void;
10+
shuffleMessages: () => void;
1011
}
1112

1213
export const ChatRenderer = ({
1314
ids,
1415
removeMessage,
1516
addMessage,
17+
shuffleMessages,
1618
}: IChatRenderer) => {
1719
const [messageText, setMessageText] = React.useState("");
1820
const styles = useChatRendererStyles();
@@ -32,6 +34,7 @@ export const ChatRenderer = ({
3234
}}
3335
/>
3436
<Button onClick={() => addMessage(messageText)}>Add Message</Button>
37+
<Button onClick={() => shuffleMessages()}>Shuffle Messages</Button>
3538
</div>
3639
<Messages ids={ids} removeMessage={removeMessage} />
3740
</>

examples/apollo-devtools-playground/src/components/chat/message.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ const MESSAGE = gql`
66
query message($id: ID) {
77
message(id: $id) {
88
id
9-
message
9+
text
1010
}
1111
}
1212
`;
1313

1414
const UPDATE_MESSAGE = gql`
15-
mutation updateMessage($id: ID!, $message: String!) {
16-
updateMessage(id: $id, message: $message) {
15+
mutation updateMessage($id: ID!, $text: String!) {
16+
updateMessage(id: $id, text: $text) {
1717
id
18-
message
18+
text
1919
}
2020
}
2121
`;
@@ -30,7 +30,7 @@ export default ({ id }: MessageProps) => {
3030
const [isEditing, setIsEditing] = React.useState(false);
3131
const [editValue, setEditValue] = React.useState("");
3232

33-
const messageText = data?.message?.message || "";
33+
const messageText = data?.message?.text || "";
3434

3535
React.useEffect(() => {
3636
setEditValue(messageText);
@@ -41,7 +41,7 @@ export default ({ id }: MessageProps) => {
4141
};
4242

4343
const handleSave = () => {
44-
updateMessage({ variables: { id, message: editValue } });
44+
updateMessage({ variables: { id, text: editValue } });
4545
setIsEditing(false);
4646
};
4747

0 commit comments

Comments
 (0)