diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9667c13db0b..47f578ab63d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,19 @@
- Allow optional arguments in `keyArgs: [...]` arrays for `InMemoryCache` field policies.
[@benjamn](https://github.com/benjamn) in [#7109](https://github.com/apollographql/apollo-client/pull/7109)
+## Apollo Client 3.2.4
+
+## Improvements
+
+- Update the `optimism` npm dependency to version 0.13.0 in order to use the new `optimistic.forget` method to fix a potential `cache.watch` memory leak.
+ [@benjamn](https://github.com/benjamn) in [#7157](https://github.com/apollographql/apollo-client/pull/7157)
+
+- Consider `cache.reset` a destructive method, like `cache.evict` and `cache.modify`.
+ [@joshjg](https://github.com/joshjg) in [#7150](https://github.com/apollographql/apollo-client/pull/7150)
+
+- Avoid refetching observerless queries with `reFetchObservableQueries`.
+ [@joshjg](https://github.com/joshjg) in [#7146](https://github.com/apollographql/apollo-client/pull/7146)
+
## Apollo Client 3.2.3
## Improvements
diff --git a/package-lock.json b/package-lock.json
index 29fec216c34..7d68b25b1d3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1473,13 +1473,13 @@
}
},
"@jest/core": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.5.2.tgz",
- "integrity": "sha512-LLTo1LQMg7eJjG/+P1NYqFof2B25EV1EqzD5FonklihG4UJKiK2JBIvWonunws6W7e+DhNLoFD+g05tCY03eyA==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.5.3.tgz",
+ "integrity": "sha512-CiU0UKFF1V7KzYTVEtFbFmGLdb2g4aTtY0WlyUfLgj/RtoTnJFhh50xKKr7OYkdmBUlGFSa2mD1TU3UZ6OLd4g==",
"dev": true,
"requires": {
"@jest/console": "^26.5.2",
- "@jest/reporters": "^26.5.2",
+ "@jest/reporters": "^26.5.3",
"@jest/test-result": "^26.5.2",
"@jest/transform": "^26.5.2",
"@jest/types": "^26.5.2",
@@ -1489,17 +1489,17 @@
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"jest-changed-files": "^26.5.2",
- "jest-config": "^26.5.2",
+ "jest-config": "^26.5.3",
"jest-haste-map": "^26.5.2",
"jest-message-util": "^26.5.2",
"jest-regex-util": "^26.0.0",
"jest-resolve": "^26.5.2",
- "jest-resolve-dependencies": "^26.5.2",
- "jest-runner": "^26.5.2",
- "jest-runtime": "^26.5.2",
- "jest-snapshot": "^26.5.2",
+ "jest-resolve-dependencies": "^26.5.3",
+ "jest-runner": "^26.5.3",
+ "jest-runtime": "^26.5.3",
+ "jest-snapshot": "^26.5.3",
"jest-util": "^26.5.2",
- "jest-validate": "^26.5.2",
+ "jest-validate": "^26.5.3",
"jest-watcher": "^26.5.2",
"micromatch": "^4.0.2",
"p-each-series": "^2.1.0",
@@ -1779,14 +1779,14 @@
}
},
"@jest/globals": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.5.2.tgz",
- "integrity": "sha512-9PmnFsAUJxpPt1s/stq02acS1YHliVBDNfAWMe1bwdRr1iTCfhbNt3ERQXrO/ZfZSweftoA26Q/2yhSVSWQ3sw==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.5.3.tgz",
+ "integrity": "sha512-7QztI0JC2CuB+Wx1VdnOUNeIGm8+PIaqngYsZXQCkH2QV0GFqzAYc9BZfU0nuqA6cbYrWh5wkuMzyii3P7deug==",
"dev": true,
"requires": {
"@jest/environment": "^26.5.2",
"@jest/types": "^26.5.2",
- "expect": "^26.5.2"
+ "expect": "^26.5.3"
},
"dependencies": {
"@jest/types": {
@@ -1857,9 +1857,9 @@
}
},
"@jest/reporters": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.5.2.tgz",
- "integrity": "sha512-zvq6Wvy6MmJq/0QY0YfOPb49CXKSf42wkJbrBPkeypVa8I+XDxijvFuywo6TJBX/ILPrdrlE/FW9vJZh6Rf9vA==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.5.3.tgz",
+ "integrity": "sha512-X+vR0CpfMQzYcYmMFKNY9n4jklcb14Kffffp7+H/MqitWnb0440bW2L76NGWKAa+bnXhNoZr+lCVtdtPmfJVOQ==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
@@ -1886,7 +1886,7 @@
"source-map": "^0.6.0",
"string-length": "^4.0.1",
"terminal-link": "^2.0.0",
- "v8-to-istanbul": "^5.0.1"
+ "v8-to-istanbul": "^6.0.1"
},
"dependencies": {
"@jest/types": {
@@ -2080,16 +2080,16 @@
}
},
"@jest/test-sequencer": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.5.2.tgz",
- "integrity": "sha512-XmGEh7hh07H2B8mHLFCIgr7gA5Y6Hw1ZATIsbz2fOhpnQ5AnQtZk0gmP0Q5/+mVB2xygO64tVFQxOajzoptkNA==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.5.3.tgz",
+ "integrity": "sha512-Wqzb7aQ13L3T47xHdpUqYMOpiqz6Dx2QDDghp5AV/eUDXR7JieY+E1s233TQlNyl+PqtqgjVokmyjzX/HA51BA==",
"dev": true,
"requires": {
"@jest/test-result": "^26.5.2",
"graceful-fs": "^4.2.4",
"jest-haste-map": "^26.5.2",
- "jest-runner": "^26.5.2",
- "jest-runtime": "^26.5.2"
+ "jest-runner": "^26.5.3",
+ "jest-runtime": "^26.5.3"
}
},
"@jest/transform": {
@@ -2562,9 +2562,9 @@
}
},
"@types/lodash": {
- "version": "4.14.161",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.161.tgz",
- "integrity": "sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==",
+ "version": "4.14.162",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.162.tgz",
+ "integrity": "sha512-alvcho1kRUnnD1Gcl4J+hK0eencvzq9rmzvFPRmP5rPHx9VVsJj6bKLTATPVf9ktgv4ujzh7T+XWKp+jhuODig==",
"dev": true
},
"@types/minimatch": {
@@ -2758,9 +2758,9 @@
}
},
"ajv": {
- "version": "6.12.5",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
- "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
+ "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": "^3.1.1",
@@ -4330,9 +4330,9 @@
"dev": true
},
"expect": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/expect/-/expect-26.5.2.tgz",
- "integrity": "sha512-ccTGrXZd8DZCcvCz4htGXTkd/LOoy6OEtiDS38x3/VVf6E4AQL0QoeksBiw7BtGR5xDNiRYPB8GN6pfbuTOi7w==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-26.5.3.tgz",
+ "integrity": "sha512-kkpOhGRWGOr+TEFUnYAjfGvv35bfP+OlPtqPIJpOCR9DVtv8QV+p8zG0Edqafh80fsjeE+7RBcVUq1xApnYglw==",
"dev": true,
"requires": {
"@jest/types": "^26.5.2",
@@ -5515,14 +5515,14 @@
"dev": true
},
"jest": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest/-/jest-26.5.2.tgz",
- "integrity": "sha512-4HFabJVwsgDwul/7rhXJ3yFAF/aUkVIXiJWmgFxb+WMdZG39fVvOwYAs8/3r4AlFPc4m/n5sTMtuMbOL3kNtrQ==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-26.5.3.tgz",
+ "integrity": "sha512-uJi3FuVSLmkZrWvaDyaVTZGLL8WcfynbRnFXyAHuEtYiSZ+ijDDIMOw1ytmftK+y/+OdAtsG9QrtbF7WIBmOyA==",
"dev": true,
"requires": {
- "@jest/core": "^26.5.2",
+ "@jest/core": "^26.5.3",
"import-local": "^3.0.2",
- "jest-cli": "^26.5.2"
+ "jest-cli": "^26.5.3"
},
"dependencies": {
"@jest/types": {
@@ -5591,12 +5591,12 @@
"dev": true
},
"jest-cli": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.5.2.tgz",
- "integrity": "sha512-usm48COuUvRp8YEG5OWOaxbSM0my7eHn3QeBWxiGUuFhvkGVBvl1fic4UjC02EAEQtDv8KrNQUXdQTV6ZZBsoA==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.5.3.tgz",
+ "integrity": "sha512-HkbSvtugpSXBf2660v9FrNVUgxvPkssN8CRGj9gPM8PLhnaa6zziFiCEKQAkQS4uRzseww45o0TR+l6KeRYV9A==",
"dev": true,
"requires": {
- "@jest/core": "^26.5.2",
+ "@jest/core": "^26.5.3",
"@jest/test-result": "^26.5.2",
"@jest/types": "^26.5.2",
"chalk": "^4.0.0",
@@ -5604,9 +5604,9 @@
"graceful-fs": "^4.2.4",
"import-local": "^3.0.2",
"is-ci": "^2.0.0",
- "jest-config": "^26.5.2",
+ "jest-config": "^26.5.3",
"jest-util": "^26.5.2",
- "jest-validate": "^26.5.2",
+ "jest-validate": "^26.5.3",
"prompts": "^2.0.1",
"yargs": "^15.4.1"
}
@@ -5788,13 +5788,13 @@
}
},
"jest-config": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.5.2.tgz",
- "integrity": "sha512-dqJOnSegNdE5yDiuGHsjTM5gec7Z4AcAMHiW+YscbOYJAlb3LEtDSobXCq0or9EmGQI5SFmKy4T7P1FxetJOfg==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.5.3.tgz",
+ "integrity": "sha512-NVhZiIuN0GQM6b6as4CI5FSCyXKxdrx5ACMCcv/7Pf+TeCajJhJc+6dwgdAVPyerUFB9pRBIz3bE7clSrRge/w==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^26.5.2",
+ "@jest/test-sequencer": "^26.5.3",
"@jest/types": "^26.5.2",
"babel-jest": "^26.5.2",
"chalk": "^4.0.0",
@@ -5804,11 +5804,11 @@
"jest-environment-jsdom": "^26.5.2",
"jest-environment-node": "^26.5.2",
"jest-get-type": "^26.3.0",
- "jest-jasmine2": "^26.5.2",
+ "jest-jasmine2": "^26.5.3",
"jest-regex-util": "^26.0.0",
"jest-resolve": "^26.5.2",
"jest-util": "^26.5.2",
- "jest-validate": "^26.5.2",
+ "jest-validate": "^26.5.3",
"micromatch": "^4.0.2",
"pretty-format": "^26.5.2"
},
@@ -6445,9 +6445,9 @@
}
},
"jest-jasmine2": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.5.2.tgz",
- "integrity": "sha512-2J+GYcgLVPTkpmvHEj0/IDTIAuyblGNGlyGe4fLfDT2aktEPBYvoxUwFiOmDDxxzuuEAD2uxcYXr0+1Yw4tjFA==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.5.3.tgz",
+ "integrity": "sha512-nFlZOpnGlNc7y/+UkkeHnvbOM+rLz4wB1AimgI9QhtnqSZte0wYjbAm8hf7TCwXlXgDwZxAXo6z0a2Wzn9FoOg==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
@@ -6458,13 +6458,13 @@
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "expect": "^26.5.2",
+ "expect": "^26.5.3",
"is-generator-fn": "^2.0.0",
"jest-each": "^26.5.2",
"jest-matcher-utils": "^26.5.2",
"jest-message-util": "^26.5.2",
- "jest-runtime": "^26.5.2",
- "jest-snapshot": "^26.5.2",
+ "jest-runtime": "^26.5.3",
+ "jest-snapshot": "^26.5.3",
"jest-util": "^26.5.2",
"pretty-format": "^26.5.2",
"throat": "^5.0.0"
@@ -7096,14 +7096,14 @@
}
},
"jest-resolve-dependencies": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.5.2.tgz",
- "integrity": "sha512-LLkc8LuRtxqOx0AtX/Npa2C4I23WcIrwUgNtHYXg4owYF/ZDQShcwBAHjYZIFR06+HpQcZ43+kCTMlQ3aDCYTg==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.5.3.tgz",
+ "integrity": "sha512-+KMDeke/BFK+mIQ2IYSyBz010h7zQaVt4Xie6cLqUGChorx66vVeQVv4ErNoMwInnyYHi1Ud73tDS01UbXbfLQ==",
"dev": true,
"requires": {
"@jest/types": "^26.5.2",
"jest-regex-util": "^26.0.0",
- "jest-snapshot": "^26.5.2"
+ "jest-snapshot": "^26.5.3"
},
"dependencies": {
"@jest/types": {
@@ -7174,9 +7174,9 @@
}
},
"jest-runner": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.5.2.tgz",
- "integrity": "sha512-GKhYxtSX5+tXZsd2QwfkDqPIj5C2HqOdXLRc2x2qYqWE26OJh17xo58/fN/mLhRkO4y6o60ZVloan7Kk5YA6hg==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.5.3.tgz",
+ "integrity": "sha512-qproP0Pq7IIule+263W57k2+8kWCszVJTC9TJWGUz0xJBr+gNiniGXlG8rotd0XxwonD5UiJloYoSO5vbUr5FQ==",
"dev": true,
"requires": {
"@jest/console": "^26.5.2",
@@ -7188,13 +7188,13 @@
"emittery": "^0.7.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-config": "^26.5.2",
+ "jest-config": "^26.5.3",
"jest-docblock": "^26.0.0",
"jest-haste-map": "^26.5.2",
"jest-leak-detector": "^26.5.2",
"jest-message-util": "^26.5.2",
"jest-resolve": "^26.5.2",
- "jest-runtime": "^26.5.2",
+ "jest-runtime": "^26.5.3",
"jest-util": "^26.5.2",
"jest-worker": "^26.5.0",
"source-map-support": "^0.5.6",
@@ -7294,15 +7294,15 @@
}
},
"jest-runtime": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.5.2.tgz",
- "integrity": "sha512-zArr4DatX/Sn0wswX/AnAuJgmwgAR5rNtrUz36HR8BfMuysHYNq5sDbYHuLC4ICyRdy5ae/KQ+sczxyS9G6Qvw==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.5.3.tgz",
+ "integrity": "sha512-IDjalmn2s/Tc4GvUwhPHZ0iaXCdMRq5p6taW9P8RpU+FpG01O3+H8z+p3rDCQ9mbyyyviDgxy/LHPLzrIOKBkQ==",
"dev": true,
"requires": {
"@jest/console": "^26.5.2",
"@jest/environment": "^26.5.2",
"@jest/fake-timers": "^26.5.2",
- "@jest/globals": "^26.5.2",
+ "@jest/globals": "^26.5.3",
"@jest/source-map": "^26.5.0",
"@jest/test-result": "^26.5.2",
"@jest/transform": "^26.5.2",
@@ -7313,15 +7313,15 @@
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.4",
- "jest-config": "^26.5.2",
+ "jest-config": "^26.5.3",
"jest-haste-map": "^26.5.2",
"jest-message-util": "^26.5.2",
"jest-mock": "^26.5.2",
"jest-regex-util": "^26.0.0",
"jest-resolve": "^26.5.2",
- "jest-snapshot": "^26.5.2",
+ "jest-snapshot": "^26.5.3",
"jest-util": "^26.5.2",
- "jest-validate": "^26.5.2",
+ "jest-validate": "^26.5.3",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
"yargs": "^15.4.1"
@@ -7419,9 +7419,9 @@
}
},
"jest-snapshot": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.5.2.tgz",
- "integrity": "sha512-MkXIDvEefzDubI/WaDVSRH4xnkuirP/Pz8LhAIDXcVQTmcEfwxywj5LGwBmhz+kAAIldA7XM4l96vbpzltSjqg==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.5.3.tgz",
+ "integrity": "sha512-ZgAk0Wm0JJ75WS4lGaeRfa0zIgpL0KD595+XmtwlIEMe8j4FaYHyZhP1LNOO+8fXq7HJ3hll54+sFV9X4+CGVw==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0",
@@ -7429,7 +7429,7 @@
"@types/babel__traverse": "^7.0.4",
"@types/prettier": "^2.0.0",
"chalk": "^4.0.0",
- "expect": "^26.5.2",
+ "expect": "^26.5.3",
"graceful-fs": "^4.2.4",
"jest-diff": "^26.5.2",
"jest-get-type": "^26.3.0",
@@ -7640,9 +7640,9 @@
}
},
"jest-validate": {
- "version": "26.5.2",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.5.2.tgz",
- "integrity": "sha512-FmJks0zY36mp6Af/5sqO6CTL9bNMU45yKCJk3hrz8d2aIqQIlN1pr9HPIwZE8blLaewOla134nt5+xAmWsx3SQ==",
+ "version": "26.5.3",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.5.3.tgz",
+ "integrity": "sha512-LX07qKeAtY+lsU0o3IvfDdN5KH9OulEGOMN1sFo6PnEf5/qjS1LZIwNk9blcBeW94pQUI9dLN9FlDYDWI5tyaA==",
"dev": true,
"requires": {
"@jest/types": "^26.5.2",
@@ -7700,9 +7700,9 @@
}
},
"camelcase": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
- "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.1.0.tgz",
+ "integrity": "sha512-WCMml9ivU60+8rEJgELlFp1gxFcEGxwYleE3bziHEDeqsqAWGHdimB7beBFGjLzVNgPGyDsfgXLQEYMpmIFnVQ==",
"dev": true
},
"chalk": {
@@ -8546,9 +8546,9 @@
}
},
"optimism": {
- "version": "0.12.2",
- "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.2.tgz",
- "integrity": "sha512-k7hFhlmfLl6HNThIuuvYMQodC1c+q6Uc6V9cLVsMWyW514QuaxVJH/khPu2vLRIoDTpFdJ5sojlARhg1rzyGbg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.13.0.tgz",
+ "integrity": "sha512-6JAh3dH+YUE4QUdsgUw8nUQyrNeBKfAEKOHMlLkQ168KhIYFIxzPsHakWrRXDnTO+x61RJrS3/2uEt6W0xlocA==",
"requires": {
"@wry/context": "^0.5.2"
}
@@ -10939,9 +10939,9 @@
"optional": true
},
"v8-to-istanbul": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz",
- "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-6.0.1.tgz",
+ "integrity": "sha512-PzM1WlqquhBvsV+Gco6WSFeg1AGdD53ccMRkFeyHRE/KRZaVacPOmQYP3EeVgDBtKD2BJ8kgynBQ5OtKiHCH+w==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.1",
diff --git a/package.json b/package.json
index 83843893585..3b753fa6a6d 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,7 @@
"fast-json-stable-stringify": "^2.0.0",
"graphql-tag": "^2.11.0",
"hoist-non-react-statics": "^3.3.2",
- "optimism": "^0.12.2",
+ "optimism": "^0.13.0",
"prop-types": "^15.7.2",
"symbol-observable": "^2.0.0",
"terser": "^5.2.0",
@@ -94,7 +94,7 @@
"@types/glob": "7.1.3",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/jest": "26.0.14",
- "@types/lodash": "4.14.161",
+ "@types/lodash": "4.14.162",
"@types/node": "14.11.8",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
@@ -106,7 +106,7 @@
"glob": "7.1.6",
"graphql": "15.3.0",
"graphql-tools": "^6.0.12",
- "jest": "26.5.2",
+ "jest": "26.5.3",
"jest-fetch-mock": "^3.0.3",
"jest-junit": "12.0.0",
"lodash": "4.17.20",
diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts
index 38c33e28812..0b76db0e846 100644
--- a/src/cache/inmemory/inMemoryCache.ts
+++ b/src/cache/inmemory/inMemoryCache.ts
@@ -200,6 +200,11 @@ export class InMemoryCache extends ApolloCache {
}
return () => {
this.watches.delete(watch);
+ this.watchDep.dirty(watch);
+ // Remove this watch from the LRU cache managed by the
+ // maybeBroadcastWatch OptimisticWrapperFunction, to prevent memory
+ // leaks involving the closure of watch.callback.
+ this.maybeBroadcastWatch.forget(watch);
};
}
diff --git a/src/core/ObservableQuery.ts b/src/core/ObservableQuery.ts
index d4b31c4083f..fce8eec00ff 100644
--- a/src/core/ObservableQuery.ts
+++ b/src/core/ObservableQuery.ts
@@ -620,6 +620,10 @@ once, rather than every time you call fetchMore.`);
},
};
+ public hasObservers() {
+ return this.observers.size > 0;
+ }
+
private tearDownQuery() {
const { queryManager } = this;
diff --git a/src/core/QueryInfo.ts b/src/core/QueryInfo.ts
index e3c82e511c7..d1b25bfdd2e 100644
--- a/src/core/QueryInfo.ts
+++ b/src/core/QueryInfo.ts
@@ -81,6 +81,7 @@ export class QueryInfo {
destructiveMethodCounts.set(cache, 0);
wrapDestructiveCacheMethod(cache, "evict");
wrapDestructiveCacheMethod(cache, "modify");
+ wrapDestructiveCacheMethod(cache, "reset");
}
}
diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts
index 1ac68eeb0c2..943fc0d994e 100644
--- a/src/core/QueryManager.ts
+++ b/src/core/QueryManager.ts
@@ -563,7 +563,7 @@ export class QueryManager {
const observableQueryPromises: Promise>[] = [];
this.queries.forEach(({ observableQuery }, queryId) => {
- if (observableQuery) {
+ if (observableQuery && observableQuery.hasObservers()) {
const fetchPolicy = observableQuery.options.fetchPolicy;
observableQuery.resetLastResults();
diff --git a/src/core/__tests__/QueryManager/index.ts b/src/core/__tests__/QueryManager/index.ts
index e29ba0e1a21..8f861def4e4 100644
--- a/src/core/__tests__/QueryManager/index.ts
+++ b/src/core/__tests__/QueryManager/index.ts
@@ -3506,9 +3506,18 @@ describe('QueryManager', () => {
}
}
`;
-
- const queryManager = mockQueryManager(reject);
+ const data = {
+ author: {
+ firstName: 'John',
+ lastName: 'Smith',
+ },
+ };
+ const queryManager = mockQueryManager(reject, {
+ request: { query },
+ result: { data }
+ });
const obs = queryManager.watchQuery({ query });
+ obs.subscribe({});
obs.refetch = resolve as any;
queryManager.resetStore();
@@ -3536,6 +3545,7 @@ describe('QueryManager', () => {
let refetchCount = 0;
const obs = queryManager.watchQuery(options);
+ obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
@@ -3570,6 +3580,41 @@ describe('QueryManager', () => {
let refetchCount = 0;
+ const obs = queryManager.watchQuery(options);
+ obs.subscribe({});
+ obs.refetch = () => {
+ ++refetchCount;
+ return null as never;
+ };
+
+ queryManager.resetStore();
+
+ setTimeout(() => {
+ expect(refetchCount).toEqual(0);
+ resolve();
+ }, 50);
+ });
+
+ itAsync('should not call refetch on a non-subscribed Observable if the store is reset', (resolve, reject) => {
+ const query = gql`
+ query {
+ author {
+ firstName
+ lastName
+ }
+ }
+ `;
+
+ const queryManager = createQueryManager({
+ link: mockSingleLink().setOnError(reject),
+ });
+
+ const options = {
+ query,
+ } as WatchQueryOptions;
+
+ let refetchCount = 0;
+
const obs = queryManager.watchQuery(options);
obs.refetch = () => {
++refetchCount;
@@ -3906,10 +3951,19 @@ describe('QueryManager', () => {
}
}
`;
-
- const queryManager = mockQueryManager(reject);
+ const data = {
+ author: {
+ firstName: 'John',
+ lastName: 'Smith',
+ },
+ };
+ const queryManager = mockQueryManager(reject, {
+ request: { query },
+ result: { data },
+ });
const obs = queryManager.watchQuery({ query });
+ obs.subscribe({});
obs.refetch = resolve as any;
queryManager.reFetchObservableQueries();
@@ -3937,6 +3991,7 @@ describe('QueryManager', () => {
let refetchCount = 0;
const obs = queryManager.watchQuery(options);
+ obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
@@ -3972,6 +4027,7 @@ describe('QueryManager', () => {
let refetchCount = 0;
const obs = queryManager.watchQuery(options);
+ obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
@@ -4007,6 +4063,7 @@ describe('QueryManager', () => {
let refetchCount = 0;
const obs = queryManager.watchQuery(options);
+ obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
@@ -4021,6 +4078,40 @@ describe('QueryManager', () => {
}, 50);
});
+ itAsync('should not call refetch on a non-subscribed Observable', (resolve, reject) => {
+ const query = gql`
+ query {
+ author {
+ firstName
+ lastName
+ }
+ }
+ `;
+
+ const queryManager = createQueryManager({
+ link: mockSingleLink().setOnError(reject),
+ });
+
+ const options = {
+ query
+ } as WatchQueryOptions;
+
+ let refetchCount = 0;
+
+ const obs = queryManager.watchQuery(options);
+ obs.refetch = () => {
+ ++refetchCount;
+ return null as never;
+ };
+
+ queryManager.reFetchObservableQueries();
+
+ setTimeout(() => {
+ expect(refetchCount).toEqual(0);
+ resolve();
+ }, 50);
+ });
+
itAsync('should NOT throw an error on an inflight query() if the observed queries are refetched', (resolve, reject) => {
let queryManager: QueryManager;
const query = gql`