Skip to content

Commit 6971df5

Browse files
authored
Merge pull request #302 from onflow/as/debounce
Debounce mutations and fix inconsistent updates
2 parents a3513b8 + fb13ea9 commit 6971df5

File tree

7 files changed

+134
-59
lines changed

7 files changed

+134
-59
lines changed

package-lock.json

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"apollo-cache-inmemory": "^1.6.6",
2828
"apollo-client": "^2.6.10",
2929
"apollo-link": "^1.2.14",
30+
"apollo-link-debounce": "^2.1.0",
3031
"apollo-link-http": "^1.5.17",
32+
"apollo-link-serialize": "^2.1.0",
3133
"detect-browser": "^5.1.1",
3234
"easymde": "^2.15.0",
3335
"file-saver": "^2.0.5",

src/api/apollo/client.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1+
import { InMemoryCache } from 'apollo-cache-inmemory';
12
import { ApolloClient } from 'apollo-client';
23
import { ApolloLink } from 'apollo-link';
3-
import { InMemoryCache } from 'apollo-cache-inmemory';
4+
import DebounceLink from 'apollo-link-debounce';
45
import { HttpLink } from 'apollo-link-http';
6+
import SerializingLink from 'apollo-link-serialize';
57
import fetch from 'isomorphic-fetch';
6-
import localResolvers from './resolvers';
7-
88
import { ResultType } from './generated/graphql';
9+
import localResolvers from './resolvers';
910

1011
const PLAYGROUND_API = process.env.PLAYGROUND_API;
12+
const DEFAULT_DEBOUNCE_TIMEOUT = 1200; // Debounce time in ms
1113

1214
const cache = new InMemoryCache();
1315

