diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000000..26106dcafd7
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "npm"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ # Disable @dependabot (except for security updates) because we use @renovate instead
+ open-pull-requests-limit: 0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57c659dd03f..95dbdd144c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## Apollo Client 3.4.8
+
+### Bug Fixes
+
+- Fix error thrown by nested `keyFields: ["a", ["b", "c"], "d"]` type policies when writing results into the cache where any of the key fields (`.a`, `.a.b`, `.a.c`, or `.d`) have been renamed by query field alias syntax.
+ [@benjamn](https://github.com/benjamn) in [#8643](https://github.com/apollographql/apollo-client/pull/8643)
+
+- Fix regression from PR [#8422](https://github.com/apollographql/apollo-client/pull/8422) (first released in `@apollo/client@3.4.0-rc.15`) that caused `result.data` to be set to undefined in some cases after `ObservableQuery#getCurrentResult` reads an incomplete result from the cache.
+ [@benjamn](https://github.com/benjamn) in [#8642](https://github.com/apollographql/apollo-client/pull/8642)
+
## Apollo Client 3.4.7
### Bug Fixes
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 878dc35b4cf..2225f9badfb 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -3718,9 +3718,9 @@
}
},
"@babel/register": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.14.5.tgz",
- "integrity": "sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.15.3.tgz",
+ "integrity": "sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==",
"requires": {
"clone-deep": "^4.0.1",
"find-cache-dir": "^2.0.0",
@@ -4688,9 +4688,9 @@
}
},
"tslib": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
- "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
@@ -4751,9 +4751,9 @@
}
},
"@oclif/plugin-help": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.2.2.tgz",
- "integrity": "sha512-SPZ8U8PBYK0n4srFjCLedk0jWU4QlxgEYLCXIBShJgOwPhTTQknkUlsEwaMIevvCU4iCQZhfMX+D8Pz5GZjFgA==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.2.3.tgz",
+ "integrity": "sha512-l2Pd0lbOMq4u/7xsl9hqISFqyR9gWEz/8+05xmrXFr67jXyS6EUCQB+mFBa0wepltrmJu0sAFg9AvA2mLaMMqQ==",
"requires": {
"@oclif/command": "^1.5.20",
"@oclif/config": "^1.15.1",
@@ -4901,11 +4901,11 @@
}
},
"@percy/config": {
- "version": "1.0.0-beta.62",
- "resolved": "https://registry.npmjs.org/@percy/config/-/config-1.0.0-beta.62.tgz",
- "integrity": "sha512-MhtjzNvjGvCv4n9pjXtIf0yKcuEOK592biaEtGAchfNJRC+kFpxQBF6wihR6AWN27uKa+8EXOuq62gqhpOJvIw==",
+ "version": "1.0.0-beta.65",
+ "resolved": "https://registry.npmjs.org/@percy/config/-/config-1.0.0-beta.65.tgz",
+ "integrity": "sha512-q6mkrBq+nmDtIDj793lNIodEYmc5wVE7ZwsQ2kNRQIAq4aiIIrD8L5CfhEOSYQ5OzhFq+qUjcZK5GptmheF0sw==",
"requires": {
- "@percy/logger": "1.0.0-beta.62",
+ "@percy/logger": "1.0.0-beta.65",
"ajv": "^8.6.2",
"cosmiconfig": "^7.0.0",
"yaml": "^1.10.0"
@@ -4942,9 +4942,9 @@
}
},
"@percy/logger": {
- "version": "1.0.0-beta.62",
- "resolved": "https://registry.npmjs.org/@percy/logger/-/logger-1.0.0-beta.62.tgz",
- "integrity": "sha512-ILdCq9S6Prok5hfoCxqthA7we/rAg7SttNZRTaFogewdPnpJ99KBAzVx9wQWGEbpIGjlQt2PHb+ymQ1yIXz56A=="
+ "version": "1.0.0-beta.65",
+ "resolved": "https://registry.npmjs.org/@percy/logger/-/logger-1.0.0-beta.65.tgz",
+ "integrity": "sha512-BJV0pjNlvcj4Y3nuMUGdb5RhjMduK40fRJJ9Lh/2qNk3pmnkGb9rH+GY+/0WY7quupNKxQjjyXcIP7I46/azNg=="
},
"@percy/migrate": {
"version": "0.10.0",
@@ -6558,9 +6558,9 @@
},
"dependencies": {
"tslib": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
- "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
@@ -11385,9 +11385,9 @@
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
},
"flow-parser": {
- "version": "0.156.0",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.156.0.tgz",
- "integrity": "sha512-OCE3oIixhOttaV4ahIGtxf9XfaDdxujiTnXuHu+0dvDVVDiSDJlQpgCWdDKqP0OHfFnxQKrjMamArDAXtrBtZw=="
+ "version": "0.157.0",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.157.0.tgz",
+ "integrity": "sha512-p0vdtrM8oAMlscIXpX0e/eGWll5NPteVChNtlQncbIbivH+BdiwXHN5QO6myAfmebd027r9RiQKdUPsFAiEVgQ=="
},
"flush-write-stream": {
"version": "1.1.1",
@@ -12240,9 +12240,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12259,9 +12259,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12278,9 +12278,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12296,9 +12296,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12368,9 +12368,9 @@
"integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g=="
},
"@babel/types": {
- "version": "7.14.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.9.tgz",
- "integrity": "sha512-u0bLTnv3DFHeaQLYzb7oRJ1JHr1sv/SYDM7JSqHFFLwXG1wTZRughxFI5NCP8qBEo1rVVsn7Yg2Lvw49nne/Ow==",
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz",
+ "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==",
"requires": {
"@babel/helper-validator-identifier": "^7.14.9",
"to-fast-properties": "^2.0.0"
@@ -12449,9 +12449,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12669,9 +12669,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12774,9 +12774,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12840,9 +12840,9 @@
}
},
"tslib": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
- "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"unist-util-visit": {
"version": "1.4.1",
@@ -12901,9 +12901,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -12955,9 +12955,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -13125,9 +13125,9 @@
}
},
"gatsby-theme-apollo-docs": {
- "version": "4.7.14",
- "resolved": "https://registry.npmjs.org/gatsby-theme-apollo-docs/-/gatsby-theme-apollo-docs-4.7.14.tgz",
- "integrity": "sha512-GB27mi4OMWsyL/9afdKfKeyuIDZkRO+o1MCl8ayElVVw7m2YKdX5QvmEBNKuJ5zBYjBSYJT2xVjsFUmwUb5c3Q==",
+ "version": "4.7.15",
+ "resolved": "https://registry.npmjs.org/gatsby-theme-apollo-docs/-/gatsby-theme-apollo-docs-4.7.15.tgz",
+ "integrity": "sha512-5W5mNnjc+r8C1bAxVtj88Q7yigWy2GkR3IhzCccfpZtVRunYsacggqbrc+U07QBlwzBnKDzsSoOX2msK9qrBlQ==",
"requires": {
"@jlengstorf/get-share-image": "^0.8.0",
"@mdx-js/mdx": "^1.1.0",
@@ -13189,9 +13189,9 @@
},
"dependencies": {
"@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
+ "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -15583,9 +15583,9 @@
},
"dependencies": {
"graceful-fs": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
},
"write-file-atomic": {
"version": "2.4.3",
@@ -16544,9 +16544,9 @@
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
},
"mermaid": {
- "version": "8.11.2",
- "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.11.2.tgz",
- "integrity": "sha512-a5aj6hmDfdPGmhB8so4VtwYZjhwGV0OvyQcRTrI3IrlWk5ZxYtEcS1GsIDJVwCX4bJMZbXYh9zbL+lArptCoSg==",
+ "version": "8.11.5",
+ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.11.5.tgz",
+ "integrity": "sha512-lbIaDQlFoIQLxnLy8hZgfS6L7gt2Wxlk83fudLslUEhj4yafHyVjzGOlojJQxgsLU5khEANhxLbo0xebtOrhXQ==",
"requires": {
"@braintree/sanitize-url": "^3.1.0",
"@percy/migrate": "^0.10.0",
@@ -18131,9 +18131,9 @@
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-to-regexp": {
"version": "0.1.7",
@@ -19851,9 +19851,9 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"tslib": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
- "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
@@ -21298,9 +21298,9 @@
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"simple-git": {
- "version": "2.42.0",
- "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.42.0.tgz",
- "integrity": "sha512-illpUX0bcrdB3AyvBGLz0ToRVP7lXNJOGVybGVuVk7PpivPNK5YKJx2aagKdKbveaMtt0DCLK4/jfjDb6b2M2g==",
+ "version": "2.44.0",
+ "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.44.0.tgz",
+ "integrity": "sha512-wIjcAmymhzgdaM0Y/a+XxmNGlivvHQTPZDYXVmyHMShVDwdeVqu3+OOyDbYu0DnfVzqLs2EOxRTgMNbC3YquwQ==",
"requires": {
"@kwsites/file-exists": "^1.1.1",
"@kwsites/promise-deferred": "^1.1.1",
diff --git a/docs/package.json b/docs/package.json
index ab4122410b6..2f425a55307 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -8,7 +8,7 @@
},
"dependencies": {
"gatsby": "2.32.13",
- "gatsby-theme-apollo-docs": "4.7.14",
+ "gatsby-theme-apollo-docs": "4.7.15",
"react": "17.0.2",
"react-dom": "17.0.1",
"webpack-virtual-modules": "0.4.3"
diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx
index 53f005165d1..26a6336de97 100644
--- a/docs/source/caching/advanced-topics.mdx
+++ b/docs/source/caching/advanced-topics.mdx
@@ -107,7 +107,6 @@ export class Foo extends Component {
export default withApollo(Foo);
```
-
## Refetching queries after a mutation
In certain cases, writing an `update` function to [update the cache after a mutation](../data/mutations/#updating-local-data) can be complex, or even impossible if the mutation doesn't return modified fields.
@@ -118,7 +117,68 @@ For details, see [Refetching queries](../data/mutations/#refetching-queries).
> Note that although `refetchQueries` can be faster to implement than an `update` function, it also requires additional network requests that are usually undesirable. For more information, see [this blog post](https://www.apollographql.com/blog/when-to-use-refetch-queries-in-apollo-client/).
-## Incremental loading: `fetchMore`
+## Cache redirects
+
+In some cases, a query requests data that already exists in the cache under a different reference. For example, your UI might have a list view and a detail view that both use the same data.
+
+The list view might run the following query:
+
+```graphql
+query Books {
+ books {
+ id
+ title
+ abstract
+ }
+}
+```
+
+When a specific book is selected, the detail view might display an individual item using this query:
+
+```graphql
+query Book($id: ID!) {
+ book(id: $id) {
+ id
+ title
+ abstract
+ }
+}
+```
+
+In a case like this, _we_ know that the second query's data might already be in the cache, but because that data was fetched by a different query, _Apollo Client_ doesn't know that. To tell Apollo Client where to look for the cached `Book` object, we can define a field policy `read` function for the `book` field:
+
+```js{9-14}
+import { ApolloClient, InMemoryCache } from '@apollo/client';
+
+const client = new ApolloClient({
+ cache: new InMemoryCache({
+ typePolicies: {
+ Query: {
+ fields: {
+ book {
+ read(_, { args, toReference }) {
+ return toReference({
+ __typename: 'Book',
+ id: args.id,
+ });
+ }
+ }
+ }
+ }
+ }
+ }
+});
+```
+
+This `read` function uses the `toReference` helper utility to generate and return a **cache reference** for a `Book` object, based on its `__typename` and `id`.
+
+Now whenever a query includes the `book` field, the `read` function above executes and returns a reference to a `Book` object. Apollo Client uses this reference to look up the object in its cache and return it if it's present. If it _isn't_ present, Apollo Client knows it needs to execute the query over the network.
+
+> ⚠️ **Note:** To avoid a network request, _all_ of a query's requested fields must already be present in the cache. If the detail view's query fetches _any_ `Book` field that the list view's query _didn't_, Apollo Client considers the cache hit to be incomplete, and it executes the full query over the network.
+
+## Pagination utilities
+
+### Incremental loading: `fetchMore`
`fetchMore` can be used to update the result of a query based on the data returned by another query. Most often, it is used to handle infinite-scroll pagination or other situations where you are loading more data when you already have some.
@@ -182,7 +242,7 @@ Here, the `fetchMore` query is the same as the query associated with the compone
Although `fetchMore` is often used for pagination, there are many other cases in which it is applicable. For example, suppose you have a list of items (say, a collaborative todo list) and you have a way to fetch items that have been updated after a certain time. Then, you don't have to refetch the whole todo list to get updates: you can just incorporate the newly added items with `fetchMore`, as long as your `updateQuery` function correctly merges the new results.
-## The `@connection` directive
+### The `@connection` directive
Fundamentally, paginated queries are the same as any other query with the exception that calls to `fetchMore` update the same cache key. Since these queries are cached by both the initial query and their parameters, a problem arises when later retrieving or updating paginated queries in the cache. We don’t care about pagination arguments such as limits, offsets, or cursors outside of the need to `fetchMore`, nor do we want to provide them simply for accessing cached data.
@@ -223,60 +283,3 @@ client.writeQuery({
```
Note that because we are only using the `type` argument in the store key, we don't have to provide `offset` or `limit`.
-
-## Cache redirects using field policy `read` functions
-
-> ⚠️ **Note:** Apollo Client >= 3.0 no longer supports the `ApolloClient` `cacheRedirects` constructor option. Equivalent `cacheRedirects` functionality can now be handled with field policy `read` functions, and is explained below.
-
-In some cases, a query requests data that already exists in the cache under a different reference. A very common example of this is when your UI has a list view and a detail view that both use the same data. The list view might run the following query:
-
-```graphql
-query Books {
- books {
- id
- title
- abstract
- }
-}
-```
-
-When a specific book is selected, the detail view displays an individual item using this query:
-
-```graphql
-query Book($id: ID!) {
- book(id: $id) {
- id
- title
- abstract
- }
-}
-```
-
-We know that the data is most likely already in the client cache, but because it was requested with a different query, Apollo Client doesn't know that. To tell Apollo Client where to look for the existing `book` data, we can define a field policy `read` function for the `book` field:
-
-```js
-import { ApolloClient, InMemoryCache } from '@apollo/client';
-
-const client = new ApolloClient({
- cache: new InMemoryCache({
- typePolicies: {
- Query: {
- fields: {
- book(_, { args, toReference }) {
- return toReference({
- __typename: 'Book',
- id: args.id,
- });
- }
- }
- }
- }
- }
-});
-```
-
-Now whenever a query includes the `book` field, the `read` function above executes and returns a reference that points to the book entity that was added to the cache when the `Books` list view query ran. Apollo Client uses the reference returned by the `read` function to look up the item in its cache.
-
-The `toReference` helper utility is passed into `read` functions as part of the second parameter options object. It's used to generate an entity reference based on its `__typename` and `id`.
-
-> ⚠️ **Note:** For the above to work properly, the data returned by the list query must include _all_ of the data that the specific detail query needs. If the specific detail query fetches a field that the list query doesn't return, Apollo Client considers the cache hit to be incomplete, and it attempts to fetch the full data set over the network (if network requests are enabled).
diff --git a/docs/source/local-state/client-side-schema.mdx b/docs/source/local-state/client-side-schema.mdx
index a92d8c41ac2..4b26789d8cc 100644
--- a/docs/source/local-state/client-side-schema.mdx
+++ b/docs/source/local-state/client-side-schema.mdx
@@ -1,11 +1,17 @@
---
title: Client-side schema
-description: Configure a client-side schema with Apollo Client
+description: Extend your schema with client-specific fields
---
-You can optionally set a client-side schema to be used with Apollo Client, through the `ApolloClient` constructor `typeDefs` parameter. Your schema should be written in [Schema Definition Language](https://www.apollographql.com/docs/graphql-tools/generate-schema#schema-language). This schema is not used for validation like it is on the server because the `graphql-js` modules for schema validation would dramatically increase your bundle size. Instead, your client-side schema is used for introspection in [Apollo Client Devtools](https://github.com/apollographql/apollo-client-devtools), where you can explore your schema in GraphiQL.
+You can optionally provide a **client-side schema** to Apollo Client that defines [local-only types and fields](./managing-state-with-field-policies/). You can define completely new types, or extend types from your server's schema with new fields.
-The following demonstrates how to configure a client-side schema through the `ApolloClient` constructor:
+As with any GraphQL schema, your client-side schema must be written in [Schema Definition Language](https://www.apollographql.com/docs/apollo-server/schema/schema/#the-schema-definition-language).
+
+The client-side schema is _not_ used to validate operations like it is on the server (the `graphql-js` modules for schema validation would dramatically increase your bundle size). Instead, your client-side schema is used for introspection in the [Apollo Client Devtools](../development-testing/developer-tooling/#apollo-client-devtools), where you can explore your schema in GraphiQL.
+
+## Setup
+
+The following demonstrates how to define a client-side schema and provide it to the `ApolloClient` constructor:
```js
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
@@ -32,6 +38,6 @@ const client = new ApolloClient({
});
```
-If you open up Apollo Client Devtools and click on the `GraphiQL` tab, you'll be able to explore your client schema in the "Docs" section. This example doesn't include a remote schema, but if it did, you would be able to see your local queries and mutations alongside your remote ones.
+If you open up the [Apollo Client Devtools](../development-testing/developer-tooling/#apollo-client-devtools) and click on the `GraphiQL` tab, you'll be able to explore your client schema in the "Docs" section. This example doesn't include a remote schema, but if it did, you would be able to see your local queries and mutations alongside your remote ones.
-![GraphiQL Console](../assets/client-schema.png)
+
diff --git a/docs/source/performance/performance.mdx b/docs/source/performance/performance.mdx
index 1fee97e37df..0f812291774 100644
--- a/docs/source/performance/performance.mdx
+++ b/docs/source/performance/performance.mdx
@@ -1,18 +1,29 @@
---
-title: Improving performance
+title: Improving performance in Apollo Client
+sidebar_title: Improving performance
---
+import {
+ ExpansionPanel,
+} from 'gatsby-theme-apollo-docs/src/components/expansion-panel';
+
## Redirecting to cached data
-In some cases, a query requests data that already exists in the client cache under a different reference. A very common example of this is when your UI has a list view and a detail view that both use the same data. To avoid re-requesting data that already exists in the cache, see [Cache redirects using field policy `read` functions](../caching/advanced-topics#cache-redirects-using-field-policy-read-functions).
+In some cases, a query might request data that's already present in the Apollo Client cache thanks to a _different_ query that already ran. For example, your UI might have both a list view and a detail view with queries that fetch the same fields from a particular object.
+
+In cases like these, you can avoid sending your server a followup query that fetches identical data. To learn how, see [Cache redirects](../caching/advanced-topics#cache-redirects).
## Prefetching data
-Prefetching is one of the easiest ways to make your application's UI feel a lot faster with Apollo Client. Prefetching simply means loading data into the cache before it needs to be rendered on the screen. Essentially, we want to load all data required for a view as soon as we can guess that a user will navigate to it.
+Prefetching involves executing queries for data _before_ that data needs to be rendered. It helps your application's UI feel more responsive to the user.
+
+Most of the time, prefetching involves querying for data as soon as you can guess that a user will _probably_ need it.
-We can accomplish this in only a few lines of code by calling `client.query` whenever the user hovers over a link.
+For example, this code snippet calls `client.query` to execute a query when the user hovers over a particular link (to a page that uses the data returned by the query):
-```jsx
+
+
+```jsx{19-24}
function Feed() {
const { loading, error, data, client } = useQuery(GET_DOGS);
@@ -55,12 +66,16 @@ function Feed() {
}
```
-All we have to do is access the client in the render prop function and call `client.query` when the user hovers over the link. Once the user clicks on the link, the data will already be available in the Apollo cache, so the user won't see a loading state.
+
+
+When the `GET_DOG` query completes, its result is stored in the Apollo Client cache. This means that if the user then clicks the link, the dog's detail page can immediately populate that data from the cache, which feels instantaneous to the user.
+
+In addition to a mouse hover, here are some other suggestions for situations when prefetching can be helpful:
-There are a lot of different ways to anticipate that the user will end up needing some data in the UI. In addition to using the hover state, here are some other places you can preload data:
+* During a multi-step flow (such as a wizard), you can preload each _next_ step's data during each _current_ step.
+* If your app's analytics indicate a frequent transition between two particular views, you can use prefetching to optimize for that path.
+* If a region of a page has multiple tabs or slides (such as a carousel), you can preload data for some or all of them to make transitions feel snappier.
-1. The next step of a multi-step wizard immediately
-2. The route of a call-to-action button
-3. All of the data for a sub-area of the application, to make navigating within that area instant
+A special form of prefetching is [store hydration from the server](./server-side-rendering/#rehydrating-the-client-side-cache), so you might also consider hydrating more data than is actually needed for the first page load to make other interactions faster.
-If you have some other ideas, please send a PR to this article, and maybe add some more code snippets. A special form of prefetching is [store hydration from the server](server-side-rendering/#rehydrating-the-client-side-cache), so you might also consider hydrating more data than is actually needed for the first page load to make other interactions faster.
+Feel free to submit a PR with suggestions for other preloading opportunities!
diff --git a/examples/bundling/no-tree-shaking/rollup-ac2/package-lock.json b/examples/bundling/no-tree-shaking/rollup-ac2/package-lock.json
index 83ad4fcd044..443fa039eb4 100644
--- a/examples/bundling/no-tree-shaking/rollup-ac2/package-lock.json
+++ b/examples/bundling/no-tree-shaking/rollup-ac2/package-lock.json
@@ -985,9 +985,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
diff --git a/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json b/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json
index 3af1658ca72..09a2b91c749 100644
--- a/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json
+++ b/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json
@@ -4913,11 +4913,6 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
},
- "path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
- },
"path-to-regexp": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
@@ -5323,10 +5318,7 @@
"resolve": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
- "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
- "requires": {
- "path-parse": "^1.0.6"
- }
+ "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w=="
},
"resolve-cwd": {
"version": "2.0.0",
@@ -6744,12 +6736,12 @@
"dev": true
},
"ajv": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz",
- "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==",
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
- "fast-deep-equal": "^2.0.1",
+ "fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
@@ -6864,29 +6856,52 @@
"dev": true
},
"clipboardy": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz",
- "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
+ "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
"dev": true,
"requires": {
- "arch": "^2.1.0",
- "execa": "^0.8.0"
+ "arch": "^2.1.1",
+ "execa": "^1.0.0",
+ "is-wsl": "^2.1.1"
},
"dependencies": {
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
"execa": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
- "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
- "cross-spawn": "^5.0.1",
- "get-stream": "^3.0.0",
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
}
}
},
@@ -6981,6 +6996,15 @@
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
},
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -7015,9 +7039,9 @@
}
},
"fast-deep-equal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
- "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
@@ -7102,6 +7126,12 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true
+ },
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
@@ -7137,6 +7167,15 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -7215,18 +7254,18 @@
"dev": true
},
"mime-db": {
- "version": "1.47.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
- "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
+ "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==",
"dev": true
},
"mime-types": {
- "version": "2.1.30",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
- "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
+ "version": "2.1.32",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
+ "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==",
"dev": true,
"requires": {
- "mime-db": "1.47.0"
+ "mime-db": "1.49.0"
}
},
"minimatch": {
@@ -7256,6 +7295,12 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
"dev": true
},
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -7305,9 +7350,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
@@ -7322,6 +7367,16 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"dev": true
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -7578,6 +7633,12 @@
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
"serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
@@ -7588,17 +7649,17 @@
}
},
"serve": {
- "version": "11.3.2",
- "resolved": "https://registry.npmjs.org/serve/-/serve-11.3.2.tgz",
- "integrity": "sha512-yKWQfI3xbj/f7X1lTBg91fXBP0FqjJ4TEi+ilES5yzH0iKJpN5LjNb1YzIfQg9Rqn4ECUS2SOf2+Kmepogoa5w==",
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/serve/-/serve-12.0.0.tgz",
+ "integrity": "sha512-BkTsETQYynAZ7rXX414kg4X6EvuZQS3UVs1NY0VQYdRHSTYWPYcH38nnDh48D0x6ONuislgjag8uKlU2gTBImA==",
"dev": true,
"requires": {
"@zeit/schemas": "2.6.0",
- "ajv": "6.5.3",
+ "ajv": "6.12.6",
"arg": "2.0.0",
"boxen": "1.3.0",
"chalk": "2.4.1",
- "clipboardy": "1.2.3",
+ "clipboardy": "2.3.0",
"compression": "1.7.3",
"serve-handler": "6.1.3",
"update-check": "1.5.2"
diff --git a/examples/bundling/tree-shaking/rollup-ac2/package-lock.json b/examples/bundling/tree-shaking/rollup-ac2/package-lock.json
index 7b53b8d1bd4..5cf62687a14 100644
--- a/examples/bundling/tree-shaking/rollup-ac2/package-lock.json
+++ b/examples/bundling/tree-shaking/rollup-ac2/package-lock.json
@@ -1135,9 +1135,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
diff --git a/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json b/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json
index aff0a49851a..b198136dd21 100644
--- a/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json
+++ b/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json
@@ -1064,9 +1064,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
diff --git a/examples/bundling/tree-shaking/rollup-ac3/package-lock.json b/examples/bundling/tree-shaking/rollup-ac3/package-lock.json
index 59f868c1781..4dbeaeacc7d 100644
--- a/examples/bundling/tree-shaking/rollup-ac3/package-lock.json
+++ b/examples/bundling/tree-shaking/rollup-ac3/package-lock.json
@@ -1209,9 +1209,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
diff --git a/package-lock.json b/package-lock.json
index f49abe92a72..95cdf61d13e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,8 +23,8 @@
"zen-observable-ts": "^1.1.0"
},
"devDependencies": {
- "@babel/parser": "7.15.2",
- "@graphql-tools/schema": "8.0.3",
+ "@babel/parser": "7.15.3",
+ "@graphql-tools/schema": "8.1.0",
"@rollup/plugin-node-resolve": "11.2.1",
"@testing-library/react": "9.5.0",
"@testing-library/react-hooks": "7.0.1",
@@ -34,8 +34,8 @@
"@types/hoist-non-react-statics": "3.3.1",
"@types/jest": "26.0.24",
"@types/lodash": "4.14.172",
- "@types/node": "16.4.13",
- "@types/react": "17.0.16",
+ "@types/node": "16.6.1",
+ "@types/react": "17.0.18",
"@types/react-dom": "17.0.2",
"@types/recompose": "0.30.8",
"bundlesize": "0.18.1",
@@ -385,9 +385,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.15.2",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.2.tgz",
- "integrity": "sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz",
+ "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -774,13 +774,12 @@
}
},
"node_modules/@graphql-tools/merge": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-7.0.0.tgz",
- "integrity": "sha512-u7TTwKQ7cybAkn6snYPRg3um/C2u690wlD8TgHITAmGQDAExN/yipSSBgu4rXWopsPLsY0G30mJ8tOWToZVE1w==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.0.0.tgz",
+ "integrity": "sha512-Hdhp3qwDeRwPGUVUkmRwTg5KX/bp1MNkplhI6szgQHeDPaC2l9a1iS6LznVP6xQjsyb8oRPqlVPKfiXemodwFw==",
"dev": true,
"dependencies": {
- "@graphql-tools/schema": "^8.0.3",
- "@graphql-tools/utils": "8.0.2",
+ "@graphql-tools/utils": "8.1.0",
"tslib": "~2.3.0"
},
"peerDependencies": {
@@ -788,13 +787,13 @@
}
},
"node_modules/@graphql-tools/schema": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.0.3.tgz",
- "integrity": "sha512-ufJH7r/RcetVPd3kKCZ16/JTRkOX8aB1yGbYnUjqWEIdYEZc3Fpg7AVlcliu2JlvwR+WSNlgWn2QK76QCsFFdA==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.1.0.tgz",
+ "integrity": "sha512-k6M877jFTKjlRU2f2YYjWx+FKXlhuQlCQQ8IdG5API4UL1qk57zYoNnYlT+CJfWxEfcMvEd6AlJ8wvmapzr53A==",
"dev": true,
"dependencies": {
- "@graphql-tools/merge": "7.0.0",
- "@graphql-tools/utils": "8.0.2",
+ "@graphql-tools/merge": "8.0.0",
+ "@graphql-tools/utils": "8.1.0",
"tslib": "~2.3.0",
"value-or-promise": "1.0.10"
},
@@ -803,9 +802,9 @@
}
},
"node_modules/@graphql-tools/utils": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.0.2.tgz",
- "integrity": "sha512-gzkavMOgbhnwkHJYg32Adv6f+LxjbQmmbdD5Hty0+CWxvaiuJq+nU6tzb/7VSU4cwhbNLx/lGu2jbCPEW1McZQ==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.1.0.tgz",
+ "integrity": "sha512-V5a7xAxZ6DHzrYYticmsLgWim+vGnC6ztbiOXrO5cGtOOk5NSK657SZXsyVOR7hNvdWiHSW0dlBZb6zkkfOnHA==",
"dev": true,
"dependencies": {
"tslib": "~2.3.0"
@@ -2298,9 +2297,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "16.4.13",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz",
- "integrity": "sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==",
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
+ "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true
},
"node_modules/@types/normalize-package-data": {
@@ -2322,9 +2321,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "17.0.16",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.16.tgz",
- "integrity": "sha512-3kCUiOOlQTwUUvjNFkbBTWMTxdTGybz/PfjCw9JmaRGcEDBQh+nGMg7/E9P2rklhJuYVd25IYLNcvqgSPCPksg==",
+ "version": "17.0.18",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz",
+ "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@@ -9391,9 +9390,9 @@
}
},
"node_modules/path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"node_modules/path-to-regexp": {
@@ -12344,9 +12343,9 @@
}
},
"@babel/parser": {
- "version": "7.15.2",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.2.tgz",
- "integrity": "sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg==",
+ "version": "7.15.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz",
+ "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -12658,32 +12657,31 @@
}
},
"@graphql-tools/merge": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-7.0.0.tgz",
- "integrity": "sha512-u7TTwKQ7cybAkn6snYPRg3um/C2u690wlD8TgHITAmGQDAExN/yipSSBgu4rXWopsPLsY0G30mJ8tOWToZVE1w==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.0.0.tgz",
+ "integrity": "sha512-Hdhp3qwDeRwPGUVUkmRwTg5KX/bp1MNkplhI6szgQHeDPaC2l9a1iS6LznVP6xQjsyb8oRPqlVPKfiXemodwFw==",
"dev": true,
"requires": {
- "@graphql-tools/schema": "^8.0.3",
- "@graphql-tools/utils": "8.0.2",
+ "@graphql-tools/utils": "8.1.0",
"tslib": "~2.3.0"
}
},
"@graphql-tools/schema": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.0.3.tgz",
- "integrity": "sha512-ufJH7r/RcetVPd3kKCZ16/JTRkOX8aB1yGbYnUjqWEIdYEZc3Fpg7AVlcliu2JlvwR+WSNlgWn2QK76QCsFFdA==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.1.0.tgz",
+ "integrity": "sha512-k6M877jFTKjlRU2f2YYjWx+FKXlhuQlCQQ8IdG5API4UL1qk57zYoNnYlT+CJfWxEfcMvEd6AlJ8wvmapzr53A==",
"dev": true,
"requires": {
- "@graphql-tools/merge": "7.0.0",
- "@graphql-tools/utils": "8.0.2",
+ "@graphql-tools/merge": "8.0.0",
+ "@graphql-tools/utils": "8.1.0",
"tslib": "~2.3.0",
"value-or-promise": "1.0.10"
}
},
"@graphql-tools/utils": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.0.2.tgz",
- "integrity": "sha512-gzkavMOgbhnwkHJYg32Adv6f+LxjbQmmbdD5Hty0+CWxvaiuJq+nU6tzb/7VSU4cwhbNLx/lGu2jbCPEW1McZQ==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.1.0.tgz",
+ "integrity": "sha512-V5a7xAxZ6DHzrYYticmsLgWim+vGnC6ztbiOXrO5cGtOOk5NSK657SZXsyVOR7hNvdWiHSW0dlBZb6zkkfOnHA==",
"dev": true,
"requires": {
"tslib": "~2.3.0"
@@ -13914,9 +13912,9 @@
"dev": true
},
"@types/node": {
- "version": "16.4.13",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz",
- "integrity": "sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==",
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
+ "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true
},
"@types/normalize-package-data": {
@@ -13938,9 +13936,9 @@
"dev": true
},
"@types/react": {
- "version": "17.0.16",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.16.tgz",
- "integrity": "sha512-3kCUiOOlQTwUUvjNFkbBTWMTxdTGybz/PfjCw9JmaRGcEDBQh+nGMg7/E9P2rklhJuYVd25IYLNcvqgSPCPksg==",
+ "version": "17.0.18",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz",
+ "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@@ -19565,9 +19563,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
diff --git a/package.json b/package.json
index 6c2855e7a23..52a79df2f96 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,7 @@
{
"name": "apollo-client",
"path": "./temp/bundlesize.min.cjs",
- "maxSize": "24.6 kB"
+ "maxSize": "24.7 kB"
}
],
"engines": {
@@ -89,8 +89,8 @@
"zen-observable-ts": "^1.1.0"
},
"devDependencies": {
- "@babel/parser": "7.15.2",
- "@graphql-tools/schema": "8.0.3",
+ "@babel/parser": "7.15.3",
+ "@graphql-tools/schema": "8.1.0",
"@rollup/plugin-node-resolve": "11.2.1",
"@testing-library/react": "9.5.0",
"@testing-library/react-hooks": "7.0.1",
@@ -100,8 +100,8 @@
"@types/hoist-non-react-statics": "3.3.1",
"@types/jest": "26.0.24",
"@types/lodash": "4.14.172",
- "@types/node": "16.4.13",
- "@types/react": "17.0.16",
+ "@types/node": "16.6.1",
+ "@types/react": "17.0.18",
"@types/react-dom": "17.0.2",
"@types/recompose": "0.30.8",
"bundlesize": "0.18.1",
diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts
index 1aad0f8b987..1e73b8225e9 100644
--- a/src/__tests__/client.ts
+++ b/src/__tests__/client.ts
@@ -2590,15 +2590,16 @@ describe('client', () => {
subscription.unsubscribe();
const lastError = observable.getLastError();
- const lastResult = observable.getLastResult();
+ expect(lastError).toBeInstanceOf(ApolloError);
+ expect(lastError!.networkError).toEqual(error);
+ const lastResult = observable.getLastResult();
expect(lastResult).toBeTruthy();
expect(lastResult!.loading).toBe(false);
expect(lastResult!.networkStatus).toBe(8);
observable.resetLastResults();
subscription = observable.subscribe(observerOptions);
- Object.assign(observable, { lastError, lastResult });
// The error arrived, run a refetch to get the third result
// which should now contain valid data.
diff --git a/src/cache/inmemory/__tests__/policies.ts b/src/cache/inmemory/__tests__/policies.ts
index 6ba256d2d7e..dc1db912e90 100644
--- a/src/cache/inmemory/__tests__/policies.ts
+++ b/src/cache/inmemory/__tests__/policies.ts
@@ -129,6 +129,63 @@ describe("type policies", function () {
checkAuthorName(cache);
});
+ it("can specify nested keyFields with alias", function () {
+ const cache = new InMemoryCache({
+ typePolicies: {
+ Book: {
+ keyFields: ["title", "author", ["name"]],
+ },
+ },
+ });
+
+ const aliasQuery = gql`
+ query {
+ book {
+ title
+ writer: author {
+ alias: name
+ }
+ }
+ }
+ `;
+
+ const { author, ...rest } = theInformationBookData;
+ const aliasBookData = {
+ ...rest,
+ writer: {
+ alias: author.name,
+ },
+ };
+
+ cache.writeQuery({
+ query: aliasQuery,
+ data: {
+ book: aliasBookData,
+ },
+ });
+
+ expect(cache.extract(true)).toEqual({
+ ROOT_QUERY: {
+ __typename: "Query",
+ book: {
+ __ref: 'Book:{"title":"The Information","author":{"name":"James Gleick"}}',
+ },
+ },
+ 'Book:{"title":"The Information","author":{"name":"James Gleick"}}': {
+ __typename: "Book",
+ title: "The Information",
+ // Note that "author" and "name" are stored internally, since they are
+ // the true names of their fields (according to the schema), despite the
+ // writer:author and alias:name aliases.
+ author: {
+ name: "James Gleick"
+ },
+ },
+ });
+
+ checkAuthorName(cache);
+ });
+
it("keeps keyFields in specified order", function () {
const cache = new InMemoryCache({
typePolicies: {
diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts
index 0f09e0a7a9d..399f7c2fbe5 100644
--- a/src/cache/inmemory/policies.ts
+++ b/src/cache/inmemory/policies.ts
@@ -1067,22 +1067,30 @@ function computeKeyObject(
// so we are careful to build keyObj in the order of keys given in
// specifier.
const keyObj = Object.create(null);
- let prevKey: string | undefined;
+
+ // The lastResponseKey variable tracks keys as seen in actual GraphQL response
+ // objects, potentially affected by aliasing. The lastActualKey variable
+ // tracks the corresponding key after removing aliases.
+ let lastResponseKey: string | undefined;
+ let lastActualKey: string | undefined;
+
specifier.forEach(s => {
if (Array.isArray(s)) {
- if (typeof prevKey === "string") {
+ if (typeof lastActualKey === "string" &&
+ typeof lastResponseKey === "string") {
const subsets = aliasMap && aliasMap.subsets;
- const subset = subsets && subsets[prevKey];
- keyObj[prevKey] = computeKeyObject(response[prevKey], s, strict, subset);
+ const subset = subsets && subsets[lastActualKey];
+ keyObj[lastActualKey] =
+ computeKeyObject(response[lastResponseKey], s, strict, subset);
}
} else {
const aliases = aliasMap && aliasMap.aliases;
const responseName = aliases && aliases[s] || s;
if (hasOwn.call(response, responseName)) {
- keyObj[prevKey = s] = response[responseName];
+ keyObj[lastActualKey = s] = response[lastResponseKey = responseName];
} else {
invariant(!strict, `Missing field '${responseName}' while computing key fields`);
- prevKey = void 0;
+ lastResponseKey = lastActualKey = void 0;
}
}
});
diff --git a/src/core/ObservableQuery.ts b/src/core/ObservableQuery.ts
index 3b339d84401..6038a87755f 100644
--- a/src/core/ObservableQuery.ts
+++ b/src/core/ObservableQuery.ts
@@ -45,6 +45,12 @@ export interface UpdateQueryOptions {
let warnedAboutUpdateQuery = false;
+interface Last {
+ result: ApolloQueryResult;
+ variables?: TVariables;
+ error?: ApolloError;
+}
+
export class ObservableQuery<
TData = any,
TVariables = OperationVariables
@@ -68,12 +74,15 @@ export class ObservableQuery<
private observers = new Set>>();
private subscriptions = new Set();
- private lastResult: ApolloQueryResult | undefined;
- private lastResultSnapshot: ApolloQueryResult | undefined;
- private lastError: ApolloError | undefined;
+ private last?: Last;
+
private queryInfo: QueryInfo;
+ // When this.concast is defined, this.observer is the Observer currently
+ // subscribed to that Concast.
private concast?: Concast>;
+ private observer?: Observer>;
+
private pollingInfo?: {
interval: number;
timeout: ReturnType;
@@ -102,10 +111,11 @@ export class ObservableQuery<
this.observers.add(observer);
// Deliver most recent error or result.
- if (this.lastError) {
- observer.error && observer.error(this.lastError);
- } else if (this.lastResult) {
- observer.next && observer.next(this.lastResult);
+ const last = this.last;
+ if (last && last.error) {
+ observer.error && observer.error(last.error);
+ } else if (last && last.result) {
+ observer.next && observer.next(last.result);
}
// Initiate observation of this query if it hasn't been reported to
@@ -177,12 +187,8 @@ export class ObservableQuery<
}
public getCurrentResult(saveAsLastResult = true): ApolloQueryResult {
- const {
- lastResult,
- options: {
- fetchPolicy = "cache-first",
- },
- } = this;
+ // Use the last result as long as the variables match this.variables.
+ const lastResult = this.getLastResult(true);
const networkStatus =
this.queryInfo.networkStatus ||
@@ -202,11 +208,14 @@ export class ObservableQuery<
if (!this.queryManager.transform(this.options.query).hasForcedResolvers) {
const diff = this.queryInfo.getDiff();
- result.data = (
- diff.complete ||
- this.options.returnPartialData
- ) ? diff.result : void 0;
+ if (diff.complete || this.options.returnPartialData) {
+ result.data = diff.result;
+ }
+ if (equal(result.data, {})) {
+ result.data = void 0 as any;
+ }
+ const { fetchPolicy = "cache-first" } = this.options;
if (diff.complete) {
// If the diff is complete, and we're using a FetchPolicy that
// terminates after a complete cache read, we can assume the next
@@ -247,23 +256,31 @@ export class ObservableQuery<
// Compares newResult to the snapshot we took of this.lastResult when it was
// first received.
public isDifferentFromLastResult(newResult: ApolloQueryResult) {
- return !equal(this.lastResultSnapshot, newResult);
+ return !this.last || !equal(this.last.result, newResult);
+ }
+
+ private getLast>(
+ key: K,
+ variablesMustMatch?: boolean,
+ ) {
+ const last = this.last;
+ if (last &&
+ last[key] &&
+ (!variablesMustMatch || equal(last!.variables, this.variables))) {
+ return last[key];
+ }
}
- // Returns the last result that observer.next was called with. This is not the same as
- // getCurrentResult! If you're not sure which you need, then you probably need getCurrentResult.
- public getLastResult(): ApolloQueryResult | undefined {
- return this.lastResult;
+ public getLastResult(variablesMustMatch?: boolean): ApolloQueryResult | undefined {
+ return this.getLast("result", variablesMustMatch);
}
- public getLastError(): ApolloError | undefined {
- return this.lastError;
+ public getLastError(variablesMustMatch?: boolean): ApolloError | undefined {
+ return this.getLast("error", variablesMustMatch);
}
public resetLastResults(): void {
- delete this.lastResult;
- delete this.lastResultSnapshot;
- delete this.lastError;
+ delete this.last;
this.isTornDown = false;
}
@@ -499,7 +516,6 @@ once, rather than every time you call fetchMore.`);
const { result } = queryManager.cache.diff({
query: this.options.query,
variables: this.variables,
- previousResult: this.lastResult?.data,
returnPartialData: true,
optimistic: false,
});
@@ -599,16 +615,21 @@ once, rather than every time you call fetchMore.`);
poll();
}
- private updateLastResult(newResult: ApolloQueryResult) {
- const previousResult = this.lastResult;
- this.lastResult = newResult;
- this.lastResultSnapshot = this.queryManager.assumeImmutableResults
- ? newResult
- : cloneDeep(newResult);
+ private updateLastResult(
+ newResult: ApolloQueryResult,
+ variables = this.variables,
+ ) {
+ this.last = {
+ ...this.last,
+ result: this.queryManager.assumeImmutableResults
+ ? newResult
+ : cloneDeep(newResult),
+ variables,
+ };
if (!isNonEmptyArray(newResult.errors)) {
- delete this.lastError;
+ delete this.last.error;
}
- return previousResult;
+ return this.last;
}
public reobserve(
@@ -657,7 +678,16 @@ once, rather than every time you call fetchMore.`);
}
}
+ const variables = options.variables && { ...options.variables };
const concast = this.fetch(options, newNetworkStatus);
+ const observer: Observer> = {
+ next: result => {
+ this.reportResult(result, variables);
+ },
+ error: error => {
+ this.reportError(error, variables);
+ },
+ };
if (!useDisposableConcast) {
// We use the {add,remove}Observer methods directly to avoid wrapping
@@ -665,14 +695,15 @@ once, rather than every time you call fetchMore.`);
// that we can remove it here without triggering any unsubscriptions,
// because we just want to ignore the old observable, not prematurely shut
// it down, since other consumers may be awaiting this.concast.promise.
- if (this.concast) {
+ if (this.concast && this.observer) {
this.concast.removeObserver(this.observer, true);
}
this.concast = concast;
+ this.observer = observer;
}
- concast.addObserver(this.observer);
+ concast.addObserver(observer);
return concast.promise;
}
@@ -684,31 +715,40 @@ once, rather than every time you call fetchMore.`);
// save the fetchMore result as this.lastResult, causing it to be
// ignored due to the this.isDifferentFromLastResult check in
// this.observer.next.
- this.observer.next(this.getCurrentResult(false));
+ this.reportResult(
+ this.getCurrentResult(false),
+ this.variables,
+ );
}
- private observer = {
- next: (result: ApolloQueryResult) => {
- if (this.lastError || this.isDifferentFromLastResult(result)) {
- this.updateLastResult(result);
- iterateObserversSafely(this.observers, 'next', result);
- }
- },
+ private reportResult(
+ result: ApolloQueryResult,
+ variables: TVariables | undefined,
+ ) {
+ if (this.getLastError() || this.isDifferentFromLastResult(result)) {
+ this.updateLastResult(result, variables);
+ iterateObserversSafely(this.observers, 'next', result);
+ }
+ }
- error: (error: ApolloError) => {
- // Since we don't get the current result on errors, only the error, we
- // must mirror the updates that occur in QueryStore.markQueryError here
- this.updateLastResult({
- ...this.lastResult,
- error,
- errors: error.graphQLErrors,
- networkStatus: NetworkStatus.error,
- loading: false,
- } as ApolloQueryResult);
-
- iterateObserversSafely(this.observers, 'error', this.lastError = error);
- },
- };
+ private reportError(
+ error: ApolloError,
+ variables: TVariables | undefined,
+ ) {
+ // Since we don't get the current result on errors, only the error, we
+ // must mirror the updates that occur in QueryStore.markQueryError here
+ const errorResult = {
+ ...this.getLastResult(),
+ error,
+ errors: error.graphQLErrors,
+ networkStatus: NetworkStatus.error,
+ loading: false,
+ } as ApolloQueryResult;
+
+ this.updateLastResult(errorResult, variables);
+
+ iterateObserversSafely(this.observers, 'error', this.last!.error = error);
+ }
public hasObservers() {
return this.observers.size > 0;
@@ -716,9 +756,10 @@ once, rather than every time you call fetchMore.`);
private tearDownQuery() {
if (this.isTornDown) return;
- if (this.concast) {
+ if (this.concast && this.observer) {
this.concast.removeObserver(this.observer);
delete this.concast;
+ delete this.observer;
}
this.stopPolling();
diff --git a/src/core/__tests__/ObservableQuery.ts b/src/core/__tests__/ObservableQuery.ts
index d3df4d89abe..94bea64470a 100644
--- a/src/core/__tests__/ObservableQuery.ts
+++ b/src/core/__tests__/ObservableQuery.ts
@@ -798,7 +798,7 @@ describe('ObservableQuery', () => {
expect(result.errors).toEqual([error]);
expect(observable.getCurrentResult().errors).toEqual([error]);
observable.setVariables(differentVariables);
- expect(observable.getCurrentResult().errors).toEqual([error]);
+ expect(observable.getCurrentResult().errors).toBeUndefined();
} else if (handleCount === 2) {
expect(result.data).toEqual(dataTwo);
expect(observable.getCurrentResult().data).toEqual(
diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts
index 7975af5fbd4..71e05d0f718 100644
--- a/src/react/data/QueryData.ts
+++ b/src/react/data/QueryData.ts
@@ -323,14 +323,13 @@ export class QueryData extends OperationData<
// has a chance to stay open).
const { currentObservable } = this;
if (currentObservable) {
- const lastError = currentObservable.getLastError();
- const lastResult = currentObservable.getLastResult();
- currentObservable.resetLastResults();
- this.startQuerySubscription();
- Object.assign(currentObservable, {
- lastError,
- lastResult
- });
+ const last = currentObservable["last"];
+ try {
+ currentObservable.resetLastResults();
+ this.startQuerySubscription();
+ } finally {
+ currentObservable["last"] = last;
+ }
}
}
diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx
index 61a8057c853..967f4ab74c9 100644
--- a/src/react/hooks/__tests__/useQuery.test.tsx
+++ b/src/react/hooks/__tests__/useQuery.test.tsx
@@ -18,7 +18,6 @@ import { ApolloLink } from '../../../link/core';
import { itAsync, MockLink, MockedProvider, mockSingleLink } from '../../../testing';
import { useQuery } from '../useQuery';
import { useMutation } from '../useMutation';
-import { invariant } from 'ts-invariant';
describe('useQuery Hook', () => {
describe('General use', () => {
@@ -2438,7 +2437,6 @@ describe('useQuery Hook', () => {
describe('Missing Fields', () => {
it('should log debug messages about MissingFieldErrors from the cache', async () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
- const debugSpy = jest.spyOn(invariant, 'debug').mockImplementation(() => {});
const carQuery: DocumentNode = gql`
query cars($id: Int) {
@@ -2488,15 +2486,8 @@ describe('useQuery Hook', () => {
expect(result.current.error).toBe(undefined);
await waitForNextUpdate();
expect(result.current.loading).toBe(false);
- expect(result.current.data).toBe(undefined);
-
+ expect(result.current.data).toEqual(carData);
expect(result.current.error).toBeUndefined();
- expect(debugSpy).toHaveBeenCalledTimes(1);
- expect(debugSpy).toHaveBeenLastCalledWith(
- "Missing cache result fields: cars.0.vin",
- [new Error("Can't find field 'vin' on Car:1 object")]
- );
- debugSpy.mockRestore();
expect(errorSpy).toHaveBeenCalledTimes(1);
expect(errorSpy).toHaveBeenLastCalledWith(