@khanacademy/wonder-blocks-data 8.0.4 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/es/index.js +87 -80
- package/dist/index.js +177 -136
- package/package.json +1 -1
- package/src/__docs__/_overview_ssr_.stories.mdx +2 -2
- package/src/__docs__/exports.purge-caches.stories.mdx +1 -1
- package/src/__docs__/exports.scoped-in-memory-cache.stories.mdx +3 -3
- package/src/__docs__/exports.serializable-in-memory-cache.stories.mdx +2 -2
- package/src/__docs__/exports.shared-cache.stories.mdx +16 -0
- package/src/__docs__/exports.use-shared-cache.stories.mdx +2 -2
- package/src/__docs__/types.raw-scoped-cache.stories.mdx +27 -0
- package/src/__docs__/types.scoped-cache.stories.mdx +96 -9
- package/src/components/__tests__/data.test.js +2 -2
- package/src/hooks/__tests__/use-shared-cache.test.js +2 -50
- package/src/hooks/use-shared-cache.js +6 -14
- package/src/index.js +4 -2
- package/src/util/__tests__/get-gql-request-id.test.js +33 -0
- package/src/util/__tests__/purge-caches.test.js +2 -2
- package/src/util/get-gql-request-id.js +50 -6
- package/src/util/purge-caches.js +2 -2
- package/src/util/scoped-in-memory-cache.js +5 -9
- package/src/util/serializable-in-memory-cache.js +4 -8
- package/src/util/types.js +38 -1
- package/src/__docs__/exports.purge-shared-cache.stories.mdx +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-data
|
|
2
2
|
|
|
3
|
+
## 9.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 944c3071: Make sure objects and arrays in variables are sorted and readable in generated request identifiers
|
|
8
|
+
|
|
9
|
+
## 9.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 778f8e43: `SharedCache` export added for interacting with the shared in-memory cache. `purgeSharedCache` method has been removed.
|
|
14
|
+
- 778f8e43: Rename `ScopedCache` type to `RawScopedCache`
|
|
15
|
+
|
|
16
|
+
## 8.0.5
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 08238b89: Export the `getGqlDataFromResponse` method so we can use it in custom `gqlFetch` scenarios for a consistent experience
|
|
21
|
+
|
|
3
22
|
## 8.0.4
|
|
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
|
|
|
@@ -689,14 +683,27 @@ const InterceptRequests = ({
|
|
|
689
683
|
}, children);
|
|
690
684
|
};
|
|
691
685
|
|
|
692
|
-
const toString =
|
|
686
|
+
const toString = value => {
|
|
693
687
|
var _JSON$stringify;
|
|
694
688
|
|
|
695
|
-
if (typeof
|
|
696
|
-
return
|
|
689
|
+
if (typeof value === "string") {
|
|
690
|
+
return value;
|
|
697
691
|
}
|
|
698
692
|
|
|
699
|
-
return (_JSON$stringify = JSON.stringify(
|
|
693
|
+
return (_JSON$stringify = JSON.stringify(value)) != null ? _JSON$stringify : "";
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
const toStringifiedVariables = (acc, key, value) => {
|
|
697
|
+
if (typeof value === "object" && value !== null) {
|
|
698
|
+
return Object.entries(value).reduce((innerAcc, [i, v]) => {
|
|
699
|
+
const subKey = `${key}.${i}`;
|
|
700
|
+
return toStringifiedVariables(innerAcc, subKey, v);
|
|
701
|
+
}, acc);
|
|
702
|
+
} else {
|
|
703
|
+
acc[key] = toString(value);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return acc;
|
|
700
707
|
};
|
|
701
708
|
|
|
702
709
|
const getGqlRequestId = (operation, variables, context) => {
|
|
@@ -708,8 +715,8 @@ const getGqlRequestId = (operation, variables, context) => {
|
|
|
708
715
|
|
|
709
716
|
if (variables != null) {
|
|
710
717
|
const stringifiedVariables = Object.keys(variables).reduce((acc, key) => {
|
|
711
|
-
|
|
712
|
-
return acc;
|
|
718
|
+
const value = variables[key];
|
|
719
|
+
return toStringifiedVariables(acc, key, value);
|
|
713
720
|
}, {});
|
|
714
721
|
const sortableVariables = new URLSearchParams(stringifiedVariables);
|
|
715
722
|
sortableVariables.sort();
|
|
@@ -719,6 +726,71 @@ const getGqlRequestId = (operation, variables, context) => {
|
|
|
719
726
|
return parts.join("|");
|
|
720
727
|
};
|
|
721
728
|
|
|
729
|
+
const GqlErrors = Object.freeze({
|
|
730
|
+
Internal: "Internal",
|
|
731
|
+
BadResponse: "BadResponse",
|
|
732
|
+
ErrorResult: "ErrorResult"
|
|
733
|
+
});
|
|
734
|
+
class GqlError extends KindError {
|
|
735
|
+
constructor(message, kind, {
|
|
736
|
+
metadata,
|
|
737
|
+
cause
|
|
738
|
+
} = {}) {
|
|
739
|
+
super(message, kind, {
|
|
740
|
+
metadata,
|
|
741
|
+
cause,
|
|
742
|
+
name: "Gql"
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const getGqlDataFromResponse = async response => {
|
|
749
|
+
const bodyText = await response.text();
|
|
750
|
+
let result;
|
|
751
|
+
|
|
752
|
+
try {
|
|
753
|
+
result = JSON.parse(bodyText);
|
|
754
|
+
} catch (e) {
|
|
755
|
+
throw new DataError("Failed to parse response", DataErrors.Parse, {
|
|
756
|
+
metadata: {
|
|
757
|
+
statusCode: response.status,
|
|
758
|
+
bodyText
|
|
759
|
+
},
|
|
760
|
+
cause: e
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
if (response.status >= 300) {
|
|
765
|
+
throw new DataError("Response unsuccessful", DataErrors.Network, {
|
|
766
|
+
metadata: {
|
|
767
|
+
statusCode: response.status,
|
|
768
|
+
result
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (!Object.prototype.hasOwnProperty.call(result, "data") && !Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
774
|
+
throw new GqlError("Server response missing", GqlErrors.BadResponse, {
|
|
775
|
+
metadata: {
|
|
776
|
+
statusCode: response.status,
|
|
777
|
+
result
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
783
|
+
throw new GqlError("GraphQL errors", GqlErrors.ErrorResult, {
|
|
784
|
+
metadata: {
|
|
785
|
+
statusCode: response.status,
|
|
786
|
+
result
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
return result.data;
|
|
792
|
+
};
|
|
793
|
+
|
|
722
794
|
const DocumentTypes = Object.freeze({
|
|
723
795
|
query: "query",
|
|
724
796
|
mutation: "mutation"
|
|
@@ -823,25 +895,6 @@ const mergeGqlContext = (defaultContext, overrides) => {
|
|
|
823
895
|
}, _extends({}, defaultContext));
|
|
824
896
|
};
|
|
825
897
|
|
|
826
|
-
const GqlErrors = Object.freeze({
|
|
827
|
-
Internal: "Internal",
|
|
828
|
-
BadResponse: "BadResponse",
|
|
829
|
-
ErrorResult: "ErrorResult"
|
|
830
|
-
});
|
|
831
|
-
class GqlError extends KindError {
|
|
832
|
-
constructor(message, kind, {
|
|
833
|
-
metadata,
|
|
834
|
-
cause
|
|
835
|
-
} = {}) {
|
|
836
|
-
super(message, kind, {
|
|
837
|
-
metadata,
|
|
838
|
-
cause,
|
|
839
|
-
name: "Gql"
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
|
|
845
898
|
const useGqlRouterContext = (contextOverrides = {}) => {
|
|
846
899
|
const gqlRouterContext = useContext(GqlRouterContext);
|
|
847
900
|
|
|
@@ -871,52 +924,6 @@ const useGqlRouterContext = (contextOverrides = {}) => {
|
|
|
871
924
|
return finalRouterContext;
|
|
872
925
|
};
|
|
873
926
|
|
|
874
|
-
const getGqlDataFromResponse = async response => {
|
|
875
|
-
const bodyText = await response.text();
|
|
876
|
-
let result;
|
|
877
|
-
|
|
878
|
-
try {
|
|
879
|
-
result = JSON.parse(bodyText);
|
|
880
|
-
} catch (e) {
|
|
881
|
-
throw new DataError("Failed to parse response", DataErrors.Parse, {
|
|
882
|
-
metadata: {
|
|
883
|
-
statusCode: response.status,
|
|
884
|
-
bodyText
|
|
885
|
-
},
|
|
886
|
-
cause: e
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
if (response.status >= 300) {
|
|
891
|
-
throw new DataError("Response unsuccessful", DataErrors.Network, {
|
|
892
|
-
metadata: {
|
|
893
|
-
statusCode: response.status,
|
|
894
|
-
result
|
|
895
|
-
}
|
|
896
|
-
});
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
if (!Object.prototype.hasOwnProperty.call(result, "data") && !Object.prototype.hasOwnProperty.call(result, "errors")) {
|
|
900
|
-
throw new GqlError("Server response missing", GqlErrors.BadResponse, {
|
|
901
|
-
metadata: {
|
|
902
|
-
statusCode: response.status,
|
|
903
|
-
result
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
if (result.errors != null && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
909
|
-
throw new GqlError("GraphQL errors", GqlErrors.ErrorResult, {
|
|
910
|
-
metadata: {
|
|
911
|
-
statusCode: response.status,
|
|
912
|
-
result
|
|
913
|
-
}
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
return result.data;
|
|
918
|
-
};
|
|
919
|
-
|
|
920
927
|
const useGql = (context = {}) => {
|
|
921
928
|
const gqlRouterContext = useGqlRouterContext(context);
|
|
922
929
|
const gqlFetch = useCallback((operation, options = Object.freeze({})) => {
|
|
@@ -934,4 +941,4 @@ const useGql = (context = {}) => {
|
|
|
934
941
|
return gqlFetch;
|
|
935
942
|
};
|
|
936
943
|
|
|
937
|
-
export { Data, DataError, DataErrors, FetchPolicy, GqlError, GqlErrors, GqlRouter, InterceptRequests, ScopedInMemoryCache, SerializableInMemoryCache, Status, TrackData, WhenClientSide, abortInflightRequests, fetchTrackedRequests, getGqlRequestId, graphQLDocumentNodeParser, hasTrackedRequestsToBeFetched, initializeHydrationCache, purgeCaches, purgeHydrationCache,
|
|
944
|
+
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 };
|