@khanacademy/wonder-blocks-data 8.0.3 → 9.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 +19 -0
- package/dist/es/index.js +70 -78
- package/dist/index.js +130 -147
- package/package.json +2 -2
- 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-cached-effect.js +3 -14
- package/src/hooks/use-hydratable-effect.js +0 -4
- package/src/hooks/use-shared-cache.js +6 -14
- package/src/index.js +4 -2
- package/src/util/__tests__/purge-caches.test.js +2 -2
- 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 -5
- package/src/__docs__/exports.purge-shared-cache.stories.mdx +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-data
|
|
2
2
|
|
|
3
|
+
## 9.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 778f8e43: `SharedCache` export added for interacting with the shared in-memory cache. `purgeSharedCache` method has been removed.
|
|
8
|
+
- 778f8e43: Rename `ScopedCache` type to `RawScopedCache`
|
|
9
|
+
|
|
10
|
+
## 8.0.5
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 08238b89: Export the `getGqlDataFromResponse` method so we can use it in custom `gqlFetch` scenarios for a consistent experience
|
|
15
|
+
|
|
16
|
+
## 8.0.4
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- dc2e00f4: Do not fetch if FetchPolicy is CacheBeforeNetwork and there is already a cached value, even if the requestId changes
|
|
21
|
+
|
|
3
22
|
## 8.0.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/es/index.js
CHANGED
|
@@ -390,13 +390,7 @@ const abortInflightRequests = () => {
|
|
|
390
390
|
};
|
|
391
391
|
|
|
392
392
|
const cache$1 = new ScopedInMemoryCache();
|
|
393
|
-
const
|
|
394
|
-
if (scope && typeof scope === "string") {
|
|
395
|
-
cache$1.purgeScope(scope);
|
|
396
|
-
} else {
|
|
397
|
-
cache$1.purgeAll();
|
|
398
|
-
}
|
|
399
|
-
};
|
|
393
|
+
const SharedCache = cache$1;
|
|
400
394
|
const useSharedCache = (id, scope, initialValue) => {
|
|
401
395
|
if (!id || typeof id !== "string") {
|
|
402
396
|
throw new DataError("id must be a non-empty string", DataErrors.InvalidInput);
|
|
@@ -422,7 +416,7 @@ const useSharedCache = (id, scope, initialValue) => {
|
|
|
422
416
|
};
|
|
423
417
|
|
|
424
418
|
const purgeCaches = () => {
|
|
425
|
-
|
|
419
|
+
SharedCache.purgeAll();
|
|
426
420
|
purgeHydrationCache();
|
|
427
421
|
};
|
|
428
422
|
|
|
@@ -585,7 +579,6 @@ const useCachedEffect = (requestId, handler, options = {}) => {
|
|
|
585
579
|
|
|
586
580
|
return fetchFn;
|
|
587
581
|
}, [requestId, onResultChanged, forceUpdate, setMostRecentResult, fetchPolicy]);
|
|
588
|
-
const requestIdRef = React.useRef(requestId);
|
|
589
582
|
const shouldFetch = React.useMemo(() => {
|
|
590
583
|
if (hardSkip) {
|
|
591
584
|
return false;
|
|
@@ -596,14 +589,13 @@ const useCachedEffect = (requestId, handler, options = {}) => {
|
|
|
596
589
|
return false;
|
|
597
590
|
|
|
598
591
|
case FetchPolicy.CacheBeforeNetwork:
|
|
599
|
-
return mostRecentResult == null
|
|
592
|
+
return mostRecentResult == null;
|
|
600
593
|
|
|
601
594
|
case FetchPolicy.CacheAndNetwork:
|
|
602
595
|
case FetchPolicy.NetworkOnly:
|
|
603
596
|
return networkResultRef.current == null;
|
|
604
597
|
}
|
|
605
|
-
}, [
|
|
606
|
-
requestIdRef.current = requestId;
|
|
598
|
+
}, [mostRecentResult, fetchPolicy, hardSkip]);
|
|
607
599
|
React.useEffect(() => {
|
|
608
600
|
if (!shouldFetch) {
|
|
609
601
|
return;
|
|
@@ -721,6 +713,71 @@ const getGqlRequestId = (operation, variables, context) => {
|
|
|
721
713
|
return parts.join("|");
|
|
722
714
|
};
|
|
723
715
|
|
|
716
|
+
const GqlErrors = Object.freeze({
|
|
717
|
+
Internal: "Internal",
|
|
718
|
+
BadResponse: "BadResponse",
|
|
719
|
+
ErrorResult: "ErrorResult"
|
|
720
|
+
});
|
|
721
|
+
class GqlError extends KindError {
|
|
722
|
+
constructor(message, kind, {
|
|
723
|
+
metadata,
|
|
724
|
+
cause
|
|
725
|
+
} = {}) {
|
|
726
|
+
super(message, kind, {
|
|
727
|
+
metadata,
|
|
728
|
+
cause,
|
|
729
|
+
name: "Gql"
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
const getGqlDataFromResponse = async response => {
|
|
736
|
+
const bodyText = await response.text();
|
|
737
|
+
let result;
|
|
738
|
+
|
|
739
|
+
try {
|
|
740
|
+
result = JSON.parse(bodyText);
|
|
741
|
+
} catch (e) {
|
|
742
|
+
throw new DataError("Failed to parse response", DataErrors.Parse, {
|
|
743
|
+
metadata: {
|
|
744
|
+
statusCode: response.status,
|
|
745
|
+
bodyText
|
|
746
|
+
},
|
|
747
|
+
cause: e
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
if (response.status >= 300) {
|
|
752
|
+
throw new DataError("Response unsuccessful", DataErrors.Network, {
|
|
753
|
+
metadata: {
|
|
754
|
+
statusCode: response.status,
|
|
755
|
+
result
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (!Object.prototype.hasOwnProperty.call(result, "data") && !Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
761
|
+
throw new GqlError("Server response missing", GqlErrors.BadResponse, {
|
|
762
|
+
metadata: {
|
|
763
|
+
statusCode: response.status,
|
|
764
|
+
result
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
770
|
+
throw new GqlError("GraphQL errors", GqlErrors.ErrorResult, {
|
|
771
|
+
metadata: {
|
|
772
|
+
statusCode: response.status,
|
|
773
|
+
result
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
return result.data;
|
|
779
|
+
};
|
|
780
|
+
|
|
724
781
|
const DocumentTypes = Object.freeze({
|
|
725
782
|
query: "query",
|
|
726
783
|
mutation: "mutation"
|
|
@@ -825,25 +882,6 @@ const mergeGqlContext = (defaultContext, overrides) => {
|
|
|
825
882
|
}, _extends({}, defaultContext));
|
|
826
883
|
};
|
|
827
884
|
|
|
828
|
-
const GqlErrors = Object.freeze({
|
|
829
|
-
Internal: "Internal",
|
|
830
|
-
BadResponse: "BadResponse",
|
|
831
|
-
ErrorResult: "ErrorResult"
|
|
832
|
-
});
|
|
833
|
-
class GqlError extends KindError {
|
|
834
|
-
constructor(message, kind, {
|
|
835
|
-
metadata,
|
|
836
|
-
cause
|
|
837
|
-
} = {}) {
|
|
838
|
-
super(message, kind, {
|
|
839
|
-
metadata,
|
|
840
|
-
cause,
|
|
841
|
-
name: "Gql"
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
}
|
|
846
|
-
|
|
847
885
|
const useGqlRouterContext = (contextOverrides = {}) => {
|
|
848
886
|
const gqlRouterContext = useContext(GqlRouterContext);
|
|
849
887
|
|
|
@@ -873,52 +911,6 @@ const useGqlRouterContext = (contextOverrides = {}) => {
|
|
|
873
911
|
return finalRouterContext;
|
|
874
912
|
};
|
|
875
913
|
|
|
876
|
-
const getGqlDataFromResponse = async response => {
|
|
877
|
-
const bodyText = await response.text();
|
|
878
|
-
let result;
|
|
879
|
-
|
|
880
|
-
try {
|
|
881
|
-
result = JSON.parse(bodyText);
|
|
882
|
-
} catch (e) {
|
|
883
|
-
throw new DataError("Failed to parse response", DataErrors.Parse, {
|
|
884
|
-
metadata: {
|
|
885
|
-
statusCode: response.status,
|
|
886
|
-
bodyText
|
|
887
|
-
},
|
|
888
|
-
cause: e
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (response.status >= 300) {
|
|
893
|
-
throw new DataError("Response unsuccessful", DataErrors.Network, {
|
|
894
|
-
metadata: {
|
|
895
|
-
statusCode: response.status,
|
|
896
|
-
result
|
|
897
|
-
}
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
if (!Object.prototype.hasOwnProperty.call(result, "data") && !Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
902
|
-
throw new GqlError("Server response missing", GqlErrors.BadResponse, {
|
|
903
|
-
metadata: {
|
|
904
|
-
statusCode: response.status,
|
|
905
|
-
result
|
|
906
|
-
}
|
|
907
|
-
});
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
911
|
-
throw new GqlError("GraphQL errors", GqlErrors.ErrorResult, {
|
|
912
|
-
metadata: {
|
|
913
|
-
statusCode: response.status,
|
|
914
|
-
result
|
|
915
|
-
}
|
|
916
|
-
});
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
return result.data;
|
|
920
|
-
};
|
|
921
|
-
|
|
922
914
|
const useGql = (context = {}) => {
|
|
923
915
|
const gqlRouterContext = useGqlRouterContext(context);
|
|
924
916
|
const gqlFetch = useCallback((operation, options = Object.freeze({})) => {
|
|
@@ -936,4 +928,4 @@ const useGql = (context = {}) => {
|
|
|
936
928
|
return gqlFetch;
|
|
937
929
|
};
|
|
938
930
|
|
|
939
|
-
export { Data, DataError, DataErrors, FetchPolicy, GqlError, GqlErrors, GqlRouter, InterceptRequests, ScopedInMemoryCache, SerializableInMemoryCache, Status, TrackData, WhenClientSide, abortInflightRequests, fetchTrackedRequests, getGqlRequestId, graphQLDocumentNodeParser, hasTrackedRequestsToBeFetched, initializeHydrationCache, purgeCaches, purgeHydrationCache,
|
|
931
|
+
export { Data, DataError, DataErrors, FetchPolicy, GqlError, GqlErrors, GqlRouter, InterceptRequests, ScopedInMemoryCache, SerializableInMemoryCache, SharedCache, Status, TrackData, WhenClientSide, abortInflightRequests, fetchTrackedRequests, getGqlDataFromResponse, getGqlRequestId, graphQLDocumentNodeParser, hasTrackedRequestsToBeFetched, initializeHydrationCache, purgeCaches, purgeHydrationCache, toGqlOperation, useCachedEffect, useGql, useHydratableEffect, useServerEffect, useSharedCache };
|