1416
const client = new ApolloClient({
1517
cache: cache,
1618
link: ApolloLink.from([
19+
new DebounceLink(DEFAULT_DEBOUNCE_TIMEOUT),
20+
new SerializingLink(),
1721
new HttpLink({
1822
uri: PLAYGROUND_API + '/query',
1923
credentials: 'include',

src/api/apollo/mutations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import gql from 'graphql-tag';
1+
import gql from 'graphql-tag'
22

33
export const CREATE_PROJECT = gql`
44
mutation CreateProject(

src/containers/Editor/components.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
} from 'providers/Project/projectDefault';
1717
import { Account, Project } from 'api/apollo/generated/graphql';
1818

19-
import debounce from 'util/debounce';
2019
import Mixpanel from 'util/mixpanel';
2120

2221
import { default as FlowButton } from 'components/Button';
@@ -249,7 +248,6 @@ const EditorContainer: React.FC<EditorContainerProps> = ({
249248
}
250249
}, [project]);
251250

252-
const onEditorChange = debounce(active.onChange);
253251
const updateProject = (
254252
title: string,
255253
description: string,
@@ -258,7 +256,7 @@ const EditorContainer: React.FC<EditorContainerProps> = ({
258256
project.title = title;
259257
project.description = description;
260258
project.readme = readme;
261-
onEditorChange(title, description, readme);
259+
active.onChange(title, description, readme)
262260
};
263261

264262
const isReadmeEditor = active.type === 4;

src/providers/Project/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@ export enum EntityType {
1818
export type ActiveEditor = {
1919
type: EntityType;
2020
index: number;
21-
onChange: (
22-
code: string,
23-
title: string,
24-
description: string,
25-
readme: string,
26-
) => void;
21+
// TODO: Type onChange functions for each EntityType
22+
onChange: any;
2723
};
2824

2925
export interface ProjectContextValue {

src/providers/Project/projectMutator.ts

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@ import { navigate } from '@reach/router';
22

33
import ApolloClient from 'apollo-client';
44

5+
import { Account, Project } from 'api/apollo/generated/graphql';
56
import {
67
CREATE_PROJECT,
7-
SAVE_PROJECT,
8-
SET_ACTIVE_PROJECT,
9-
UPDATE_ACCOUNT_DRAFT_CODE,
10-
UPDATE_ACCOUNT_DEPLOYED_CODE,
11-
UPDATE_TRANSACTION_TEMPLATE,
12-
CREATE_TRANSACTION_EXECUTION,
13-
CREATE_TRANSACTION_TEMPLATE,
148
CREATE_SCRIPT_EXECUTION,
15-
UPDATE_SCRIPT_TEMPLATE,
169
CREATE_SCRIPT_TEMPLATE,
10+
CREATE_TRANSACTION_EXECUTION,
11+
CREATE_TRANSACTION_TEMPLATE,
1712
DELETE_SCRIPT_TEMPLATE,
1813
DELETE_TRANSACTION_TEMPLATE,
14+
SAVE_PROJECT,
15+
SET_ACTIVE_PROJECT,
16+
UPDATE_ACCOUNT_DEPLOYED_CODE,
17+
UPDATE_ACCOUNT_DRAFT_CODE,
18+
UPDATE_SCRIPT_TEMPLATE,
19+
UPDATE_TRANSACTION_TEMPLATE,
1920
} from 'api/apollo/mutations';
20-
import { Project, Account } from 'api/apollo/generated/graphql';
2121
import { GET_LOCAL_PROJECT, GET_PROJECT } from 'api/apollo/queries';
2222

2323
import Mixpanel from 'util/mixpanel';
@@ -41,7 +41,7 @@ export default class ProjectMutator {
4141
isLocal: boolean,
4242
title: string,
4343
description: string,
44-
readme: string
44+
readme: string,
4545
) {
4646
this.client = client;
4747
this.projectId = projectId;
@@ -83,7 +83,6 @@ export default class ProjectMutator {
8383
scriptTemplates: scriptTemplates,
8484
},
8585
});
86-
8786

8887
const project = data.project;
8988

@@ -103,22 +102,43 @@ export default class ProjectMutator {
103102
return project;
104103
}
105104

106-
async saveProject(isFork: boolean, title: string, description: string, readme: string) {
105+
async saveProject(
106+
isFork: boolean,
107+
title: string,
108+
description: string,
109+
readme: string,
110+
) {
107111
if (this.isLocal) {
108112
await this.createProject();
109113
unregisterOnCloseSaveMessage();
110114
}
111115

116+
const key = ['SAVE_PROJECT', this.projectId];
117+
118+
this.client.writeData({
119+
id: `Project:${this.projectId}`,
120+
data: {
121+
title,
122+
description,
123+
readme,
124+
persist: true,
125+
},
126+
});
127+
112128
await this.client.mutate({
113129
mutation: SAVE_PROJECT,
114130
variables: {
115131
projectId: this.projectId,
116-
title: title,
117-
description: description,
118-
readme: readme
132+
title,
133+
description,
134+
readme,
135+
},
136+
context: {
137+
debounceKey: key,
138+
serializationKey: key,
119139
},
120140
});
121-
141+
122142
if (isFork) {
123143
Mixpanel.track('Project forked', { projectId: this.projectId });
124144
} else {
@@ -129,26 +149,33 @@ export default class ProjectMutator {
129149
}
130150

131151
async updateAccountDraftCode(account: Account, code: string) {
152+
this.client.writeData({
153+
id: `Account:${account.id}`,
154+
data: {
155+
__typename: 'Account',
156+
draftCode: code,
157+
},
158+
});
159+
132160
if (this.isLocal) {
133-
this.client.writeData({
134-
id: `Account:${account.id}`,
135-
data: {
136-
__typename: 'Account',
137-
draftCode: code,
138-
},
139-
});
140161
registerOnCloseSaveMessage();
141-
142162
return;
143163
}
144164

165+
const key = ['UPDATE_ACCOUNT_DRAFT_CODE', this.projectId, account.id];
166+
145167
await this.client.mutate({
146168
mutation: UPDATE_ACCOUNT_DRAFT_CODE,
147169
variables: {
148170
projectId: this.projectId,
149171
accountId: account.id,
150172
code,
151173
},
174+
context: {
175+
debounceKey: key,
176+
serializationKey: key,
177+
},
178+
fetchPolicy: 'no-cache',
152179
});
153180
}
154181

@@ -184,29 +211,34 @@ export default class ProjectMutator {
184211
script: string,
185212
title: string,
186213
) {
214+
this.client.writeData({
215+
id: `TransactionTemplate:${templateId}`,
216+
data: {
217+
script,
218+
title,
219+
},
220+
});
221+
187222
if (this.isLocal) {
188-
this.client.writeData({
189-
id: `TransactionTemplate:${templateId}`,
190-
data: {
191-
script: script,
192-
title: title,
193-
},
194-
});
195223
registerOnCloseSaveMessage();
196224
return;
197225
}
198226

227+
const key = ['UPDATE_TRANSACTION_TEMPLATE', this.projectId, templateId];
228+
199229
await this.client.mutate({
200230
mutation: UPDATE_TRANSACTION_TEMPLATE,
201231
variables: {
202232
projectId: this.projectId,
203233
templateId: templateId,
204-
script: script,
205-
title: title,
234+
script,
235+
title,
206236
},
207-
refetchQueries: [
208-
{ query: GET_PROJECT, variables: { projectId: this.projectId } },
209-
],
237+
context: {
238+
debounceKey: key,
239+
serializationKey: key,
240+
},
241+
fetchPolicy: 'no-cache',
210242
});
211243
}
212244

@@ -274,18 +306,21 @@ export default class ProjectMutator {
274306
script: string,
275307
title: string,
276308
) {
309+
this.client.writeData({
310+
id: `ScriptTemplate:${templateId}`,
311+
data: {
312+
script: script,
313+
title: title,
314+
},
315+
});
316+
277317
if (this.isLocal) {
278-
this.client.writeData({
279-
id: `ScriptTemplate:${templateId}`,
280-
data: {
281-
script: script,
282-
title: title,
283-
},
284-
});
285318
registerOnCloseSaveMessage();
286319
return;
287320
}
288321

322+
const key = ['UPDATE_SCRIPT_TEMPLATE', this.projectId, templateId];
323+
289324
await this.client.mutate({
290325
mutation: UPDATE_SCRIPT_TEMPLATE,
291326
variables: {
@@ -294,9 +329,11 @@ export default class ProjectMutator {
294329
script: script,
295330
title: title,
296331
},
297-
refetchQueries: [
298-
{ query: GET_PROJECT, variables: { projectId: this.projectId } },
299-
],
332+
context: {
333+
debounceKey: key,
334+
serializationKey: key,
335+
},
336+
fetchPolicy: 'no-cache',
300337
});
301338
}
302339

0 commit comments

Comments
 (0)