diff --git a/package-lock.json b/package-lock.json index a16efc2d..ef3e54d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "flow-playground", "dependencies": { - "@apollo/react-hooks": "^3.1.3", + "@apollo/react-hooks": "^3.1.5", "@emotion/react": "^11.0.0", "@emotion/styled": "^11.10.4", "@onflow/cadence-language-server": "^0.26.1", diff --git a/package.json b/package.json index 3090f8de..516f0ba9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "ci:check": "npm run format:check:app && npm run lint && npm run types" }, "dependencies": { - "@apollo/react-hooks": "^3.1.3", + "@apollo/react-hooks": "^3.1.5", "@emotion/react": "^11.0.0", "@emotion/styled": "^11.10.4", "@onflow/cadence-language-server": "^0.26.1", diff --git a/src/api/apollo/mutations.ts b/src/api/apollo/mutations.ts index 94d2e4e9..dbc4ccee 100644 --- a/src/api/apollo/mutations.ts +++ b/src/api/apollo/mutations.ts @@ -24,15 +24,31 @@ export const CREATE_PROJECT = gql` } ) { id - parentId + persist mutable + parentId + seed + title + description + readme accounts { id address draftCode deployedCode + deployedContracts state } + transactionTemplates { + id + script + title + } + scriptTemplates { + id + script + title + } } } `; diff --git a/src/providers/Project/projectDefault.ts b/src/providers/Project/projectDefault.ts index d421f81f..1b500e18 100644 --- a/src/providers/Project/projectDefault.ts +++ b/src/providers/Project/projectDefault.ts @@ -1,8 +1,8 @@ import { - Project, Account, - TransactionTemplate, + Project, ScriptTemplate, + TransactionTemplate, } from 'api/apollo/generated/graphql'; import { strToSeed, uuid } from 'util/rng'; import { LOCAL_PROJECT_ID } from 'util/url'; @@ -110,6 +110,8 @@ const DEFAULT_ACCOUNT_5 = `access(all) contract HelloWorld { } `; +export const DEFAULT_ACCOUNT_STATE = '{}'; + const DEFAULT_ACCOUNTS = [ DEFAULT_ACCOUNT_1, DEFAULT_ACCOUNT_2, @@ -184,7 +186,7 @@ export function createLocalProject( draftCode: script, deployedCode: '', deployedContracts: [], - state: '{}', + state: DEFAULT_ACCOUNT_STATE, }; }); diff --git a/src/providers/Project/projectMutator.ts b/src/providers/Project/projectMutator.ts index e8e0f7de..9da674fc 100644 --- a/src/providers/Project/projectMutator.ts +++ b/src/providers/Project/projectMutator.ts @@ -25,6 +25,7 @@ import { registerOnCloseSaveMessage, unregisterOnCloseSaveMessage, } from 'util/onclose'; +import { DEFAULT_ACCOUNT_STATE } from './projectDefault'; // TODO: Switch to directives for serialization keys after upgrading to the newest Apollo/apollo-link-serialize export const PROJECT_SERIALIZATION_KEY = 'PROJECT_SERIALIZATION_KEY'; @@ -95,6 +96,15 @@ export default class ProjectMutator { this.projectId = project.id; this.isLocal = false; + // TODO: this writeQuery is required to avoid having the active GET_PROJECT hook refetch unnecessarily. Investigate further after switching to Apollo 3 + this.client.writeQuery({ + query: GET_PROJECT, + variables: { + projectId: project.id, + }, + data, + }); + await this.client.mutate({ mutation: SET_ACTIVE_PROJECT, variables: { @@ -186,7 +196,41 @@ export default class ProjectMutator { }); } + clearProjectAccountsOnReDeploy(accountId) { + const { project: cachedProject } = this.client.readQuery({ + query: GET_PROJECT, + variables: { + projectId: this.projectId, + }, + }); + + const newProject = { + ...cachedProject, + accounts: cachedProject.accounts.map((cachedAccount) => { + if (cachedAccount.id === accountId) return cachedAccount; + return { + ...cachedAccount, + deployedCode: '', + deployedContracts: [], + state: DEFAULT_ACCOUNT_STATE, + }; + }), + }; + + this.client.writeQuery({ + query: GET_PROJECT, + variables: { + projectId: this.projectId, + }, + data: { + project: newProject, + }, + }); + } + async updateAccountDeployedCode(account: Account, index: number) { + const hasDeployedCode = !!account.deployedCode?.length; + if (this.isLocal) { const project = await this.createProject(); account = project.accounts[index]; @@ -200,16 +244,13 @@ export default class ProjectMutator { accountId: account.id, code: account.draftCode, }, - // Redeploying code affects all accounts and requires a project refetch - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, }, }); + if (hasDeployedCode) this.clearProjectAccountsOnReDeploy(account.id); + Mixpanel.track('Contract deployed', { projectId: this.projectId, accountId: account.id, @@ -276,10 +317,6 @@ export default class ProjectMutator { arguments: args, script, }, - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, }, @@ -304,10 +341,6 @@ export default class ProjectMutator { script, title, }, - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, }, @@ -368,10 +401,6 @@ export default class ProjectMutator { projectId: this.projectId, templateId, }, - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, }, @@ -391,10 +420,6 @@ export default class ProjectMutator { projectId: this.projectId, templateId, }, - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, }, @@ -439,10 +464,6 @@ export default class ProjectMutator { script, title, }, - refetchQueries: [ - { query: GET_PROJECT, variables: { projectId: this.projectId } }, - ], - awaitRefetchQueries: true, context: { serializationKey: PROJECT_SERIALIZATION_KEY, },