@khanacademy/wonder-blocks-data 8.0.4 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/es/index.js +87 -80
- package/dist/index.js +177 -136
- package/package.json +1 -1
- package/src/__docs__/_overview_ssr_.stories.mdx +2 -2
- package/src/__docs__/exports.purge-caches.stories.mdx +1 -1
- package/src/__docs__/exports.scoped-in-memory-cache.stories.mdx +3 -3
- package/src/__docs__/exports.serializable-in-memory-cache.stories.mdx +2 -2
- package/src/__docs__/exports.shared-cache.stories.mdx +16 -0
- package/src/__docs__/exports.use-shared-cache.stories.mdx +2 -2
- package/src/__docs__/types.raw-scoped-cache.stories.mdx +27 -0
- package/src/__docs__/types.scoped-cache.stories.mdx +96 -9
- package/src/components/__tests__/data.test.js +2 -2
- package/src/hooks/__tests__/use-shared-cache.test.js +2 -50
- package/src/hooks/use-shared-cache.js +6 -14
- package/src/index.js +4 -2
- package/src/util/__tests__/get-gql-request-id.test.js +33 -0
- package/src/util/__tests__/purge-caches.test.js +2 -2
- package/src/util/get-gql-request-id.js +50 -6
- package/src/util/purge-caches.js +2 -2
- package/src/util/scoped-in-memory-cache.js +5 -9
- package/src/util/serializable-in-memory-cache.js +4 -8
- package/src/util/types.js +38 -1
- package/src/__docs__/exports.purge-shared-cache.stories.mdx +0 -20
package/dist/index.js
CHANGED
|
@@ -178,7 +178,7 @@ module.exports = require("@khanacademy/wonder-blocks-core");
|
|
|
178
178
|
/**
|
|
179
179
|
* Defines the various fetch policies that can be applied to requests.
|
|
180
180
|
*/
|
|
181
|
-
const FetchPolicy = __webpack_require__(
|
|
181
|
+
const FetchPolicy = __webpack_require__(23).Mirrored(["CacheBeforeNetwork", "CacheAndNetwork", "CacheOnly", "NetworkOnly"]);
|
|
182
182
|
/**
|
|
183
183
|
* Define what can be cached.
|
|
184
184
|
*
|
|
@@ -242,7 +242,7 @@ class GqlError extends _khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0
|
|
|
242
242
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
243
243
|
|
|
244
244
|
"use strict";
|
|
245
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return
|
|
245
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return SharedCache; });
|
|
246
246
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return useSharedCache; });
|
|
247
247
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
|
248
248
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
@@ -259,18 +259,13 @@ class GqlError extends _khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0
|
|
|
259
259
|
*/
|
|
260
260
|
const cache = new _util_scoped_in_memory_cache_js__WEBPACK_IMPORTED_MODULE_2__[/* ScopedInMemoryCache */ "a"]();
|
|
261
261
|
/**
|
|
262
|
-
*
|
|
262
|
+
* Access to the shared in-memory cache.
|
|
263
|
+
*
|
|
264
|
+
* This is the cache used by `useSharedCache` and related hooks and
|
|
265
|
+
* components.
|
|
263
266
|
*/
|
|
264
267
|
|
|
265
|
-
const
|
|
266
|
-
// If we have a valid scope (empty string is falsy), then clear that scope.
|
|
267
|
-
if (scope && typeof scope === "string") {
|
|
268
|
-
cache.purgeScope(scope);
|
|
269
|
-
} else {
|
|
270
|
-
// Just reset the object. This should be sufficient.
|
|
271
|
-
cache.purgeAll();
|
|
272
|
-
}
|
|
273
|
-
};
|
|
268
|
+
const SharedCache = cache;
|
|
274
269
|
/**
|
|
275
270
|
* Hook to retrieve data from and store data in an in-memory cache.
|
|
276
271
|
*
|
|
@@ -279,9 +274,6 @@ const purgeSharedCache = (scope = "") => {
|
|
|
279
274
|
* function to set the cache entry (passing null or undefined to this function
|
|
280
275
|
* will delete the entry).
|
|
281
276
|
*
|
|
282
|
-
* To clear a single scope within the cache or the entire cache,
|
|
283
|
-
* the `clearScopedCache` export is available.
|
|
284
|
-
*
|
|
285
277
|
* NOTE: Unlike useState or useReducer, we don't automatically update folks
|
|
286
278
|
* if the value they reference changes. We might add it later (if we need to),
|
|
287
279
|
* but the likelihood here is that things won't be changing in this cache in a
|
|
@@ -924,7 +916,7 @@ class ScopedInMemoryCache {
|
|
|
924
916
|
/**
|
|
925
917
|
* Policies to define how a hydratable effect should behave client-side.
|
|
926
918
|
*/
|
|
927
|
-
const WhenClientSide = __webpack_require__(
|
|
919
|
+
const WhenClientSide = __webpack_require__(23).Mirrored(["DoNotHydrate", "ExecuteWhenNoResult", "ExecuteWhenNoSuccessResult", "AlwaysExecute"]);
|
|
928
920
|
const DefaultScope = "useHydratableEffect";
|
|
929
921
|
/**
|
|
930
922
|
* Hook to execute an async operation on server and client.
|
|
@@ -1118,8 +1110,8 @@ const purgeHydrationCache = predicate => _ssr_cache_js__WEBPACK_IMPORTED_MODULE_
|
|
|
1118
1110
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
|
|
1119
1111
|
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8);
|
|
1120
1112
|
/* harmony import */ var _util_ssr_cache_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9);
|
|
1121
|
-
/* harmony import */ var _util_result_from_cache_response_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(
|
|
1122
|
-
/* harmony import */ var _use_request_interception_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(
|
|
1113
|
+
/* harmony import */ var _util_result_from_cache_response_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(33);
|
|
1114
|
+
/* harmony import */ var _use_request_interception_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20);
|
|
1123
1115
|
|
|
1124
1116
|
|
|
1125
1117
|
|
|
@@ -1183,7 +1175,7 @@ const useServerEffect = (requestId, handler, options = {}) => {
|
|
|
1183
1175
|
/* harmony import */ var _util_request_fulfillment_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
|
|
1184
1176
|
/* harmony import */ var _util_status_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6);
|
|
1185
1177
|
/* harmony import */ var _use_shared_cache_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5);
|
|
1186
|
-
/* harmony import */ var _use_request_interception_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(
|
|
1178
|
+
/* harmony import */ var _use_request_interception_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20);
|
|
1187
1179
|
/* harmony import */ var _util_types_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3);
|
|
1188
1180
|
|
|
1189
1181
|
|
|
@@ -1392,6 +1384,76 @@ const useCachedEffect = (requestId, handler, options = {}) => {
|
|
|
1392
1384
|
/* 18 */
|
|
1393
1385
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1394
1386
|
|
|
1387
|
+
"use strict";
|
|
1388
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getGqlDataFromResponse; });
|
|
1389
|
+
/* harmony import */ var _data_error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1390
|
+
/* harmony import */ var _gql_error_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* Validate a GQL operation response and extract the data.
|
|
1395
|
+
*/
|
|
1396
|
+
|
|
1397
|
+
const getGqlDataFromResponse = async response => {
|
|
1398
|
+
// Get the response as text, that way we can use the text in error
|
|
1399
|
+
// messaging, should our parsing fail.
|
|
1400
|
+
const bodyText = await response.text();
|
|
1401
|
+
let result;
|
|
1402
|
+
|
|
1403
|
+
try {
|
|
1404
|
+
result = JSON.parse(bodyText);
|
|
1405
|
+
} catch (e) {
|
|
1406
|
+
throw new _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataError */ "a"]("Failed to parse response", _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataErrors */ "b"].Parse, {
|
|
1407
|
+
metadata: {
|
|
1408
|
+
statusCode: response.status,
|
|
1409
|
+
bodyText
|
|
1410
|
+
},
|
|
1411
|
+
cause: e
|
|
1412
|
+
});
|
|
1413
|
+
} // Check for a bad status code.
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
if (response.status >= 300) {
|
|
1417
|
+
throw new _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataError */ "a"]("Response unsuccessful", _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataErrors */ "b"].Network, {
|
|
1418
|
+
metadata: {
|
|
1419
|
+
statusCode: response.status,
|
|
1420
|
+
result
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
} // Check that we have a valid result payload.
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
if ( // Flow shouldn't be warning about this.
|
|
1427
|
+
// $FlowIgnore[method-unbinding]
|
|
1428
|
+
!Object.prototype.hasOwnProperty.call(result, "data") && // Flow shouldn't be warning about this.
|
|
1429
|
+
// $FlowIgnore[method-unbinding]
|
|
1430
|
+
!Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
1431
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlError */ "a"]("Server response missing", _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlErrors */ "b"].BadResponse, {
|
|
1432
|
+
metadata: {
|
|
1433
|
+
statusCode: response.status,
|
|
1434
|
+
result
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
} // If the response payload has errors, throw an error.
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
1441
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlError */ "a"]("GraphQL errors", _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlErrors */ "b"].ErrorResult, {
|
|
1442
|
+
metadata: {
|
|
1443
|
+
statusCode: response.status,
|
|
1444
|
+
result
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
} // We got here, so return the data.
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
return result.data;
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
/***/ }),
|
|
1454
|
+
/* 19 */
|
|
1455
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1456
|
+
|
|
1395
1457
|
"use strict";
|
|
1396
1458
|
/* unused harmony export DocumentTypes */
|
|
1397
1459
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return graphQLDocumentNodeParser; });
|
|
@@ -1470,7 +1532,7 @@ function graphQLDocumentNodeParser(document) {
|
|
|
1470
1532
|
}
|
|
1471
1533
|
|
|
1472
1534
|
/***/ }),
|
|
1473
|
-
/*
|
|
1535
|
+
/* 20 */
|
|
1474
1536
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1475
1537
|
|
|
1476
1538
|
"use strict";
|
|
@@ -1521,7 +1583,7 @@ const useRequestInterception = (requestId, handler) => {
|
|
|
1521
1583
|
};
|
|
1522
1584
|
|
|
1523
1585
|
/***/ }),
|
|
1524
|
-
/*
|
|
1586
|
+
/* 21 */
|
|
1525
1587
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1526
1588
|
|
|
1527
1589
|
"use strict";
|
|
@@ -1532,7 +1594,7 @@ const useRequestInterception = (requestId, handler) => {
|
|
|
1532
1594
|
const GqlRouterContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createContext"](null);
|
|
1533
1595
|
|
|
1534
1596
|
/***/ }),
|
|
1535
|
-
/*
|
|
1597
|
+
/* 22 */
|
|
1536
1598
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1537
1599
|
|
|
1538
1600
|
"use strict";
|
|
@@ -1566,13 +1628,13 @@ const mergeGqlContext = (defaultContext, overrides) => {
|
|
|
1566
1628
|
};
|
|
1567
1629
|
|
|
1568
1630
|
/***/ }),
|
|
1569
|
-
/*
|
|
1631
|
+
/* 23 */
|
|
1570
1632
|
/***/ (function(module, exports) {
|
|
1571
1633
|
|
|
1572
1634
|
module.exports = require("flow-enums-runtime");
|
|
1573
1635
|
|
|
1574
1636
|
/***/ }),
|
|
1575
|
-
/*
|
|
1637
|
+
/* 24 */
|
|
1576
1638
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1577
1639
|
|
|
1578
1640
|
"use strict";
|
|
@@ -1649,7 +1711,7 @@ const abortInflightRequests = () => {
|
|
|
1649
1711
|
};
|
|
1650
1712
|
|
|
1651
1713
|
/***/ }),
|
|
1652
|
-
/*
|
|
1714
|
+
/* 25 */
|
|
1653
1715
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1654
1716
|
|
|
1655
1717
|
"use strict";
|
|
@@ -1667,12 +1729,12 @@ const abortInflightRequests = () => {
|
|
|
1667
1729
|
*/
|
|
1668
1730
|
|
|
1669
1731
|
const purgeCaches = () => {
|
|
1670
|
-
|
|
1732
|
+
_hooks_use_shared_cache_js__WEBPACK_IMPORTED_MODULE_0__[/* SharedCache */ "a"].purgeAll();
|
|
1671
1733
|
Object(_hydration_cache_api_js__WEBPACK_IMPORTED_MODULE_1__[/* purgeHydrationCache */ "b"])();
|
|
1672
1734
|
};
|
|
1673
1735
|
|
|
1674
1736
|
/***/ }),
|
|
1675
|
-
/*
|
|
1737
|
+
/* 26 */
|
|
1676
1738
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1677
1739
|
|
|
1678
1740
|
"use strict";
|
|
@@ -1703,7 +1765,7 @@ class TrackData extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
1703
1765
|
}
|
|
1704
1766
|
|
|
1705
1767
|
/***/ }),
|
|
1706
|
-
/*
|
|
1768
|
+
/* 27 */
|
|
1707
1769
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1708
1770
|
|
|
1709
1771
|
"use strict";
|
|
@@ -1735,7 +1797,7 @@ const Data = ({
|
|
|
1735
1797
|
/* harmony default export */ __webpack_exports__["a"] = (Data);
|
|
1736
1798
|
|
|
1737
1799
|
/***/ }),
|
|
1738
|
-
/*
|
|
1800
|
+
/* 28 */
|
|
1739
1801
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1740
1802
|
|
|
1741
1803
|
"use strict";
|
|
@@ -1776,19 +1838,37 @@ const InterceptRequests = ({
|
|
|
1776
1838
|
/* harmony default export */ __webpack_exports__["a"] = (InterceptRequests);
|
|
1777
1839
|
|
|
1778
1840
|
/***/ }),
|
|
1779
|
-
/*
|
|
1841
|
+
/* 29 */
|
|
1780
1842
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1781
1843
|
|
|
1782
1844
|
"use strict";
|
|
1783
1845
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getGqlRequestId; });
|
|
1784
|
-
const toString =
|
|
1846
|
+
const toString = value => {
|
|
1785
1847
|
var _JSON$stringify;
|
|
1786
1848
|
|
|
1787
|
-
if (typeof
|
|
1788
|
-
return
|
|
1849
|
+
if (typeof value === "string") {
|
|
1850
|
+
return value;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
return (_JSON$stringify = JSON.stringify(value)) != null ? _JSON$stringify : "";
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
const toStringifiedVariables = (acc, key, value) => {
|
|
1857
|
+
if (typeof value === "object" && value !== null) {
|
|
1858
|
+
// If we have an object or array, we build sub-variables so that
|
|
1859
|
+
// the ID is easily human-readable rather than having lots of
|
|
1860
|
+
// extra %-encodings. This means that an object or array variable
|
|
1861
|
+
// turns into x variables, where x is the field or element count of
|
|
1862
|
+
// variable. See below for example.
|
|
1863
|
+
return Object.entries(value).reduce((innerAcc, [i, v]) => {
|
|
1864
|
+
const subKey = `${key}.${i}`;
|
|
1865
|
+
return toStringifiedVariables(innerAcc, subKey, v);
|
|
1866
|
+
}, acc);
|
|
1867
|
+
} else {
|
|
1868
|
+
acc[key] = toString(value);
|
|
1789
1869
|
}
|
|
1790
1870
|
|
|
1791
|
-
return
|
|
1871
|
+
return acc;
|
|
1792
1872
|
};
|
|
1793
1873
|
/**
|
|
1794
1874
|
* Get an identifier for a given request.
|
|
@@ -1809,9 +1889,36 @@ const getGqlRequestId = (operation, variables, context) => {
|
|
|
1809
1889
|
|
|
1810
1890
|
if (variables != null) {
|
|
1811
1891
|
// We need to turn each variable into a string.
|
|
1892
|
+
// We also need to ensure we sort any sub-object keys.
|
|
1893
|
+
// `toStringifiedVariables` helps us with this by hoisting nested
|
|
1894
|
+
// data to individual variables for the purposes of ID generation.
|
|
1895
|
+
//
|
|
1896
|
+
// For example, consider variables:
|
|
1897
|
+
// {x: [1,2,3], y: {a: 1, b: 2, c: 3}, z: 123}
|
|
1898
|
+
//
|
|
1899
|
+
// Each variable, x, y and z, would be stringified into
|
|
1900
|
+
// stringifiedVariables as follows:
|
|
1901
|
+
// x becomes {"x.0": "1", "x.1": "2", "x.2": "3"}
|
|
1902
|
+
// y becomes {"y.a": "1", "y.b": "2", "y.c": "3"}
|
|
1903
|
+
// z becomes {"z": "123"}
|
|
1904
|
+
//
|
|
1905
|
+
// This then leads to stringifiedVariables being:
|
|
1906
|
+
// {
|
|
1907
|
+
// "x.0": "1",
|
|
1908
|
+
// "x.1": "2",
|
|
1909
|
+
// "x.2": "3",
|
|
1910
|
+
// "y.a": "1",
|
|
1911
|
+
// "y.b": "2",
|
|
1912
|
+
// "y.c": "3",
|
|
1913
|
+
// "z": "123",
|
|
1914
|
+
// }
|
|
1915
|
+
//
|
|
1916
|
+
// Thus allowing our use of URLSearchParams to both sort and easily
|
|
1917
|
+
// encode the variables into an idempotent identifier for those
|
|
1918
|
+
// variable values that is also human-readable.
|
|
1812
1919
|
const stringifiedVariables = Object.keys(variables).reduce((acc, key) => {
|
|
1813
|
-
|
|
1814
|
-
return acc;
|
|
1920
|
+
const value = variables[key];
|
|
1921
|
+
return toStringifiedVariables(acc, key, value);
|
|
1815
1922
|
}, {}); // We use the same mechanism as context to sort and arrange the
|
|
1816
1923
|
// variables.
|
|
1817
1924
|
|
|
@@ -1825,12 +1932,12 @@ const getGqlRequestId = (operation, variables, context) => {
|
|
|
1825
1932
|
};
|
|
1826
1933
|
|
|
1827
1934
|
/***/ }),
|
|
1828
|
-
/*
|
|
1935
|
+
/* 30 */
|
|
1829
1936
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1830
1937
|
|
|
1831
1938
|
"use strict";
|
|
1832
1939
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return toGqlOperation; });
|
|
1833
|
-
/* harmony import */ var _graphql_document_node_parser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
1940
|
+
/* harmony import */ var _graphql_document_node_parser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(19);
|
|
1834
1941
|
|
|
1835
1942
|
|
|
1836
1943
|
/**
|
|
@@ -1872,14 +1979,14 @@ const toGqlOperation = documentNode => {
|
|
|
1872
1979
|
};
|
|
1873
1980
|
|
|
1874
1981
|
/***/ }),
|
|
1875
|
-
/*
|
|
1982
|
+
/* 31 */
|
|
1876
1983
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1877
1984
|
|
|
1878
1985
|
"use strict";
|
|
1879
1986
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GqlRouter; });
|
|
1880
1987
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
|
1881
1988
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1882
|
-
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
1989
|
+
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21);
|
|
1883
1990
|
|
|
1884
1991
|
|
|
1885
1992
|
|
|
@@ -1916,16 +2023,16 @@ const GqlRouter = ({
|
|
|
1916
2023
|
};
|
|
1917
2024
|
|
|
1918
2025
|
/***/ }),
|
|
1919
|
-
/*
|
|
2026
|
+
/* 32 */
|
|
1920
2027
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1921
2028
|
|
|
1922
2029
|
"use strict";
|
|
1923
2030
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return useGql; });
|
|
1924
2031
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
|
1925
2032
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1926
|
-
/* harmony import */ var _util_merge_gql_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
1927
|
-
/* harmony import */ var _use_gql_router_context_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
1928
|
-
/* harmony import */ var _util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(
|
|
2033
|
+
/* harmony import */ var _util_merge_gql_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(22);
|
|
2034
|
+
/* harmony import */ var _use_gql_router_context_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34);
|
|
2035
|
+
/* harmony import */ var _util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(18);
|
|
1929
2036
|
|
|
1930
2037
|
|
|
1931
2038
|
|
|
@@ -1966,7 +2073,7 @@ const useGql = (context = {}) => {
|
|
|
1966
2073
|
};
|
|
1967
2074
|
|
|
1968
2075
|
/***/ }),
|
|
1969
|
-
/*
|
|
2076
|
+
/* 33 */
|
|
1970
2077
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1971
2078
|
|
|
1972
2079
|
"use strict";
|
|
@@ -2006,15 +2113,15 @@ const resultFromCachedResponse = cacheEntry => {
|
|
|
2006
2113
|
};
|
|
2007
2114
|
|
|
2008
2115
|
/***/ }),
|
|
2009
|
-
/*
|
|
2116
|
+
/* 34 */
|
|
2010
2117
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
2011
2118
|
|
|
2012
2119
|
"use strict";
|
|
2013
2120
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return useGqlRouterContext; });
|
|
2014
2121
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
|
2015
2122
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
2016
|
-
/* harmony import */ var _util_merge_gql_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
2017
|
-
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
2123
|
+
/* harmony import */ var _util_merge_gql_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(22);
|
|
2124
|
+
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21);
|
|
2018
2125
|
/* harmony import */ var _util_gql_error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
|
|
2019
2126
|
|
|
2020
2127
|
|
|
@@ -2057,76 +2164,6 @@ const useGqlRouterContext = (contextOverrides = {}) => {
|
|
|
2057
2164
|
return finalRouterContext;
|
|
2058
2165
|
};
|
|
2059
2166
|
|
|
2060
|
-
/***/ }),
|
|
2061
|
-
/* 34 */
|
|
2062
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
2063
|
-
|
|
2064
|
-
"use strict";
|
|
2065
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getGqlDataFromResponse; });
|
|
2066
|
-
/* harmony import */ var _data_error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
2067
|
-
/* harmony import */ var _gql_error_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
/**
|
|
2071
|
-
* Validate a GQL operation response and extract the data.
|
|
2072
|
-
*/
|
|
2073
|
-
|
|
2074
|
-
const getGqlDataFromResponse = async response => {
|
|
2075
|
-
// Get the response as text, that way we can use the text in error
|
|
2076
|
-
// messaging, should our parsing fail.
|
|
2077
|
-
const bodyText = await response.text();
|
|
2078
|
-
let result;
|
|
2079
|
-
|
|
2080
|
-
try {
|
|
2081
|
-
result = JSON.parse(bodyText);
|
|
2082
|
-
} catch (e) {
|
|
2083
|
-
throw new _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataError */ "a"]("Failed to parse response", _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataErrors */ "b"].Parse, {
|
|
2084
|
-
metadata: {
|
|
2085
|
-
statusCode: response.status,
|
|
2086
|
-
bodyText
|
|
2087
|
-
},
|
|
2088
|
-
cause: e
|
|
2089
|
-
});
|
|
2090
|
-
} // Check for a bad status code.
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
if (response.status >= 300) {
|
|
2094
|
-
throw new _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataError */ "a"]("Response unsuccessful", _data_error_js__WEBPACK_IMPORTED_MODULE_0__[/* DataErrors */ "b"].Network, {
|
|
2095
|
-
metadata: {
|
|
2096
|
-
statusCode: response.status,
|
|
2097
|
-
result
|
|
2098
|
-
}
|
|
2099
|
-
});
|
|
2100
|
-
} // Check that we have a valid result payload.
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
if ( // Flow shouldn't be warning about this.
|
|
2104
|
-
// $FlowIgnore[method-unbinding]
|
|
2105
|
-
!Object.prototype.hasOwnProperty.call(result, "data") && // Flow shouldn't be warning about this.
|
|
2106
|
-
// $FlowIgnore[method-unbinding]
|
|
2107
|
-
!Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
2108
|
-
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlError */ "a"]("Server response missing", _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlErrors */ "b"].BadResponse, {
|
|
2109
|
-
metadata: {
|
|
2110
|
-
statusCode: response.status,
|
|
2111
|
-
result
|
|
2112
|
-
}
|
|
2113
|
-
});
|
|
2114
|
-
} // If the response payload has errors, throw an error.
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
2118
|
-
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlError */ "a"]("GraphQL errors", _gql_error_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlErrors */ "b"].ErrorResult, {
|
|
2119
|
-
metadata: {
|
|
2120
|
-
statusCode: response.status,
|
|
2121
|
-
result
|
|
2122
|
-
}
|
|
2123
|
-
});
|
|
2124
|
-
} // We got here, so return the data.
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
return result.data;
|
|
2128
|
-
};
|
|
2129
|
-
|
|
2130
2167
|
/***/ }),
|
|
2131
2168
|
/* 35 */
|
|
2132
2169
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
@@ -2141,23 +2178,23 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2141
2178
|
|
|
2142
2179
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "purgeHydrationCache", function() { return _util_hydration_cache_api_js__WEBPACK_IMPORTED_MODULE_1__["b"]; });
|
|
2143
2180
|
|
|
2144
|
-
/* harmony import */ var _util_request_api_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
2181
|
+
/* harmony import */ var _util_request_api_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(24);
|
|
2145
2182
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fetchTrackedRequests", function() { return _util_request_api_js__WEBPACK_IMPORTED_MODULE_2__["b"]; });
|
|
2146
2183
|
|
|
2147
2184
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "hasTrackedRequestsToBeFetched", function() { return _util_request_api_js__WEBPACK_IMPORTED_MODULE_2__["c"]; });
|
|
2148
2185
|
|
|
2149
2186
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "abortInflightRequests", function() { return _util_request_api_js__WEBPACK_IMPORTED_MODULE_2__["a"]; });
|
|
2150
2187
|
|
|
2151
|
-
/* harmony import */ var _util_purge_caches_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(
|
|
2188
|
+
/* harmony import */ var _util_purge_caches_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25);
|
|
2152
2189
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "purgeCaches", function() { return _util_purge_caches_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
|
|
2153
2190
|
|
|
2154
|
-
/* harmony import */ var _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(
|
|
2191
|
+
/* harmony import */ var _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26);
|
|
2155
2192
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrackData", function() { return _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
|
|
2156
2193
|
|
|
2157
|
-
/* harmony import */ var _components_data_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(
|
|
2194
|
+
/* harmony import */ var _components_data_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(27);
|
|
2158
2195
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Data", function() { return _components_data_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
|
|
2159
2196
|
|
|
2160
|
-
/* harmony import */ var _components_intercept_requests_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(
|
|
2197
|
+
/* harmony import */ var _components_intercept_requests_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28);
|
|
2161
2198
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InterceptRequests", function() { return _components_intercept_requests_js__WEBPACK_IMPORTED_MODULE_6__["a"]; });
|
|
2162
2199
|
|
|
2163
2200
|
/* harmony import */ var _util_data_error_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(0);
|
|
@@ -2174,7 +2211,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2174
2211
|
/* harmony import */ var _hooks_use_shared_cache_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5);
|
|
2175
2212
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useSharedCache", function() { return _hooks_use_shared_cache_js__WEBPACK_IMPORTED_MODULE_10__["b"]; });
|
|
2176
2213
|
|
|
2177
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2214
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SharedCache", function() { return _hooks_use_shared_cache_js__WEBPACK_IMPORTED_MODULE_10__["a"]; });
|
|
2178
2215
|
|
|
2179
2216
|
/* harmony import */ var _hooks_use_hydratable_effect_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(12);
|
|
2180
2217
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useHydratableEffect", function() { return _hooks_use_hydratable_effect_js__WEBPACK_IMPORTED_MODULE_11__["b"]; });
|
|
@@ -2190,25 +2227,28 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2190
2227
|
/* harmony import */ var _util_status_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(6);
|
|
2191
2228
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Status", function() { return _util_status_js__WEBPACK_IMPORTED_MODULE_14__["a"]; });
|
|
2192
2229
|
|
|
2193
|
-
/* harmony import */ var _util_get_gql_request_id_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(
|
|
2230
|
+
/* harmony import */ var _util_get_gql_request_id_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(29);
|
|
2194
2231
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getGqlRequestId", function() { return _util_get_gql_request_id_js__WEBPACK_IMPORTED_MODULE_15__["a"]; });
|
|
2195
2232
|
|
|
2196
|
-
/* harmony import */ var
|
|
2197
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2233
|
+
/* harmony import */ var _util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(18);
|
|
2234
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getGqlDataFromResponse", function() { return _util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_16__["a"]; });
|
|
2198
2235
|
|
|
2199
|
-
/* harmony import */ var
|
|
2200
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2236
|
+
/* harmony import */ var _util_graphql_document_node_parser_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(19);
|
|
2237
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "graphQLDocumentNodeParser", function() { return _util_graphql_document_node_parser_js__WEBPACK_IMPORTED_MODULE_17__["a"]; });
|
|
2201
2238
|
|
|
2202
|
-
/* harmony import */ var
|
|
2203
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2239
|
+
/* harmony import */ var _util_to_gql_operation_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(30);
|
|
2240
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toGqlOperation", function() { return _util_to_gql_operation_js__WEBPACK_IMPORTED_MODULE_18__["a"]; });
|
|
2204
2241
|
|
|
2205
|
-
/* harmony import */ var
|
|
2206
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2242
|
+
/* harmony import */ var _components_gql_router_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(31);
|
|
2243
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlRouter", function() { return _components_gql_router_js__WEBPACK_IMPORTED_MODULE_19__["a"]; });
|
|
2207
2244
|
|
|
2208
|
-
/* harmony import */ var
|
|
2209
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
2245
|
+
/* harmony import */ var _hooks_use_gql_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(32);
|
|
2246
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useGql", function() { return _hooks_use_gql_js__WEBPACK_IMPORTED_MODULE_20__["a"]; });
|
|
2210
2247
|
|
|
2211
|
-
/* harmony
|
|
2248
|
+
/* harmony import */ var _util_gql_error_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(4);
|
|
2249
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlError", function() { return _util_gql_error_js__WEBPACK_IMPORTED_MODULE_21__["a"]; });
|
|
2250
|
+
|
|
2251
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlErrors", function() { return _util_gql_error_js__WEBPACK_IMPORTED_MODULE_21__["b"]; });
|
|
2212
2252
|
|
|
2213
2253
|
// TODO(somewhatabstract, FEI-4174): Update eslint-plugin-import when they
|
|
2214
2254
|
// have fixed:
|
|
@@ -2239,5 +2279,6 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2239
2279
|
|
|
2240
2280
|
|
|
2241
2281
|
|
|
2282
|
+
|
|
2242
2283
|
/***/ })
|
|
2243
2284
|
/******/ ]);
|
package/package.json
CHANGED
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
TrackData,
|
|
87
87
|
hasTrackedRequestsToBeFetched,
|
|
88
88
|
fetchTrackedRequests,
|
|
89
|
-
|
|
89
|
+
SharedCache,
|
|
90
90
|
} from "@khanacademy/wonder-blocks-data";
|
|
91
91
|
|
|
92
92
|
// Don't forget to import your app!
|
|
@@ -113,7 +113,7 @@ async function renderApp(): Promise<string> {
|
|
|
113
113
|
* shared cache used by the `useSharedCache` hook as this is transient
|
|
114
114
|
* cache that does not itself get directly hydrated.
|
|
115
115
|
*/
|
|
116
|
-
|
|
116
|
+
SharedCache.purgeAll();
|
|
117
117
|
|
|
118
118
|
// Render the tracked component.
|
|
119
119
|
renderedComponent = renderToString(trackedElement);
|
|
@@ -20,4 +20,4 @@ The `purgeCaches` method will purge the following caches managed by Wonder Block
|
|
|
20
20
|
- Shared in-memory cache as used by [`useSharedCache`](/docs/data-exports-usesharedcache--page) and other hooks
|
|
21
21
|
- Hydration cache as used during server-side rendering
|
|
22
22
|
|
|
23
|
-
This is equivalent to calling both `
|
|
23
|
+
This is equivalent to calling both `SharedCache.purgeAll()` and `purgeHydrationCache()`, and is especially useful when writing tests or setting up a test environment.
|
|
@@ -11,12 +11,12 @@ import {Meta} from "@storybook/addon-docs";
|
|
|
11
11
|
|
|
12
12
|
# ScopedInMemoryCache
|
|
13
13
|
|
|
14
|
-
This class implements an in-memory cache that can contain different scopes of cached data. This allows for quick removal of entire classes of data as identified by their scopes without having to iterate each cached item to find them.
|
|
14
|
+
This class implements an in-memory cache that can contain different scopes of cached data. This allows for quick removal of entire classes of data as identified by their scopes without having to iterate each cached item to find them. It implements the [`ScopedCache`](/docs/data-types-scopedcache--page) interface.
|
|
15
15
|
|
|
16
16
|
## constructor()
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
|
-
new ScopedInMemoryCache(initialCache?:
|
|
19
|
+
new ScopedInMemoryCache(initialCache?: RawScopedCache)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Creates a new instance. An initial state for the cache can be provided.
|
|
@@ -34,7 +34,7 @@ Is `true` if the cache contains any data; otherwise, `false`.
|
|
|
34
34
|
## set()
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
|
-
set
|
|
37
|
+
set(
|
|
38
38
|
scope: string,
|
|
39
39
|
id: string,
|
|
40
40
|
value: TValue,
|
|
@@ -16,7 +16,7 @@ This class is a specialization of [`ScopedInMemoryCache`](/docs/data-exports-sco
|
|
|
16
16
|
## constructor()
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
|
-
new SerializableInMemoryCache(initialCache?:
|
|
19
|
+
new SerializableInMemoryCache(initialCache?: RawScopedCache)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Creates a new instance. The `initialCache`, if provided, will be cloned and used as the initial state of the cache.
|
|
@@ -67,7 +67,7 @@ Gets a value from the cache. If a value with the given identifier (`id`) is not
|
|
|
67
67
|
## clone()
|
|
68
68
|
|
|
69
69
|
```ts
|
|
70
|
-
clone():
|
|
70
|
+
clone(): RawScopedCache;
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Returns a clone of the current cache.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {Meta} from "@storybook/addon-docs";
|
|
2
|
+
|
|
3
|
+
<Meta
|
|
4
|
+
title="Data / Exports / SharedCache"
|
|
5
|
+
parameters={{
|
|
6
|
+
chromatic: {
|
|
7
|
+
disableSnapshot: true,
|
|
8
|
+
},
|
|
9
|
+
}}
|
|
10
|
+
/>
|
|
11
|
+
|
|
12
|
+
# SharedCache
|
|
13
|
+
|
|
14
|
+
The `SharedCache` export can be used to view and modify the in-memory cache used by [`useSharedCache`](/docs/data-exports-usesharedcache--page) hook and the hooks and components that relate to it.
|
|
15
|
+
|
|
16
|
+
The `SharedCache` export implements the [`ScopedCache` interface type](/docs/data-types-scopedcache--page).
|