@khanacademy/wonder-blocks-data 7.0.1 → 8.0.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 +20 -0
- package/dist/es/index.js +284 -100
- package/dist/index.js +1180 -800
- package/package.json +1 -1
- package/src/__docs__/_overview_ssr_.stories.mdx +13 -13
- package/src/__docs__/exports.abort-inflight-requests.stories.mdx +20 -0
- package/src/__docs__/exports.data.stories.mdx +3 -3
- package/src/__docs__/{exports.fulfill-all-data-requests.stories.mdx → exports.fetch-tracked-requests.stories.mdx} +5 -5
- package/src/__docs__/exports.get-gql-request-id.stories.mdx +24 -0
- package/src/__docs__/{exports.has-unfulfilled-requests.stories.mdx → exports.has-tracked-requests-to-be-fetched.stories.mdx} +4 -4
- package/src/__docs__/exports.intialize-hydration-cache.stories.mdx +29 -0
- package/src/__docs__/exports.purge-caches.stories.mdx +23 -0
- package/src/__docs__/{exports.remove-all-from-cache.stories.mdx → exports.purge-hydration-cache.stories.mdx} +4 -4
- package/src/__docs__/{exports.clear-shared-cache.stories.mdx → exports.purge-shared-cache.stories.mdx} +4 -4
- package/src/__docs__/exports.track-data.stories.mdx +4 -4
- package/src/__docs__/exports.use-cached-effect.stories.mdx +7 -4
- package/src/__docs__/exports.use-gql.stories.mdx +1 -33
- package/src/__docs__/exports.use-server-effect.stories.mdx +1 -1
- package/src/__docs__/exports.use-shared-cache.stories.mdx +2 -2
- package/src/__docs__/types.fetch-policy.stories.mdx +44 -0
- package/src/__docs__/types.response-cache.stories.mdx +1 -1
- package/src/__tests__/generated-snapshot.test.js +5 -5
- package/src/components/__tests__/data.test.js +2 -6
- package/src/hooks/__tests__/use-cached-effect.test.js +341 -100
- package/src/hooks/__tests__/use-hydratable-effect.test.js +15 -9
- package/src/hooks/__tests__/use-shared-cache.test.js +6 -6
- package/src/hooks/use-cached-effect.js +169 -93
- package/src/hooks/use-hydratable-effect.js +8 -1
- package/src/hooks/use-shared-cache.js +2 -2
- package/src/index.js +14 -78
- package/src/util/__tests__/get-gql-request-id.test.js +74 -0
- package/src/util/__tests__/graphql-document-node-parser.test.js +542 -0
- package/src/util/__tests__/hydration-cache-api.test.js +35 -0
- package/src/util/__tests__/purge-caches.test.js +29 -0
- package/src/util/__tests__/request-api.test.js +188 -0
- package/src/util/__tests__/request-fulfillment.test.js +42 -0
- package/src/util/__tests__/ssr-cache.test.js +10 -60
- package/src/util/__tests__/to-gql-operation.test.js +42 -0
- package/src/util/data-error.js +6 -0
- package/src/util/get-gql-request-id.js +50 -0
- package/src/util/graphql-document-node-parser.js +133 -0
- package/src/util/graphql-types.js +30 -0
- package/src/util/hydration-cache-api.js +28 -0
- package/src/util/purge-caches.js +15 -0
- package/src/util/request-api.js +66 -0
- package/src/util/request-fulfillment.js +32 -12
- package/src/util/request-tracking.js +1 -1
- package/src/util/ssr-cache.js +1 -21
- package/src/util/to-gql-operation.js +44 -0
- package/src/util/types.js +31 -0
- package/src/__docs__/exports.intialize-cache.stories.mdx +0 -29
- package/src/__docs__/exports.remove-from-cache.stories.mdx +0 -25
- package/src/__docs__/exports.request-fulfillment.stories.mdx +0 -36
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-data
|
|
2
2
|
|
|
3
|
+
## 8.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 0720470e: Renamed `initializeCache` to `initializeHydrationCache`, deleted `removeFromCache`, renamed `removeAllFromCache` to `purgeHydrationCache`
|
|
8
|
+
- cf9ed87f: Add `fetchPolicy` to `useCachedEffect` options, add `refetch` to `useCachedEffect` return value (return value is now a tuple of [result, refetch]), add abort API to request fulfillment (not truly aborting though)
|
|
9
|
+
- b882b082: Stop exporting `RequestFulfillment`, update `useCachedEffect` to consider scope with sharing inflight requests
|
|
10
|
+
- 0720470e: Rename `fulfillAllDataRequests` to `fetchTrackedRequests`, rename `hasUnfulfilledRequests` to `hasTrackedRequestsToBeFetched`
|
|
11
|
+
- 0720470e: Renamed `clearSharedCache` to `purgeSharedCache`
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 0720470e: Add `purgeCaches` export for purging all caches with one call
|
|
16
|
+
- 75c10036: Add `abortInflightRequests` to exports
|
|
17
|
+
- a85f2f3a: Provide `getGqlRequestId` function
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 1385f468: Removed unnecessary `new` on tracking context creation
|
|
22
|
+
|
|
3
23
|
## 7.0.1
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/dist/es/index.js
CHANGED
|
@@ -4,11 +4,14 @@ import _extends from '@babel/runtime/helpers/extends';
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { useContext, useRef, useMemo, useCallback } from 'react';
|
|
6
6
|
|
|
7
|
+
const FetchPolicy = require("flow-enums-runtime").Mirrored(["CacheBeforeNetwork", "CacheAndNetwork", "CacheOnly", "NetworkOnly"]);
|
|
8
|
+
|
|
7
9
|
const DataErrors = Object.freeze({
|
|
8
10
|
Unknown: "Unknown",
|
|
9
11
|
Internal: "Internal",
|
|
10
12
|
InvalidInput: "InvalidInput",
|
|
11
13
|
Network: "Network",
|
|
14
|
+
NotAllowed: "NotAllowed",
|
|
12
15
|
Parse: "Parse",
|
|
13
16
|
Hydrated: "Hydrated"
|
|
14
17
|
});
|
|
@@ -180,20 +183,14 @@ class SsrCache {
|
|
|
180
183
|
return internalEntry;
|
|
181
184
|
};
|
|
182
185
|
|
|
183
|
-
this.
|
|
184
|
-
var _this$
|
|
185
|
-
|
|
186
|
-
return this._hydrationCache.purge(DefaultScope$2, id) || ((_this$_ssrOnlyCache$p = (_this$_ssrOnlyCache2 = this._ssrOnlyCache) == null ? void 0 : _this$_ssrOnlyCache2.purge(DefaultScope$2, id)) != null ? _this$_ssrOnlyCache$p : false);
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
this.removeAll = predicate => {
|
|
190
|
-
var _this$_ssrOnlyCache3;
|
|
186
|
+
this.purgeData = predicate => {
|
|
187
|
+
var _this$_ssrOnlyCache2;
|
|
191
188
|
|
|
192
189
|
const realPredicate = predicate ? (_, key, cachedEntry) => predicate(key, cachedEntry) : undefined;
|
|
193
190
|
|
|
194
191
|
this._hydrationCache.purgeAll(realPredicate);
|
|
195
192
|
|
|
196
|
-
(_this$
|
|
193
|
+
(_this$_ssrOnlyCache2 = this._ssrOnlyCache) == null ? void 0 : _this$_ssrOnlyCache2.purgeAll(realPredicate);
|
|
197
194
|
};
|
|
198
195
|
|
|
199
196
|
this.cloneHydratableData = () => {
|
|
@@ -215,9 +212,9 @@ class SsrCache {
|
|
|
215
212
|
if (hydrate) {
|
|
216
213
|
this._hydrationCache.set(DefaultScope$2, id, frozenEntry);
|
|
217
214
|
} else {
|
|
218
|
-
var _this$
|
|
215
|
+
var _this$_ssrOnlyCache3;
|
|
219
216
|
|
|
220
|
-
(_this$
|
|
217
|
+
(_this$_ssrOnlyCache3 = this._ssrOnlyCache) == null ? void 0 : _this$_ssrOnlyCache3.set(DefaultScope$2, id, frozenEntry);
|
|
221
218
|
}
|
|
222
219
|
}
|
|
223
220
|
|
|
@@ -226,6 +223,9 @@ class SsrCache {
|
|
|
226
223
|
|
|
227
224
|
}
|
|
228
225
|
|
|
226
|
+
const initializeHydrationCache = source => SsrCache.Default.initialize(source);
|
|
227
|
+
const purgeHydrationCache = predicate => SsrCache.Default.purgeData(predicate);
|
|
228
|
+
|
|
229
229
|
let _default$1;
|
|
230
230
|
|
|
231
231
|
class RequestFulfillment {
|
|
@@ -268,6 +268,14 @@ class RequestFulfillment {
|
|
|
268
268
|
this._requests[id] = request;
|
|
269
269
|
return request;
|
|
270
270
|
};
|
|
271
|
+
|
|
272
|
+
this.abort = id => {
|
|
273
|
+
delete this._requests[id];
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
this.abortAll = () => {
|
|
277
|
+
Object.keys(this._requests).forEach(id => this.abort(id));
|
|
278
|
+
};
|
|
271
279
|
}
|
|
272
280
|
|
|
273
281
|
static get Default() {
|
|
@@ -280,7 +288,7 @@ class RequestFulfillment {
|
|
|
280
288
|
|
|
281
289
|
}
|
|
282
290
|
|
|
283
|
-
const TrackerContext =
|
|
291
|
+
const TrackerContext = React.createContext(null);
|
|
284
292
|
|
|
285
293
|
let _default;
|
|
286
294
|
|
|
@@ -352,6 +360,77 @@ class RequestTracker {
|
|
|
352
360
|
|
|
353
361
|
}
|
|
354
362
|
|
|
363
|
+
const SSRCheck = () => {
|
|
364
|
+
if (Server.isServerSide()) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (process.env.NODE_ENV === "production") {
|
|
369
|
+
return new DataError("No CSR tracking", DataErrors.NotAllowed);
|
|
370
|
+
} else {
|
|
371
|
+
return new DataError("Data requests are not tracked for fulfillment when when client-side", DataErrors.NotAllowed);
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const fetchTrackedRequests = () => {
|
|
376
|
+
const ssrCheck = SSRCheck();
|
|
377
|
+
|
|
378
|
+
if (ssrCheck != null) {
|
|
379
|
+
return Promise.reject(ssrCheck);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return RequestTracker.Default.fulfillTrackedRequests();
|
|
383
|
+
};
|
|
384
|
+
const hasTrackedRequestsToBeFetched = () => {
|
|
385
|
+
const ssrCheck = SSRCheck();
|
|
386
|
+
|
|
387
|
+
if (ssrCheck != null) {
|
|
388
|
+
throw ssrCheck;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return RequestTracker.Default.hasUnfulfilledRequests;
|
|
392
|
+
};
|
|
393
|
+
const abortInflightRequests = () => {
|
|
394
|
+
RequestFulfillment.Default.abortAll();
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
const cache$1 = new ScopedInMemoryCache();
|
|
398
|
+
const purgeSharedCache = (scope = "") => {
|
|
399
|
+
if (scope && typeof scope === "string") {
|
|
400
|
+
cache$1.purgeScope(scope);
|
|
401
|
+
} else {
|
|
402
|
+
cache$1.purgeAll();
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
const useSharedCache = (id, scope, initialValue) => {
|
|
406
|
+
if (!id || typeof id !== "string") {
|
|
407
|
+
throw new DataError("id must be a non-empty string", DataErrors.InvalidInput);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (!scope || typeof scope !== "string") {
|
|
411
|
+
throw new DataError("scope must be a non-empty string", DataErrors.InvalidInput);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const cacheValue = React.useCallback(value => value == null ? cache$1.purge(scope, id) : cache$1.set(scope, id, value), [id, scope]);
|
|
415
|
+
let currentValue = cache$1.get(scope, id);
|
|
416
|
+
|
|
417
|
+
if (currentValue == null && initialValue !== undefined) {
|
|
418
|
+
const value = typeof initialValue === "function" ? initialValue() : initialValue;
|
|
419
|
+
|
|
420
|
+
if (value != null) {
|
|
421
|
+
cacheValue(value);
|
|
422
|
+
currentValue = value;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return [currentValue, cacheValue];
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const purgeCaches = () => {
|
|
430
|
+
purgeSharedCache();
|
|
431
|
+
purgeHydrationCache();
|
|
432
|
+
};
|
|
433
|
+
|
|
355
434
|
class TrackData extends React.Component {
|
|
356
435
|
render() {
|
|
357
436
|
if (!Server.isServerSide()) {
|
|
@@ -438,41 +517,12 @@ const useServerEffect = (requestId, handler, options = {}) => {
|
|
|
438
517
|
return cachedResult == null ? null : resultFromCachedResponse(cachedResult);
|
|
439
518
|
};
|
|
440
519
|
|
|
441
|
-
const cache = new ScopedInMemoryCache();
|
|
442
|
-
const clearSharedCache = (scope = "") => {
|
|
443
|
-
if (scope && typeof scope === "string") {
|
|
444
|
-
cache.purgeScope(scope);
|
|
445
|
-
} else {
|
|
446
|
-
cache.purgeAll();
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
const useSharedCache = (id, scope, initialValue) => {
|
|
450
|
-
if (!id || typeof id !== "string") {
|
|
451
|
-
throw new DataError("id must be a non-empty string", DataErrors.InvalidInput);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if (!scope || typeof scope !== "string") {
|
|
455
|
-
throw new DataError("scope must be a non-empty string", DataErrors.InvalidInput);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
const cacheValue = React.useCallback(value => value == null ? cache.purge(scope, id) : cache.set(scope, id, value), [id, scope]);
|
|
459
|
-
let currentValue = cache.get(scope, id);
|
|
460
|
-
|
|
461
|
-
if (currentValue == null && initialValue !== undefined) {
|
|
462
|
-
const value = typeof initialValue === "function" ? initialValue() : initialValue;
|
|
463
|
-
|
|
464
|
-
if (value != null) {
|
|
465
|
-
cacheValue(value);
|
|
466
|
-
currentValue = value;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
return [currentValue, cacheValue];
|
|
471
|
-
};
|
|
472
|
-
|
|
473
520
|
const DefaultScope$1 = "useCachedEffect";
|
|
474
521
|
const useCachedEffect = (requestId, handler, options = {}) => {
|
|
522
|
+
var _ref;
|
|
523
|
+
|
|
475
524
|
const {
|
|
525
|
+
fetchPolicy = FetchPolicy.CacheBeforeNetwork,
|
|
476
526
|
skip: hardSkip = false,
|
|
477
527
|
retainResultOnChange = false,
|
|
478
528
|
onResultChanged,
|
|
@@ -481,55 +531,102 @@ const useCachedEffect = (requestId, handler, options = {}) => {
|
|
|
481
531
|
const interceptedHandler = useRequestInterception(requestId, handler);
|
|
482
532
|
const [mostRecentResult, setMostRecentResult] = useSharedCache(requestId, scope);
|
|
483
533
|
const forceUpdate = useForceUpdate();
|
|
484
|
-
const
|
|
485
|
-
|
|
534
|
+
const networkResultRef = React.useRef();
|
|
535
|
+
const currentRequestRef = React.useRef();
|
|
536
|
+
const fetchRequest = React.useMemo(() => {
|
|
537
|
+
var _currentRequestRef$cu;
|
|
486
538
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
forceUpdate();
|
|
491
|
-
}
|
|
492
|
-
}, [setMostRecentResult, onResultChanged, forceUpdate]);
|
|
493
|
-
const requestIdRef = React.useRef();
|
|
494
|
-
const previousRequestId = requestIdRef.current;
|
|
495
|
-
const softSkip = React.useMemo(() => {
|
|
496
|
-
if (requestId === previousRequestId) {
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
539
|
+
(_currentRequestRef$cu = currentRequestRef.current) == null ? void 0 : _currentRequestRef$cu.cancel();
|
|
540
|
+
currentRequestRef.current = null;
|
|
541
|
+
networkResultRef.current = null;
|
|
499
542
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
}
|
|
543
|
+
const fetchFn = () => {
|
|
544
|
+
var _currentRequestRef$cu2, _currentRequestRef$cu3;
|
|
503
545
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
let cancel = false;
|
|
546
|
+
if (fetchPolicy === FetchPolicy.CacheOnly) {
|
|
547
|
+
throw new DataError("Cannot fetch with CacheOnly policy", DataErrors.NotAllowed);
|
|
548
|
+
}
|
|
508
549
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
550
|
+
const request = RequestFulfillment.Default.fulfill(`${requestId}|${scope}`, {
|
|
551
|
+
handler: interceptedHandler
|
|
552
|
+
});
|
|
512
553
|
|
|
513
|
-
|
|
514
|
-
RequestFulfillment.Default.fulfill(requestId, {
|
|
515
|
-
handler: interceptedHandler
|
|
516
|
-
}).then(result => {
|
|
517
|
-
if (cancel) {
|
|
554
|
+
if (request === ((_currentRequestRef$cu2 = currentRequestRef.current) == null ? void 0 : _currentRequestRef$cu2.request)) {
|
|
518
555
|
return;
|
|
519
556
|
}
|
|
520
557
|
|
|
521
|
-
|
|
558
|
+
networkResultRef.current = null;
|
|
559
|
+
(_currentRequestRef$cu3 = currentRequestRef.current) == null ? void 0 : _currentRequestRef$cu3.cancel();
|
|
560
|
+
let cancel = false;
|
|
561
|
+
request.then(result => {
|
|
562
|
+
currentRequestRef.current = null;
|
|
563
|
+
|
|
564
|
+
if (cancel) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
setMostRecentResult(result);
|
|
569
|
+
networkResultRef.current = result;
|
|
570
|
+
|
|
571
|
+
if (onResultChanged != null) {
|
|
572
|
+
onResultChanged(result);
|
|
573
|
+
} else {
|
|
574
|
+
forceUpdate();
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return;
|
|
578
|
+
});
|
|
579
|
+
currentRequestRef.current = {
|
|
580
|
+
requestId,
|
|
581
|
+
request,
|
|
582
|
+
|
|
583
|
+
cancel() {
|
|
584
|
+
cancel = true;
|
|
585
|
+
RequestFulfillment.Default.abort(requestId);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
return fetchFn;
|
|
592
|
+
}, [requestId, onResultChanged, forceUpdate, setMostRecentResult, fetchPolicy]);
|
|
593
|
+
const requestIdRef = React.useRef(requestId);
|
|
594
|
+
const shouldFetch = React.useMemo(() => {
|
|
595
|
+
if (hardSkip) {
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
switch (fetchPolicy) {
|
|
600
|
+
case FetchPolicy.CacheOnly:
|
|
601
|
+
return false;
|
|
602
|
+
|
|
603
|
+
case FetchPolicy.CacheBeforeNetwork:
|
|
604
|
+
return mostRecentResult == null || requestId !== requestIdRef.current;
|
|
605
|
+
|
|
606
|
+
case FetchPolicy.CacheAndNetwork:
|
|
607
|
+
case FetchPolicy.NetworkOnly:
|
|
608
|
+
return networkResultRef.current == null;
|
|
609
|
+
}
|
|
610
|
+
}, [requestId, mostRecentResult, fetchPolicy, hardSkip]);
|
|
611
|
+
requestIdRef.current = requestId;
|
|
612
|
+
React.useEffect(() => {
|
|
613
|
+
if (!shouldFetch) {
|
|
522
614
|
return;
|
|
523
|
-
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
fetchRequest();
|
|
524
618
|
return () => {
|
|
525
|
-
|
|
619
|
+
var _currentRequestRef$cu4;
|
|
620
|
+
|
|
621
|
+
(_currentRequestRef$cu4 = currentRequestRef.current) == null ? void 0 : _currentRequestRef$cu4.cancel();
|
|
622
|
+
currentRequestRef.current = null;
|
|
526
623
|
};
|
|
527
|
-
}, [
|
|
624
|
+
}, [shouldFetch, fetchRequest]);
|
|
528
625
|
const lastResultAgnosticOfIdRef = React.useRef(Status.loading());
|
|
529
626
|
const loadingResult = retainResultOnChange ? lastResultAgnosticOfIdRef.current : Status.loading();
|
|
530
|
-
const result =
|
|
627
|
+
const result = (_ref = fetchPolicy === FetchPolicy.NetworkOnly ? networkResultRef.current : mostRecentResult) != null ? _ref : loadingResult;
|
|
531
628
|
lastResultAgnosticOfIdRef.current = result;
|
|
532
|
-
return result;
|
|
629
|
+
return [result, fetchRequest];
|
|
533
630
|
};
|
|
534
631
|
|
|
535
632
|
const WhenClientSide = require("flow-enums-runtime").Mirrored(["DoNotHydrate", "ExecuteWhenNoResult", "ExecuteWhenNoSuccessResult", "AlwaysExecute"]);
|
|
@@ -564,11 +661,12 @@ const useHydratableEffect = (requestId, handler, options = {}) => {
|
|
|
564
661
|
}
|
|
565
662
|
}, [serverResult]);
|
|
566
663
|
useSharedCache(requestId, scope, getDefaultCacheValue);
|
|
567
|
-
const clientResult = useCachedEffect(requestId, handler, {
|
|
664
|
+
const [clientResult] = useCachedEffect(requestId, handler, {
|
|
568
665
|
skip,
|
|
569
666
|
onResultChanged,
|
|
570
667
|
retainResultOnChange,
|
|
571
|
-
scope
|
|
668
|
+
scope,
|
|
669
|
+
fetchPolicy: FetchPolicy.CacheBeforeNetwork
|
|
572
670
|
});
|
|
573
671
|
return serverResult != null ? serverResult : clientResult;
|
|
574
672
|
};
|
|
@@ -598,6 +696,110 @@ const InterceptRequests = ({
|
|
|
598
696
|
}, children);
|
|
599
697
|
};
|
|
600
698
|
|
|
699
|
+
const toString = valid => {
|
|
700
|
+
var _JSON$stringify;
|
|
701
|
+
|
|
702
|
+
if (typeof valid === "string") {
|
|
703
|
+
return valid;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return (_JSON$stringify = JSON.stringify(valid)) != null ? _JSON$stringify : "";
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
const getGqlRequestId = (operation, variables, context) => {
|
|
710
|
+
const parts = [];
|
|
711
|
+
const sortableContext = new URLSearchParams(context);
|
|
712
|
+
sortableContext.sort();
|
|
713
|
+
parts.push(sortableContext.toString());
|
|
714
|
+
parts.push(operation.id);
|
|
715
|
+
|
|
716
|
+
if (variables != null) {
|
|
717
|
+
const stringifiedVariables = Object.keys(variables).reduce((acc, key) => {
|
|
718
|
+
acc[key] = toString(variables[key]);
|
|
719
|
+
return acc;
|
|
720
|
+
}, {});
|
|
721
|
+
const sortableVariables = new URLSearchParams(stringifiedVariables);
|
|
722
|
+
sortableVariables.sort();
|
|
723
|
+
parts.push(sortableVariables.toString());
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
return parts.join("|");
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
const DocumentTypes = Object.freeze({
|
|
730
|
+
query: "query",
|
|
731
|
+
mutation: "mutation"
|
|
732
|
+
});
|
|
733
|
+
const cache = new Map();
|
|
734
|
+
function graphQLDocumentNodeParser(document) {
|
|
735
|
+
var _definition$name;
|
|
736
|
+
|
|
737
|
+
const cached = cache.get(document);
|
|
738
|
+
|
|
739
|
+
if (cached) {
|
|
740
|
+
return cached;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if (!(document != null && document.kind)) {
|
|
744
|
+
if (process.env.NODE_ENV === "production") {
|
|
745
|
+
throw new DataError("Bad DocumentNode", DataErrors.InvalidInput);
|
|
746
|
+
} else {
|
|
747
|
+
throw new DataError(`Argument of ${JSON.stringify(document)} passed to parser was not a valid GraphQL ` + `DocumentNode. You may need to use 'graphql-tag' or another method ` + `to convert your operation into a document`, DataErrors.InvalidInput);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
const fragments = document.definitions.filter(x => x.kind === "FragmentDefinition");
|
|
752
|
+
const queries = document.definitions.filter(x => x.kind === "OperationDefinition" && x.operation === "query");
|
|
753
|
+
const mutations = document.definitions.filter(x => x.kind === "OperationDefinition" && x.operation === "mutation");
|
|
754
|
+
const subscriptions = document.definitions.filter(x => x.kind === "OperationDefinition" && x.operation === "subscription");
|
|
755
|
+
|
|
756
|
+
if (fragments.length && !queries.length && !mutations.length) {
|
|
757
|
+
if (process.env.NODE_ENV === "production") {
|
|
758
|
+
throw new DataError("Fragment only", DataErrors.InvalidInput);
|
|
759
|
+
} else {
|
|
760
|
+
throw new DataError(`Passing only a fragment to 'graphql' is not supported. ` + `You must include a query or mutation as well`, DataErrors.InvalidInput);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
if (subscriptions.length) {
|
|
765
|
+
if (process.env.NODE_ENV === "production") {
|
|
766
|
+
throw new DataError("No subscriptions", DataErrors.InvalidInput);
|
|
767
|
+
} else {
|
|
768
|
+
throw new DataError(`We do not support subscriptions. ` + `${JSON.stringify(document)} had ${subscriptions.length} subscriptions`, DataErrors.InvalidInput);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (queries.length + mutations.length > 1) {
|
|
773
|
+
if (process.env.NODE_ENV === "production") {
|
|
774
|
+
throw new DataError("Too many ops", DataErrors.InvalidInput);
|
|
775
|
+
} else {
|
|
776
|
+
throw new DataError(`We only support one query or mutation per component. ` + `${JSON.stringify(document)} had ${queries.length} queries and ` + `${mutations.length} mutations. `, DataErrors.InvalidInput);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const type = queries.length ? DocumentTypes.query : DocumentTypes.mutation;
|
|
781
|
+
const definitions = queries.length ? queries : mutations;
|
|
782
|
+
const definition = definitions[0];
|
|
783
|
+
const variables = definition.variableDefinitions || [];
|
|
784
|
+
const name = ((_definition$name = definition.name) == null ? void 0 : _definition$name.kind) === "Name" ? definition.name.value : "data";
|
|
785
|
+
const payload = {
|
|
786
|
+
name,
|
|
787
|
+
type,
|
|
788
|
+
variables
|
|
789
|
+
};
|
|
790
|
+
cache.set(document, payload);
|
|
791
|
+
return payload;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const toGqlOperation = documentNode => {
|
|
795
|
+
const definition = graphQLDocumentNodeParser(documentNode);
|
|
796
|
+
const wbDataOperation = {
|
|
797
|
+
id: definition.name,
|
|
798
|
+
type: definition.type
|
|
799
|
+
};
|
|
800
|
+
return wbDataOperation;
|
|
801
|
+
};
|
|
802
|
+
|
|
601
803
|
const GqlRouterContext = React.createContext(null);
|
|
602
804
|
|
|
603
805
|
const GqlRouter = ({
|
|
@@ -739,22 +941,4 @@ const useGql = (context = {}) => {
|
|
|
739
941
|
return gqlFetch;
|
|
740
942
|
};
|
|
741
943
|
|
|
742
|
-
|
|
743
|
-
const fulfillAllDataRequests = () => {
|
|
744
|
-
if (!Server.isServerSide()) {
|
|
745
|
-
return Promise.reject(new Error("Data requests are not tracked when client-side"));
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
return RequestTracker.Default.fulfillTrackedRequests();
|
|
749
|
-
};
|
|
750
|
-
const hasUnfulfilledRequests = () => {
|
|
751
|
-
if (!Server.isServerSide()) {
|
|
752
|
-
throw new Error("Data requests are not tracked when client-side");
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
return RequestTracker.Default.hasUnfulfilledRequests;
|
|
756
|
-
};
|
|
757
|
-
const removeFromCache = id => SsrCache.Default.remove(id);
|
|
758
|
-
const removeAllFromCache = predicate => SsrCache.Default.removeAll(predicate);
|
|
759
|
-
|
|
760
|
-
export { Data, DataError, DataErrors, GqlError, GqlErrors, GqlRouter, InterceptRequests, RequestFulfillment, ScopedInMemoryCache, SerializableInMemoryCache, Status, TrackData, WhenClientSide, clearSharedCache, fulfillAllDataRequests, hasUnfulfilledRequests, initializeCache, removeAllFromCache, removeFromCache, useCachedEffect, useGql, useHydratableEffect, useServerEffect, useSharedCache };
|
|
944
|
+
export { Data, DataError, DataErrors, FetchPolicy, GqlError, GqlErrors, GqlRouter, InterceptRequests, ScopedInMemoryCache, SerializableInMemoryCache, Status, TrackData, WhenClientSide, abortInflightRequests, fetchTrackedRequests, getGqlRequestId, graphQLDocumentNodeParser, hasTrackedRequestsToBeFetched, initializeHydrationCache, purgeCaches, purgeHydrationCache, purgeSharedCache, toGqlOperation, useCachedEffect, useGql, useHydratableEffect, useServerEffect, useSharedCache };
|