@khanacademy/wonder-blocks-data 2.3.3 → 3.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 +21 -0
- package/dist/es/index.js +365 -429
- package/dist/index.js +455 -461
- package/docs.md +19 -13
- package/package.json +6 -6
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +40 -160
- package/src/__tests__/generated-snapshot.test.js +15 -195
- package/src/components/__tests__/data.test.js +159 -965
- package/src/components/__tests__/gql-router.test.js +64 -0
- package/src/components/__tests__/intercept-data.test.js +9 -66
- package/src/components/__tests__/track-data.test.js +6 -5
- package/src/components/data.js +9 -119
- package/src/components/data.md +38 -60
- package/src/components/gql-router.js +66 -0
- package/src/components/intercept-context.js +2 -3
- package/src/components/intercept-data.js +2 -34
- package/src/components/intercept-data.md +7 -105
- package/src/hooks/__tests__/use-data.test.js +826 -0
- package/src/hooks/__tests__/use-gql.test.js +233 -0
- package/src/hooks/use-data.js +143 -0
- package/src/hooks/use-gql.js +75 -0
- package/src/index.js +7 -9
- package/src/util/__tests__/get-gql-data-from-response.test.js +187 -0
- package/src/util/__tests__/memory-cache.test.js +134 -35
- package/src/util/__tests__/request-fulfillment.test.js +21 -36
- package/src/util/__tests__/request-handler.test.js +30 -30
- package/src/util/__tests__/request-tracking.test.js +29 -30
- package/src/util/__tests__/response-cache.test.js +521 -561
- package/src/util/__tests__/result-from-cache-entry.test.js +68 -0
- package/src/util/get-gql-data-from-response.js +69 -0
- package/src/util/gql-error.js +36 -0
- package/src/util/gql-router-context.js +6 -0
- package/src/util/gql-types.js +60 -0
- package/src/util/memory-cache.js +20 -15
- package/src/util/request-fulfillment.js +4 -0
- package/src/util/request-handler.js +4 -28
- package/src/util/request-handler.md +0 -32
- package/src/util/request-tracking.js +2 -3
- package/src/util/response-cache.js +50 -110
- package/src/util/result-from-cache-entry.js +38 -0
- package/src/util/types.js +14 -35
- package/LICENSE +0 -21
- package/src/components/__tests__/intercept-cache.test.js +0 -124
- package/src/components/__tests__/internal-data.test.js +0 -1030
- package/src/components/intercept-cache.js +0 -79
- package/src/components/intercept-cache.md +0 -103
- package/src/components/internal-data.js +0 -219
- package/src/util/__tests__/no-cache.test.js +0 -112
- package/src/util/no-cache.js +0 -66
- package/src/util/no-cache.md +0 -66
package/dist/index.js
CHANGED
|
@@ -82,7 +82,7 @@ module.exports =
|
|
|
82
82
|
/******/
|
|
83
83
|
/******/
|
|
84
84
|
/******/ // Load entry module and return exports
|
|
85
|
-
/******/ return __webpack_require__(__webpack_require__.s =
|
|
85
|
+
/******/ return __webpack_require__(__webpack_require__.s = 19);
|
|
86
86
|
/******/ })
|
|
87
87
|
/************************************************************************/
|
|
88
88
|
/******/ ([
|
|
@@ -95,13 +95,55 @@ module.exports = require("react");
|
|
|
95
95
|
/* 1 */
|
|
96
96
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
97
97
|
|
|
98
|
+
"use strict";
|
|
99
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return GqlErrors; });
|
|
100
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GqlError; });
|
|
101
|
+
/* harmony import */ var _khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
|
|
102
|
+
/* harmony import */ var _khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0__);
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Error kinds for GqlError.
|
|
107
|
+
*/
|
|
108
|
+
const GqlErrors = Object.freeze({ ..._khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0__["Errors"],
|
|
109
|
+
Network: "Network",
|
|
110
|
+
Parse: "Parse",
|
|
111
|
+
BadResponse: "BadResponse",
|
|
112
|
+
ErrorResult: "ErrorResult"
|
|
113
|
+
});
|
|
114
|
+
/**
|
|
115
|
+
* An error from the GQL API.
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
class GqlError extends _khanacademy_wonder_stuff_core__WEBPACK_IMPORTED_MODULE_0__["KindError"] {
|
|
119
|
+
constructor(message, kind, {
|
|
120
|
+
metadata,
|
|
121
|
+
cause
|
|
122
|
+
} = {}) {
|
|
123
|
+
super(message, kind, {
|
|
124
|
+
metadata,
|
|
125
|
+
cause,
|
|
126
|
+
prefix: "Gql"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/***/ }),
|
|
133
|
+
/* 2 */
|
|
134
|
+
/***/ (function(module, exports) {
|
|
135
|
+
|
|
136
|
+
module.exports = require("@khanacademy/wonder-blocks-core");
|
|
137
|
+
|
|
138
|
+
/***/ }),
|
|
139
|
+
/* 3 */
|
|
140
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
141
|
+
|
|
98
142
|
"use strict";
|
|
99
143
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ResponseCache; });
|
|
100
144
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
|
101
145
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__);
|
|
102
|
-
/* harmony import */ var _memory_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
103
|
-
/* harmony import */ var _no_cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
|
104
|
-
|
|
146
|
+
/* harmony import */ var _memory_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9);
|
|
105
147
|
|
|
106
148
|
|
|
107
149
|
|
|
@@ -126,24 +168,22 @@ class ResponseCache {
|
|
|
126
168
|
return _default;
|
|
127
169
|
}
|
|
128
170
|
|
|
129
|
-
constructor(
|
|
171
|
+
constructor(hydrationCache = null, ssrOnlyCache = null) {
|
|
130
172
|
this.initialize = source => {
|
|
131
|
-
if (this.
|
|
173
|
+
if (this._hydrationCache.inUse) {
|
|
132
174
|
throw new Error("Cannot initialize data response cache more than once");
|
|
133
175
|
}
|
|
134
176
|
|
|
135
177
|
try {
|
|
136
|
-
this.
|
|
178
|
+
this._hydrationCache = new _memory_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"](source);
|
|
137
179
|
} catch (e) {
|
|
138
180
|
throw new Error(`An error occurred trying to initialize the data response cache: ${e}`);
|
|
139
181
|
}
|
|
140
182
|
};
|
|
141
183
|
|
|
142
|
-
this.cacheData = (handler, options, data) => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
});
|
|
146
|
-
};
|
|
184
|
+
this.cacheData = (handler, options, data) => this._setCacheEntry(handler, options, {
|
|
185
|
+
data
|
|
186
|
+
});
|
|
147
187
|
|
|
148
188
|
this.cacheError = (handler, options, error) => {
|
|
149
189
|
const errorMessage = typeof error === "string" ? error : error.message;
|
|
@@ -153,110 +193,64 @@ class ResponseCache {
|
|
|
153
193
|
};
|
|
154
194
|
|
|
155
195
|
this.getEntry = (handler, options) => {
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// This allows us to use our hydrated cache during hydration.
|
|
167
|
-
// If we just returned null when the custom cache didn't have it,
|
|
168
|
-
// we would never hydrate properly.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const internalEntry = this._defaultCache(handler).retrieve(handler, options); // If we are not server-side and we hydrated something that the custom
|
|
172
|
-
// cache didn't have, we need to make sure the custom cache contains
|
|
173
|
-
// that value.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (this._ssrOnlyCache == null && handler.cache != null && internalEntry != null) {
|
|
177
|
-
// Yes, if this throws, we will have a problem. We want that.
|
|
178
|
-
// Bad cache implementations should be overt.
|
|
179
|
-
handler.cache.store(handler, options, internalEntry); // We now delete this from our in-memory cache as we don't need it.
|
|
196
|
+
// Get the cached entry for this value.
|
|
197
|
+
// If the handler wants WB Data to hydrate (i.e. handler.hydrate is
|
|
198
|
+
// true), we use our hydration cache. Otherwise, if we're server-side
|
|
199
|
+
// we use our SSR-only cache. Otherwise, there's no entry to return.
|
|
200
|
+
const cache = handler.hydrate ? this._hydrationCache : _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__["Server"].isServerSide() ? this._ssrOnlyCache : undefined;
|
|
201
|
+
const internalEntry = cache == null ? void 0 : cache.retrieve(handler, options); // If we are not server-side and we hydrated something, let's clear
|
|
202
|
+
// that from the hydration cache to save memory.
|
|
203
|
+
|
|
204
|
+
if (this._ssrOnlyCache == null && internalEntry != null) {
|
|
205
|
+
// We now delete this from our hydration cache as we don't need it.
|
|
180
206
|
// This does mean that if another handler of the same type but
|
|
181
|
-
// without
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
this.
|
|
207
|
+
// without some sort of linked cache won't get the value, but
|
|
208
|
+
// that's not an expected use-case. If two different places use the
|
|
209
|
+
// same handler and options (i.e. the same request), then the
|
|
210
|
+
// handler should cater to that to ensure they share the result.
|
|
211
|
+
this._hydrationCache.remove(handler, options);
|
|
186
212
|
}
|
|
187
213
|
|
|
188
214
|
return internalEntry;
|
|
189
215
|
};
|
|
190
216
|
|
|
191
217
|
this.remove = (handler, options) => {
|
|
218
|
+
var _this$_ssrOnlyCache$r, _this$_ssrOnlyCache;
|
|
219
|
+
|
|
192
220
|
// NOTE(somewhatabstract): We could invoke removeAll with a predicate
|
|
193
221
|
// to match the key of the entry we're removing, but that's an
|
|
194
222
|
// inefficient way to remove a single item, so let's not do that.
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
const customCache = this._ssrOnlyCache == null ? handler.cache : null;
|
|
198
|
-
const removedCustom = !!(customCache != null && customCache.remove(handler, options)); // Delete the entry from our internal cache.
|
|
199
|
-
// Even if we have a custom cache, we want to make sure we still
|
|
200
|
-
// removed the same value from internal cache since this could be
|
|
201
|
-
// getting called before hydration for some complex advanced usage
|
|
202
|
-
// reason.
|
|
203
|
-
|
|
204
|
-
return this._defaultCache(handler).remove(handler, options) || removedCustom;
|
|
223
|
+
// Delete the entry from the appropriate cache.
|
|
224
|
+
return handler.hydrate ? this._hydrationCache.remove(handler, options) : (_this$_ssrOnlyCache$r = (_this$_ssrOnlyCache = this._ssrOnlyCache) == null ? void 0 : _this$_ssrOnlyCache.remove(handler, options)) != null ? _this$_ssrOnlyCache$r : false;
|
|
205
225
|
};
|
|
206
226
|
|
|
207
227
|
this.removeAll = (handler, predicate) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
// Even if we have a custom cache, we want to make sure we still
|
|
213
|
-
// removed the same value from internal cache since this could be
|
|
214
|
-
// getting called before hydration for some complex advanced usage
|
|
215
|
-
// reason.
|
|
216
|
-
|
|
217
|
-
const removedCount = this._defaultCache(handler).removeAll(handler, predicate); // We have no idea which keys were removed from which caches,
|
|
218
|
-
// so we can't dedupe the remove counts based on keys.
|
|
219
|
-
// That's why we return the total records deleted rather than the
|
|
220
|
-
// total keys deleted.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return removedCount + removedCountCustom;
|
|
228
|
+
var _this$_ssrOnlyCache$r2, _this$_ssrOnlyCache2;
|
|
229
|
+
|
|
230
|
+
// Apply the predicate to what we have in the appropriate cache.
|
|
231
|
+
return handler.hydrate ? this._hydrationCache.removeAll(handler, predicate) : (_this$_ssrOnlyCache$r2 = (_this$_ssrOnlyCache2 = this._ssrOnlyCache) == null ? void 0 : _this$_ssrOnlyCache2.removeAll(handler, predicate)) != null ? _this$_ssrOnlyCache$r2 : 0;
|
|
224
232
|
};
|
|
225
233
|
|
|
226
234
|
this.cloneHydratableData = () => {
|
|
227
235
|
// We return our hydration cache only.
|
|
228
|
-
return this.
|
|
236
|
+
return this._hydrationCache.cloneData();
|
|
229
237
|
};
|
|
230
238
|
|
|
231
239
|
this._ssrOnlyCache = _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__["Server"].isServerSide() ? ssrOnlyCache || new _memory_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"]() : undefined;
|
|
232
|
-
this.
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Returns the default cache to use for the given handler.
|
|
236
|
-
*/
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
_defaultCache(handler) {
|
|
240
|
-
if (handler.hydrate) {
|
|
241
|
-
return this._hydrationAndDefaultCache;
|
|
242
|
-
} // If the handler doesn't want to hydrate, we return the SSR-only cache.
|
|
243
|
-
// If we are client-side, we return our non-caching implementation.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return this._ssrOnlyCache || _no_cache_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ "a"].Default;
|
|
240
|
+
this._hydrationCache = hydrationCache || new _memory_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"]();
|
|
247
241
|
}
|
|
248
242
|
|
|
249
243
|
_setCacheEntry(handler, options, entry) {
|
|
250
244
|
const frozenEntry = Object.freeze(entry);
|
|
251
245
|
|
|
252
|
-
if (this._ssrOnlyCache
|
|
253
|
-
// We are
|
|
254
|
-
//
|
|
255
|
-
handler.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
246
|
+
if (this._ssrOnlyCache != null) {
|
|
247
|
+
// We are server-side.
|
|
248
|
+
// We need to store this value.
|
|
249
|
+
if (handler.hydrate) {
|
|
250
|
+
this._hydrationCache.store(handler, options, frozenEntry);
|
|
251
|
+
} else {
|
|
252
|
+
this._ssrOnlyCache.store(handler, options, frozenEntry);
|
|
253
|
+
}
|
|
260
254
|
}
|
|
261
255
|
|
|
262
256
|
return frozenEntry;
|
|
@@ -271,13 +265,7 @@ class ResponseCache {
|
|
|
271
265
|
}
|
|
272
266
|
|
|
273
267
|
/***/ }),
|
|
274
|
-
/*
|
|
275
|
-
/***/ (function(module, exports) {
|
|
276
|
-
|
|
277
|
-
module.exports = require("@khanacademy/wonder-blocks-core");
|
|
278
|
-
|
|
279
|
-
/***/ }),
|
|
280
|
-
/* 3 */
|
|
268
|
+
/* 4 */
|
|
281
269
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
282
270
|
|
|
283
271
|
"use strict";
|
|
@@ -285,8 +273,8 @@ module.exports = require("@khanacademy/wonder-blocks-core");
|
|
|
285
273
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return RequestTracker; });
|
|
286
274
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
287
275
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
288
|
-
/* harmony import */ var _response_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
289
|
-
/* harmony import */ var _request_fulfillment_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
276
|
+
/* harmony import */ var _response_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
277
|
+
/* harmony import */ var _request_fulfillment_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
|
|
290
278
|
|
|
291
279
|
|
|
292
280
|
|
|
@@ -429,7 +417,7 @@ class RequestTracker {
|
|
|
429
417
|
}
|
|
430
418
|
|
|
431
419
|
/***/ }),
|
|
432
|
-
/*
|
|
420
|
+
/* 5 */
|
|
433
421
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
434
422
|
|
|
435
423
|
"use strict";
|
|
@@ -446,54 +434,150 @@ const InterceptContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["create
|
|
|
446
434
|
/* harmony default export */ __webpack_exports__["a"] = (InterceptContext);
|
|
447
435
|
|
|
448
436
|
/***/ }),
|
|
449
|
-
/*
|
|
437
|
+
/* 6 */
|
|
450
438
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
451
439
|
|
|
452
440
|
"use strict";
|
|
453
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
* handler as this ensures that cache space and memory are never used for the
|
|
464
|
-
* requested data after hydration has finished.
|
|
465
|
-
*/
|
|
441
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return useData; });
|
|
442
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
|
443
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__);
|
|
444
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
|
|
445
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
|
|
446
|
+
/* harmony import */ var _util_request_fulfillment_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
|
|
447
|
+
/* harmony import */ var _components_intercept_context_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
|
|
448
|
+
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4);
|
|
449
|
+
/* harmony import */ var _util_result_from_cache_entry_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(17);
|
|
450
|
+
/* harmony import */ var _util_response_cache_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3);
|
|
466
451
|
|
|
467
|
-
class NoCache {
|
|
468
|
-
constructor() {
|
|
469
|
-
this.store = (handler, options, entry) => {
|
|
470
|
-
/* empty */
|
|
471
|
-
};
|
|
472
452
|
|
|
473
|
-
this.retrieve = (handler, options) => null;
|
|
474
453
|
|
|
475
|
-
this.remove = (handler, options) => false;
|
|
476
454
|
|
|
477
|
-
this.removeAll = (handler, predicate) => 0;
|
|
478
|
-
}
|
|
479
455
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
const useData = (handler, options) => {
|
|
459
|
+
// If we're server-side or hydrating, we'll have a cached entry to use.
|
|
460
|
+
// So we get that and use it to initialize our state.
|
|
461
|
+
// This works in both hydration and SSR because the very first call to
|
|
462
|
+
// this will have cached data in those cases as it will be present on the
|
|
463
|
+
// initial render - and subsequent renders on the client it will be null.
|
|
464
|
+
const cachedResult = _util_response_cache_js__WEBPACK_IMPORTED_MODULE_6__[/* ResponseCache */ "a"].Default.getEntry(handler, options);
|
|
465
|
+
const [result, setResult] = Object(react__WEBPACK_IMPORTED_MODULE_1__["useState"])(cachedResult); // Lookup to see if there's an interceptor for the handler.
|
|
466
|
+
// If we have one, we need to replace the handler with one that
|
|
467
|
+
// uses the interceptor.
|
|
468
|
+
|
|
469
|
+
const interceptorMap = Object(react__WEBPACK_IMPORTED_MODULE_1__["useContext"])(_components_intercept_context_js__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"]);
|
|
470
|
+
const interceptor = interceptorMap[handler.type]; // If we have an interceptor, we need to replace the handler with one that
|
|
471
|
+
// uses the interceptor. This helper function generates a new handler.
|
|
472
|
+
// We need this before we track the request as we want the interceptor
|
|
473
|
+
// to also work for tracked requests to simplify testing the server-side
|
|
474
|
+
// request fulfillment.
|
|
475
|
+
|
|
476
|
+
const getMaybeInterceptedHandler = () => {
|
|
477
|
+
if (interceptor == null) {
|
|
478
|
+
return handler;
|
|
483
479
|
}
|
|
484
480
|
|
|
485
|
-
|
|
486
|
-
|
|
481
|
+
const fulfillRequestFn = options => {
|
|
482
|
+
var _interceptor$fulfillR;
|
|
487
483
|
|
|
488
|
-
|
|
484
|
+
return (_interceptor$fulfillR = interceptor.fulfillRequest(options)) != null ? _interceptor$fulfillR : handler.fulfillRequest(options);
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
return {
|
|
488
|
+
fulfillRequest: fulfillRequestFn,
|
|
489
|
+
getKey: options => handler.getKey(options),
|
|
490
|
+
type: handler.type,
|
|
491
|
+
hydrate: handler.hydrate
|
|
492
|
+
};
|
|
493
|
+
}; // We only track data requests when we are server-side and we don't
|
|
494
|
+
// already have a result, as given by the cachedData (which is also the
|
|
495
|
+
// initial value for the result state).
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
const maybeTrack = Object(react__WEBPACK_IMPORTED_MODULE_1__["useContext"])(_util_request_tracking_js__WEBPACK_IMPORTED_MODULE_4__[/* TrackerContext */ "b"]);
|
|
499
|
+
|
|
500
|
+
if (result == null && _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__["Server"].isServerSide()) {
|
|
501
|
+
maybeTrack == null ? void 0 : maybeTrack(getMaybeInterceptedHandler(), options);
|
|
502
|
+
} // We need to update our request when the handler changes or the key
|
|
503
|
+
// to the options change, so we keep track of those.
|
|
504
|
+
// However, even if we are hydrating from cache, we still need to make the
|
|
505
|
+
// request at least once, so we do not initialize these references.
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
const handlerRef = Object(react__WEBPACK_IMPORTED_MODULE_1__["useRef"])();
|
|
509
|
+
const keyRef = Object(react__WEBPACK_IMPORTED_MODULE_1__["useRef"])();
|
|
510
|
+
const interceptorRef = Object(react__WEBPACK_IMPORTED_MODULE_1__["useRef"])(); // This effect will ensure that we fulfill the request as desired.
|
|
511
|
+
|
|
512
|
+
Object(react__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(() => {
|
|
513
|
+
// If we are server-side, then just skip the effect. We track requests
|
|
514
|
+
// during SSR and fulfill them outside of the React render cycle.
|
|
515
|
+
// NOTE: This shouldn't happen since effects would not run on the server
|
|
516
|
+
// but let's be defensive - I think it makes the code clearer.
|
|
517
|
+
|
|
518
|
+
/* istanbul ignore next */
|
|
519
|
+
if (_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__["Server"].isServerSide()) {
|
|
520
|
+
return;
|
|
521
|
+
} // Update our refs to the current handler and key.
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
handlerRef.current = handler;
|
|
525
|
+
keyRef.current = handler.getKey(options);
|
|
526
|
+
interceptorRef.current = interceptor; // If we're not hydrating a result, we want to make sure we set our
|
|
527
|
+
// result to null so that we're in the loading state.
|
|
528
|
+
|
|
529
|
+
if (cachedResult == null) {
|
|
530
|
+
// Mark ourselves as loading.
|
|
531
|
+
setResult(null);
|
|
532
|
+
} // We aren't server-side, so let's make the request.
|
|
533
|
+
// The request handler is in control of whether that request actually
|
|
534
|
+
// happens or not.
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
let cancel = false;
|
|
538
|
+
_util_request_fulfillment_js__WEBPACK_IMPORTED_MODULE_2__[/* RequestFulfillment */ "a"].Default.fulfill(getMaybeInterceptedHandler(), options).then(updateEntry => {
|
|
539
|
+
if (cancel) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
setResult(updateEntry);
|
|
544
|
+
return;
|
|
545
|
+
}).catch(e => {
|
|
546
|
+
if (cancel) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* We should never get here as errors in fulfillment are part
|
|
551
|
+
* of the `then`, but if we do.
|
|
552
|
+
*/
|
|
553
|
+
// eslint-disable-next-line no-console
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
console.error(`Unexpected error occurred during data fulfillment: ${e}`);
|
|
557
|
+
setResult({
|
|
558
|
+
data: null,
|
|
559
|
+
error: typeof e === "string" ? e : e.message
|
|
560
|
+
});
|
|
561
|
+
return;
|
|
562
|
+
});
|
|
563
|
+
return () => {
|
|
564
|
+
cancel = true;
|
|
565
|
+
}; // - handler.getKey is a proxy for options
|
|
566
|
+
// - We don't want to trigger on cachedResult changing, we're
|
|
567
|
+
// just using that as a flag for render state if the other things
|
|
568
|
+
// trigger this effect.
|
|
569
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
570
|
+
}, [handler, handler.getKey(options), interceptor]);
|
|
571
|
+
return Object(_util_result_from_cache_entry_js__WEBPACK_IMPORTED_MODULE_5__[/* resultFromCacheEntry */ "a"])(result);
|
|
572
|
+
};
|
|
489
573
|
|
|
490
574
|
/***/ }),
|
|
491
|
-
/*
|
|
575
|
+
/* 7 */
|
|
492
576
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
493
577
|
|
|
494
578
|
"use strict";
|
|
495
579
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return RequestFulfillment; });
|
|
496
|
-
/* harmony import */ var _response_cache_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
580
|
+
/* harmony import */ var _response_cache_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
|
|
497
581
|
|
|
498
582
|
|
|
499
583
|
let _default;
|
|
@@ -546,6 +630,8 @@ class RequestFulfillment {
|
|
|
546
630
|
delete handlerRequests[key];
|
|
547
631
|
/**
|
|
548
632
|
* Let's cache the data!
|
|
633
|
+
*
|
|
634
|
+
* NOTE: This only caches when we're server side.
|
|
549
635
|
*/
|
|
550
636
|
|
|
551
637
|
return cacheData(handler, options, data);
|
|
@@ -553,6 +639,8 @@ class RequestFulfillment {
|
|
|
553
639
|
delete handlerRequests[key];
|
|
554
640
|
/**
|
|
555
641
|
* Let's cache the error!
|
|
642
|
+
*
|
|
643
|
+
* NOTE: This only caches when we're server side.
|
|
556
644
|
*/
|
|
557
645
|
|
|
558
646
|
return cacheError(handler, options, error);
|
|
@@ -574,7 +662,18 @@ class RequestFulfillment {
|
|
|
574
662
|
}
|
|
575
663
|
|
|
576
664
|
/***/ }),
|
|
577
|
-
/*
|
|
665
|
+
/* 8 */
|
|
666
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
667
|
+
|
|
668
|
+
"use strict";
|
|
669
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GqlRouterContext; });
|
|
670
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
671
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
672
|
+
|
|
673
|
+
const GqlRouterContext = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createContext"](null);
|
|
674
|
+
|
|
675
|
+
/***/ }),
|
|
676
|
+
/* 9 */
|
|
578
677
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
579
678
|
|
|
580
679
|
"use strict";
|
|
@@ -596,9 +695,7 @@ function deepClone(source) {
|
|
|
596
695
|
*
|
|
597
696
|
* Special case cache implementation for the memory cache.
|
|
598
697
|
*
|
|
599
|
-
* This is only used within our framework
|
|
600
|
-
* provide this as a custom cache as the framework will default to this in the
|
|
601
|
-
* absence of a custom cache. We use this for SSR too (see ./response-cache.js).
|
|
698
|
+
* This is only used within our framework for SSR (see ./response-cache.js).
|
|
602
699
|
*/
|
|
603
700
|
|
|
604
701
|
|
|
@@ -606,7 +703,7 @@ class MemoryCache {
|
|
|
606
703
|
constructor(source = null) {
|
|
607
704
|
this.store = (handler, options, entry) => {
|
|
608
705
|
const requestType = handler.type;
|
|
609
|
-
const frozenEntry = Object.
|
|
706
|
+
const frozenEntry = Object.freeze(entry); // Ensure we have a cache location for this handler type.
|
|
610
707
|
|
|
611
708
|
this._cache[requestType] = this._cache[requestType] || {}; // Cache the data.
|
|
612
709
|
|
|
@@ -666,16 +763,22 @@ class MemoryCache {
|
|
|
666
763
|
|
|
667
764
|
if (!handlerCache) {
|
|
668
765
|
return 0;
|
|
669
|
-
}
|
|
670
|
-
|
|
766
|
+
}
|
|
671
767
|
|
|
672
768
|
let removedCount = 0;
|
|
673
769
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
770
|
+
if (typeof predicate === "function") {
|
|
771
|
+
// Apply the predicate to what we have cached.
|
|
772
|
+
for (const [key, entry] of Object.entries(handlerCache)) {
|
|
773
|
+
if (predicate(key, entry)) {
|
|
774
|
+
removedCount++;
|
|
775
|
+
delete handlerCache[key];
|
|
776
|
+
}
|
|
678
777
|
}
|
|
778
|
+
} else {
|
|
779
|
+
// We're removing everything so delete the entire subcache.
|
|
780
|
+
removedCount = Object.keys(handlerCache).length;
|
|
781
|
+
delete this._cache[requestType];
|
|
679
782
|
}
|
|
680
783
|
|
|
681
784
|
return removedCount;
|
|
@@ -705,6 +808,12 @@ class MemoryCache {
|
|
|
705
808
|
}
|
|
706
809
|
}
|
|
707
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Indicate if this cache is being used or now.
|
|
813
|
+
*
|
|
814
|
+
* When the cache has entries, returns `true`; otherwise, returns `false`.
|
|
815
|
+
*/
|
|
816
|
+
|
|
708
817
|
|
|
709
818
|
get inUse() {
|
|
710
819
|
return Object.keys(this._cache).length > 0;
|
|
@@ -713,7 +822,13 @@ class MemoryCache {
|
|
|
713
822
|
}
|
|
714
823
|
|
|
715
824
|
/***/ }),
|
|
716
|
-
/*
|
|
825
|
+
/* 10 */
|
|
826
|
+
/***/ (function(module, exports) {
|
|
827
|
+
|
|
828
|
+
module.exports = require("@khanacademy/wonder-stuff-core");
|
|
829
|
+
|
|
830
|
+
/***/ }),
|
|
831
|
+
/* 11 */
|
|
717
832
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
718
833
|
|
|
719
834
|
"use strict";
|
|
@@ -725,9 +840,8 @@ class MemoryCache {
|
|
|
725
840
|
* use with the Wonder Blocks Data framework.
|
|
726
841
|
*/
|
|
727
842
|
class RequestHandler {
|
|
728
|
-
constructor(type,
|
|
843
|
+
constructor(type, hydrate = true) {
|
|
729
844
|
this._type = type;
|
|
730
|
-
this._cache = cache || null;
|
|
731
845
|
this._hydrate = !!hydrate;
|
|
732
846
|
}
|
|
733
847
|
|
|
@@ -735,26 +849,10 @@ class RequestHandler {
|
|
|
735
849
|
return this._type;
|
|
736
850
|
}
|
|
737
851
|
|
|
738
|
-
get cache() {
|
|
739
|
-
return this._cache;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
852
|
get hydrate() {
|
|
743
853
|
return this._hydrate;
|
|
744
854
|
}
|
|
745
855
|
|
|
746
|
-
shouldRefreshCache(options, cachedEntry) {
|
|
747
|
-
/**
|
|
748
|
-
* By default, the cache needs a refresh if the current entry is an
|
|
749
|
-
* error.
|
|
750
|
-
*
|
|
751
|
-
* This means that an error will cause a re-request on render.
|
|
752
|
-
* Useful if the server rendered an error, as it means the client
|
|
753
|
-
* will update after rehydration.
|
|
754
|
-
*/
|
|
755
|
-
return cachedEntry == null || cachedEntry.error != null;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
856
|
getKey(options) {
|
|
759
857
|
try {
|
|
760
858
|
return options === undefined ? "undefined" : JSON.stringify(options);
|
|
@@ -770,7 +868,7 @@ class RequestHandler {
|
|
|
770
868
|
}
|
|
771
869
|
|
|
772
870
|
/***/ }),
|
|
773
|
-
/*
|
|
871
|
+
/* 12 */
|
|
774
872
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
775
873
|
|
|
776
874
|
"use strict";
|
|
@@ -779,7 +877,7 @@ class RequestHandler {
|
|
|
779
877
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
780
878
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
|
|
781
879
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_1__);
|
|
782
|
-
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
880
|
+
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
|
783
881
|
|
|
784
882
|
|
|
785
883
|
|
|
@@ -801,18 +899,13 @@ class TrackData extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
801
899
|
}
|
|
802
900
|
|
|
803
901
|
/***/ }),
|
|
804
|
-
/*
|
|
902
|
+
/* 13 */
|
|
805
903
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
806
904
|
|
|
807
905
|
"use strict";
|
|
808
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Data; });
|
|
809
906
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
810
907
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
811
|
-
/* harmony import */ var
|
|
812
|
-
/* harmony import */ var _internal_data_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
|
|
813
|
-
/* harmony import */ var _intercept_context_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
|
|
814
|
-
|
|
815
|
-
|
|
908
|
+
/* harmony import */ var _hooks_use_data_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
|
|
816
909
|
|
|
817
910
|
|
|
818
911
|
|
|
@@ -821,93 +914,22 @@ class TrackData extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
821
914
|
* requirements can be placed in a React application in a manner that will
|
|
822
915
|
* support server-side rendering and efficient caching.
|
|
823
916
|
*/
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
} = this.props;
|
|
829
|
-
|
|
830
|
-
if (!interceptor) {
|
|
831
|
-
return handler;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
const {
|
|
835
|
-
fulfillRequest,
|
|
836
|
-
shouldRefreshCache
|
|
837
|
-
} = interceptor;
|
|
838
|
-
const fulfillRequestFn = fulfillRequest ? options => {
|
|
839
|
-
const interceptedResult = fulfillRequest(options);
|
|
840
|
-
return interceptedResult != null ? interceptedResult : handler.fulfillRequest(options);
|
|
841
|
-
} : options => handler.fulfillRequest(options);
|
|
842
|
-
const shouldRefreshCacheFn = shouldRefreshCache ? (options, cacheEntry) => {
|
|
843
|
-
const interceptedResult = shouldRefreshCache(options, cacheEntry);
|
|
844
|
-
return interceptedResult != null ? interceptedResult : handler.shouldRefreshCache(options, cacheEntry);
|
|
845
|
-
} : (options, cacheEntry) => handler.shouldRefreshCache(options, cacheEntry);
|
|
846
|
-
return {
|
|
847
|
-
fulfillRequest: fulfillRequestFn,
|
|
848
|
-
shouldRefreshCache: shouldRefreshCacheFn,
|
|
849
|
-
getKey: options => handler.getKey(options),
|
|
850
|
-
type: handler.type,
|
|
851
|
-
cache: handler.cache,
|
|
852
|
-
hydrate: handler.hydrate
|
|
853
|
-
};
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
_getCacheLookupFnFromInterceptor(interceptor) {
|
|
857
|
-
const getEntry = interceptor && interceptor.getEntry;
|
|
858
|
-
|
|
859
|
-
if (!getEntry) {
|
|
860
|
-
return _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* ResponseCache */ "a"].Default.getEntry;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
return (handler, options) => {
|
|
864
|
-
// 1. Lookup the current cache value.
|
|
865
|
-
const cacheEntry = _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* ResponseCache */ "a"].Default.getEntry(handler, options); // 2. See if our interceptor wants to override it.
|
|
866
|
-
|
|
867
|
-
const interceptedData = getEntry(options, cacheEntry); // 3. Return the appropriate response.
|
|
868
|
-
|
|
869
|
-
return interceptedData != null ? interceptedData : cacheEntry;
|
|
870
|
-
};
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
render() {
|
|
874
|
-
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_intercept_context_js__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"].Consumer, null, value => {
|
|
875
|
-
const handlerType = this.props.handler.type;
|
|
876
|
-
const interceptor = value[handlerType];
|
|
877
|
-
|
|
878
|
-
const handler = this._getHandlerFromInterceptor(interceptor);
|
|
879
|
-
|
|
880
|
-
const getEntry = this._getCacheLookupFnFromInterceptor(interceptor);
|
|
881
|
-
/**
|
|
882
|
-
* Need to share our types with InternalData so Flow
|
|
883
|
-
* doesn't need to infer them and find mismatches.
|
|
884
|
-
* However, just deriving a new component creates issues
|
|
885
|
-
* where InternalData starts rerendering too often.
|
|
886
|
-
* Couldn't track down why, so suppressing the error
|
|
887
|
-
* instead.
|
|
888
|
-
*/
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_internal_data_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ "a"] // $FlowIgnore[incompatible-type-arg]
|
|
892
|
-
, {
|
|
893
|
-
handler: handler,
|
|
894
|
-
options: this.props.options,
|
|
895
|
-
getEntry: getEntry
|
|
896
|
-
}, result => this.props.children(result));
|
|
897
|
-
});
|
|
898
|
-
}
|
|
917
|
+
const Data = props => {
|
|
918
|
+
const data = Object(_hooks_use_data_js__WEBPACK_IMPORTED_MODULE_1__[/* useData */ "a"])(props.handler, props.options);
|
|
919
|
+
return props.children(data);
|
|
920
|
+
};
|
|
899
921
|
|
|
900
|
-
|
|
922
|
+
/* harmony default export */ __webpack_exports__["a"] = (Data);
|
|
901
923
|
|
|
902
924
|
/***/ }),
|
|
903
|
-
/*
|
|
925
|
+
/* 14 */
|
|
904
926
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
905
927
|
|
|
906
928
|
"use strict";
|
|
907
929
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return InterceptData; });
|
|
908
930
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
909
931
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
910
|
-
/* harmony import */ var _intercept_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
932
|
+
/* harmony import */ var _intercept_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
|
|
911
933
|
|
|
912
934
|
|
|
913
935
|
|
|
@@ -916,9 +938,6 @@ class Data extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
916
938
|
* type of a given handler and provide alternative results. This is mostly
|
|
917
939
|
* useful for testing.
|
|
918
940
|
*
|
|
919
|
-
* Results from this interceptor will end up in the cache. If you
|
|
920
|
-
* wish to only override the cache, use `InterceptCache` instead.
|
|
921
|
-
*
|
|
922
941
|
* This component is not recommended for use in production code as it
|
|
923
942
|
* can prevent predictable functioning of the Wonder Blocks Data framework.
|
|
924
943
|
* One possible side-effect is that inflight requests from the interceptor could
|
|
@@ -935,8 +954,7 @@ class InterceptData extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
935
954
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_intercept_context_js__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"].Consumer, null, value => {
|
|
936
955
|
const handlerType = this.props.handler.type;
|
|
937
956
|
const interceptor = { ...value[handlerType],
|
|
938
|
-
fulfillRequest: this.props.fulfillRequest
|
|
939
|
-
shouldRefreshCache: this.props.shouldRefreshCache || null
|
|
957
|
+
fulfillRequest: this.props.fulfillRequest
|
|
940
958
|
};
|
|
941
959
|
const newValue = { ...value,
|
|
942
960
|
[handlerType]: interceptor
|
|
@@ -950,252 +968,223 @@ class InterceptData extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
950
968
|
}
|
|
951
969
|
|
|
952
970
|
/***/ }),
|
|
953
|
-
/*
|
|
971
|
+
/* 15 */
|
|
954
972
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
955
973
|
|
|
956
974
|
"use strict";
|
|
957
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return
|
|
975
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GqlRouter; });
|
|
958
976
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
959
977
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
960
|
-
/* harmony import */ var
|
|
978
|
+
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
|
|
961
979
|
|
|
962
980
|
|
|
963
981
|
|
|
964
982
|
/**
|
|
965
|
-
*
|
|
966
|
-
* type of a given handler and provide alternative values. This is mostly
|
|
967
|
-
* useful for testing.
|
|
983
|
+
* Configure GraphQL routing for GraphQL hooks and components.
|
|
968
984
|
*
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
* This component is generally not suitable for use in production code as it
|
|
973
|
-
* can prevent predictable functioning of the Wonder Blocks Data framework.
|
|
974
|
-
*
|
|
975
|
-
* These components do not chain. If a different `InterceptCache` instance is
|
|
976
|
-
* rendered within this one that intercepts the same handler type, then that
|
|
977
|
-
* new instance will replace this interceptor for its children.
|
|
985
|
+
* These can be nested. Components and hooks relying on the GraphQL routing
|
|
986
|
+
* will use the configuration from their closest ancestral GqlRouter.
|
|
978
987
|
*/
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
988
|
+
const GqlRouter = ({
|
|
989
|
+
defaultContext: thisDefaultContext,
|
|
990
|
+
fetch: thisFetch,
|
|
991
|
+
children
|
|
992
|
+
}) => {
|
|
993
|
+
// We don't care if we're nested. We always force our callers to define
|
|
994
|
+
// everything. It makes for a clearer API and requires less error checking
|
|
995
|
+
// code (assuming our flow types are correct). We also don't default fetch
|
|
996
|
+
// to anything - our callers can tell us what function to use quite easily.
|
|
997
|
+
// If code that consumes this wants more nuanced nesting, it can implement
|
|
998
|
+
// it within its own GqlRouter than then defers to this one.
|
|
999
|
+
// We want to always use the same object if things haven't changed to avoid
|
|
1000
|
+
// over-rendering consumers of our context, let's memoize the configuration.
|
|
1001
|
+
// By doing this, if a component under children that uses this context
|
|
1002
|
+
// uses React.memo, we won't force it to re-render every time we render
|
|
1003
|
+
// because we'll only change the context value if something has actually
|
|
1004
|
+
// changed.
|
|
1005
|
+
const configuration = react__WEBPACK_IMPORTED_MODULE_0__["useMemo"](() => ({
|
|
1006
|
+
fetch: thisFetch,
|
|
1007
|
+
defaultContext: thisDefaultContext
|
|
1008
|
+
}), [thisDefaultContext, thisFetch]);
|
|
1009
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlRouterContext */ "a"].Provider, {
|
|
1010
|
+
value: configuration
|
|
1011
|
+
}, children);
|
|
1012
|
+
};
|
|
996
1013
|
|
|
997
1014
|
/***/ }),
|
|
998
|
-
/*
|
|
1015
|
+
/* 16 */
|
|
999
1016
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1000
1017
|
|
|
1001
1018
|
"use strict";
|
|
1002
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return
|
|
1019
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return useGql; });
|
|
1003
1020
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1004
1021
|
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1005
|
-
/* harmony import */ var
|
|
1006
|
-
/* harmony import */ var
|
|
1007
|
-
/* harmony import */ var
|
|
1008
|
-
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3);
|
|
1022
|
+
/* harmony import */ var _util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
|
|
1023
|
+
/* harmony import */ var _util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18);
|
|
1024
|
+
/* harmony import */ var _util_gql_error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1);
|
|
1009
1025
|
|
|
1010
1026
|
|
|
1011
1027
|
|
|
1012
1028
|
|
|
1013
1029
|
|
|
1014
1030
|
/**
|
|
1015
|
-
*
|
|
1016
|
-
* It is wrapped by Data in order to support intercepts and be exported for use.
|
|
1031
|
+
* Hook to obtain a gqlFetch function for performing GraphQL requests.
|
|
1017
1032
|
*
|
|
1018
|
-
*
|
|
1033
|
+
* The fetch function will resolve null if the request was aborted, otherwise
|
|
1034
|
+
* it will resolve the data returned by the GraphQL server.
|
|
1019
1035
|
*/
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
this.state = this._buildStateAndfulfillNeeds(props);
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
componentDidMount() {
|
|
1027
|
-
this._mounted = true;
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
shouldComponentUpdate(nextProps, nextState) {
|
|
1031
|
-
/**
|
|
1032
|
-
* We only bother updating if our state changed.
|
|
1033
|
-
*
|
|
1034
|
-
* And we only update the state if props changed
|
|
1035
|
-
* or we got new data/error.
|
|
1036
|
-
*/
|
|
1037
|
-
if (!this._propsMatch(nextProps)) {
|
|
1038
|
-
const newState = this._buildStateAndfulfillNeeds(nextProps);
|
|
1039
|
-
|
|
1040
|
-
this.setState(newState);
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
return this.state.loading !== nextState.loading || this.state.data !== nextState.data || this.state.error !== nextState.error;
|
|
1044
|
-
}
|
|
1036
|
+
const useGql = () => {
|
|
1037
|
+
// This hook only works if the `GqlRouter` has been used to setup context.
|
|
1038
|
+
const gqlRouterContext = Object(react__WEBPACK_IMPORTED_MODULE_0__["useContext"])(_util_gql_router_context_js__WEBPACK_IMPORTED_MODULE_1__[/* GqlRouterContext */ "a"]);
|
|
1045
1039
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1040
|
+
if (gqlRouterContext == null) {
|
|
1041
|
+
throw new _util_gql_error_js__WEBPACK_IMPORTED_MODULE_3__[/* GqlError */ "a"]("No GqlRouter", _util_gql_error_js__WEBPACK_IMPORTED_MODULE_3__[/* GqlErrors */ "b"].Internal);
|
|
1048
1042
|
}
|
|
1049
1043
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
} = otherProps;
|
|
1059
|
-
return handler === prevHandler && handler.getKey(options) === prevHandler.getKey(prevOptions);
|
|
1060
|
-
}
|
|
1044
|
+
const {
|
|
1045
|
+
fetch,
|
|
1046
|
+
defaultContext
|
|
1047
|
+
} = gqlRouterContext; // Let's memoize the gqlFetch function we create based off our context.
|
|
1048
|
+
// That way, even if the context happens to change, if its values don't
|
|
1049
|
+
// we give the same function instance back to our callers instead of
|
|
1050
|
+
// making a new one. That then means they can safely use the return value
|
|
1051
|
+
// in hooks deps without fear of it triggering extra renders.
|
|
1061
1052
|
|
|
1062
|
-
|
|
1053
|
+
const gqlFetch = Object(react__WEBPACK_IMPORTED_MODULE_0__["useMemo"])(() => (operation, options = Object.freeze({})) => {
|
|
1063
1054
|
const {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
* We have to do this here from the constructor so that this
|
|
1078
|
-
* data request is tracked when performing server-side rendering.
|
|
1079
|
-
*/
|
|
1080
|
-
_util_request_fulfillment_js__WEBPACK_IMPORTED_MODULE_2__[/* RequestFulfillment */ "a"].Default.fulfill(handler, options).then(cacheEntry => {
|
|
1081
|
-
/**
|
|
1082
|
-
* We get here, we should have updated the cache.
|
|
1083
|
-
* However, we need to update the component, but we
|
|
1084
|
-
* should only do that if the props are the same as they
|
|
1085
|
-
* were when this was called.
|
|
1086
|
-
*/
|
|
1087
|
-
if (this._mounted && this._propsMatch(propsAtFulfillment)) {
|
|
1088
|
-
this.setState({
|
|
1089
|
-
loading: false,
|
|
1090
|
-
data: cacheEntry.data,
|
|
1091
|
-
error: cacheEntry.error
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1055
|
+
variables,
|
|
1056
|
+
context
|
|
1057
|
+
} = options; // Invoke the fetch and extract the data.
|
|
1058
|
+
|
|
1059
|
+
return fetch(operation, variables, { ...defaultContext,
|
|
1060
|
+
...context
|
|
1061
|
+
}).then(_util_get_gql_data_from_response_js__WEBPACK_IMPORTED_MODULE_2__[/* getGqlDataFromResponse */ "a"], error => {
|
|
1062
|
+
// Return null if the request was aborted.
|
|
1063
|
+
// The only way to detect this reliably, it seems, is to
|
|
1064
|
+
// check the error name and see if it's "AbortError" (this
|
|
1065
|
+
// is also what Apollo does).
|
|
1066
|
+
// Even then, it's reliant on the fetch supporting aborts.
|
|
1067
|
+
if (error.name === "AbortError") {
|
|
1095
1068
|
return null;
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
console.error(`Unexpected error occurred during data fulfillment: ${e}`);
|
|
1102
|
-
|
|
1103
|
-
if (this._mounted && this._propsMatch(propsAtFulfillment)) {
|
|
1104
|
-
this.setState({
|
|
1105
|
-
loading: false,
|
|
1106
|
-
data: null,
|
|
1107
|
-
error: typeof e === "string" ? e : e.message
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
return null;
|
|
1112
|
-
});
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
* This is the default response for the server and for the initial
|
|
1116
|
-
* client-side render if we have cachedData.
|
|
1117
|
-
*
|
|
1118
|
-
* This ensures we don't make promises we don't want when doing
|
|
1119
|
-
* server-side rendering. Instead, we either have data from the cache
|
|
1120
|
-
* or we don't.
|
|
1121
|
-
*/
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
1071
|
+
}, [fetch, defaultContext]);
|
|
1072
|
+
return gqlFetch;
|
|
1073
|
+
};
|
|
1122
1074
|
|
|
1075
|
+
/***/ }),
|
|
1076
|
+
/* 17 */
|
|
1077
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1123
1078
|
|
|
1079
|
+
"use strict";
|
|
1080
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return resultFromCacheEntry; });
|
|
1081
|
+
/**
|
|
1082
|
+
* Turns a cache entry into a stateful result.
|
|
1083
|
+
*/
|
|
1084
|
+
const resultFromCacheEntry = cacheEntry => {
|
|
1085
|
+
// No cache entry means we didn't load one yet.
|
|
1086
|
+
if (cacheEntry == null) {
|
|
1124
1087
|
return {
|
|
1125
|
-
|
|
1126
|
-
data: cachedData && cachedData.data,
|
|
1127
|
-
error: cachedData && cachedData.error
|
|
1088
|
+
status: "loading"
|
|
1128
1089
|
};
|
|
1129
1090
|
}
|
|
1130
1091
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
error
|
|
1136
|
-
} = this.state;
|
|
1137
|
-
|
|
1138
|
-
if (loading) {
|
|
1139
|
-
return {
|
|
1140
|
-
loading: true
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
if (data != null) {
|
|
1145
|
-
return {
|
|
1146
|
-
loading: false,
|
|
1147
|
-
data
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
if (error == null) {
|
|
1152
|
-
// We should never get here ever.
|
|
1153
|
-
throw new Error("Loaded result has invalid state where data and error are missing");
|
|
1154
|
-
}
|
|
1092
|
+
const {
|
|
1093
|
+
data,
|
|
1094
|
+
error
|
|
1095
|
+
} = cacheEntry;
|
|
1155
1096
|
|
|
1097
|
+
if (data != null) {
|
|
1156
1098
|
return {
|
|
1157
|
-
|
|
1158
|
-
|
|
1099
|
+
status: "success",
|
|
1100
|
+
data
|
|
1159
1101
|
};
|
|
1160
1102
|
}
|
|
1161
1103
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1104
|
+
if (error == null) {
|
|
1105
|
+
// We should never get here ever.
|
|
1106
|
+
return {
|
|
1107
|
+
status: "error",
|
|
1108
|
+
error: "Loaded result has invalid state where data and error are missing"
|
|
1109
|
+
};
|
|
1167
1110
|
}
|
|
1168
1111
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1112
|
+
return {
|
|
1113
|
+
status: "error",
|
|
1114
|
+
error
|
|
1115
|
+
};
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
/***/ }),
|
|
1119
|
+
/* 18 */
|
|
1120
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1177
1121
|
|
|
1178
|
-
|
|
1122
|
+
"use strict";
|
|
1123
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getGqlDataFromResponse; });
|
|
1124
|
+
/* harmony import */ var _gql_error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Validate a GQL operation response and extract the data.
|
|
1128
|
+
*/
|
|
1129
|
+
|
|
1130
|
+
const getGqlDataFromResponse = async response => {
|
|
1131
|
+
// Get the response as text, that way we can use the text in error
|
|
1132
|
+
// messaging, should our parsing fail.
|
|
1133
|
+
const bodyText = await response.text();
|
|
1134
|
+
let result;
|
|
1135
|
+
|
|
1136
|
+
try {
|
|
1137
|
+
result = JSON.parse(bodyText);
|
|
1138
|
+
} catch (e) {
|
|
1139
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlError */ "a"]("Failed to parse response", _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlErrors */ "b"].Parse, {
|
|
1140
|
+
metadata: {
|
|
1141
|
+
statusCode: response.status,
|
|
1142
|
+
bodyText
|
|
1143
|
+
},
|
|
1144
|
+
cause: e
|
|
1179
1145
|
});
|
|
1180
|
-
}
|
|
1146
|
+
} // Check for a bad status code.
|
|
1181
1147
|
|
|
1182
|
-
render() {
|
|
1183
|
-
const result = this._resultFromState(); // We only track data requests when we are server-side and we don't
|
|
1184
|
-
// already have a result. The existence of a result is indicated by the
|
|
1185
|
-
// loading flag being false.
|
|
1186
1148
|
|
|
1149
|
+
if (response.status >= 300) {
|
|
1150
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlError */ "a"]("Response unsuccessful", _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlErrors */ "b"].Network, {
|
|
1151
|
+
metadata: {
|
|
1152
|
+
statusCode: response.status,
|
|
1153
|
+
result
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
} // Check that we have a valid result payload.
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
if ( // Flow shouldn't be warning about this.
|
|
1160
|
+
// $FlowIgnore[method-unbinding]
|
|
1161
|
+
!Object.prototype.hasOwnProperty.call(result, "data") && // Flow shouldn't be warning about this.
|
|
1162
|
+
// $FlowIgnore[method-unbinding]
|
|
1163
|
+
!Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
1164
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlError */ "a"]("Server response missing", _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlErrors */ "b"].BadResponse, {
|
|
1165
|
+
metadata: {
|
|
1166
|
+
statusCode: response.status,
|
|
1167
|
+
result
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
} // If the response payload has errors, throw an error.
|
|
1187
1171
|
|
|
1188
|
-
if (result.loading && _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_1__["Server"].isServerSide()) {
|
|
1189
|
-
return this._renderWithTrackingContext(result);
|
|
1190
|
-
}
|
|
1191
1172
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1173
|
+
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
1174
|
+
throw new _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlError */ "a"]("GraphQL errors", _gql_error_js__WEBPACK_IMPORTED_MODULE_0__[/* GqlErrors */ "b"].ErrorResult, {
|
|
1175
|
+
metadata: {
|
|
1176
|
+
statusCode: response.status,
|
|
1177
|
+
result
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
} // We got here, so return the data.
|
|
1194
1181
|
|
|
1195
|
-
|
|
1182
|
+
|
|
1183
|
+
return result.data;
|
|
1184
|
+
};
|
|
1196
1185
|
|
|
1197
1186
|
/***/ }),
|
|
1198
|
-
/*
|
|
1187
|
+
/* 19 */
|
|
1199
1188
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1200
1189
|
|
|
1201
1190
|
"use strict";
|
|
@@ -1207,25 +1196,33 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1207
1196
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeAllFromCache", function() { return removeAllFromCache; });
|
|
1208
1197
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
|
1209
1198
|
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_0__);
|
|
1210
|
-
/* harmony import */ var _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
1211
|
-
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
1212
|
-
/* harmony import */ var _util_request_handler_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(
|
|
1199
|
+
/* harmony import */ var _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
1200
|
+
/* harmony import */ var _util_request_tracking_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
|
1201
|
+
/* harmony import */ var _util_request_handler_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
|
|
1213
1202
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RequestHandler", function() { return _util_request_handler_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
|
|
1214
1203
|
|
|
1215
|
-
/* harmony import */ var _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(
|
|
1204
|
+
/* harmony import */ var _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(12);
|
|
1216
1205
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrackData", function() { return _components_track_data_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
|
|
1217
1206
|
|
|
1218
|
-
/* harmony import */ var _components_data_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(
|
|
1207
|
+
/* harmony import */ var _components_data_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(13);
|
|
1219
1208
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Data", function() { return _components_data_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
|
|
1220
1209
|
|
|
1221
|
-
/* harmony import */ var _components_intercept_data_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(
|
|
1210
|
+
/* harmony import */ var _components_intercept_data_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(14);
|
|
1222
1211
|
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InterceptData", function() { return _components_intercept_data_js__WEBPACK_IMPORTED_MODULE_6__["a"]; });
|
|
1223
1212
|
|
|
1224
|
-
/* harmony import */ var
|
|
1225
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "
|
|
1213
|
+
/* harmony import */ var _hooks_use_data_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6);
|
|
1214
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useData", function() { return _hooks_use_data_js__WEBPACK_IMPORTED_MODULE_7__["a"]; });
|
|
1215
|
+
|
|
1216
|
+
/* harmony import */ var _components_gql_router_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(15);
|
|
1217
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlRouter", function() { return _components_gql_router_js__WEBPACK_IMPORTED_MODULE_8__["a"]; });
|
|
1218
|
+
|
|
1219
|
+
/* harmony import */ var _hooks_use_gql_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(16);
|
|
1220
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useGql", function() { return _hooks_use_gql_js__WEBPACK_IMPORTED_MODULE_9__["a"]; });
|
|
1221
|
+
|
|
1222
|
+
/* harmony import */ var _util_gql_error_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1);
|
|
1223
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlErrors", function() { return _util_gql_error_js__WEBPACK_IMPORTED_MODULE_10__["b"]; });
|
|
1226
1224
|
|
|
1227
|
-
/* harmony
|
|
1228
|
-
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoCache", function() { return _util_no_cache_js__WEBPACK_IMPORTED_MODULE_8__["a"]; });
|
|
1225
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GqlError", function() { return _util_gql_error_js__WEBPACK_IMPORTED_MODULE_10__["a"]; });
|
|
1229
1226
|
|
|
1230
1227
|
|
|
1231
1228
|
|
|
@@ -1247,15 +1244,12 @@ const hasUnfulfilledRequests = () => {
|
|
|
1247
1244
|
};
|
|
1248
1245
|
const removeFromCache = (handler, options) => _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* ResponseCache */ "a"].Default.remove(handler, options);
|
|
1249
1246
|
const removeAllFromCache = (handler, predicate) => _util_response_cache_js__WEBPACK_IMPORTED_MODULE_1__[/* ResponseCache */ "a"].Default.removeAll(handler, predicate);
|
|
1250
|
-
/**
|
|
1251
|
-
* TODO(somewhatabstract): Export each cache type we implement.
|
|
1252
|
-
*
|
|
1253
|
-
* Is there a base type we export, like we do for RequestHandler?
|
|
1254
|
-
*/
|
|
1255
1247
|
|
|
1256
1248
|
|
|
1257
1249
|
|
|
1258
1250
|
|
|
1251
|
+
// GraphQL
|
|
1252
|
+
|
|
1259
1253
|
|
|
1260
1254
|
|
|
1261
1255
|
|