@khanacademy/wonder-blocks-data 10.0.5 → 10.1.1

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.
Files changed (181) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/components/data.d.ts +52 -0
  3. package/dist/components/data.js.flow +63 -0
  4. package/dist/components/gql-router.d.ts +24 -0
  5. package/dist/components/gql-router.js.flow +33 -0
  6. package/dist/components/intercept-context.d.ts +10 -0
  7. package/dist/components/intercept-context.js.flow +19 -0
  8. package/dist/components/intercept-requests.d.ts +42 -0
  9. package/dist/components/intercept-requests.js.flow +51 -0
  10. package/dist/components/track-data.d.ts +11 -0
  11. package/dist/components/track-data.js.flow +18 -0
  12. package/dist/es/index.js +196 -214
  13. package/dist/hooks/use-cached-effect.d.ts +70 -0
  14. package/dist/hooks/use-cached-effect.js.flow +85 -0
  15. package/dist/hooks/use-gql-router-context.d.ts +5 -0
  16. package/dist/hooks/use-gql-router-context.js.flow +15 -0
  17. package/dist/hooks/use-gql.d.ts +12 -0
  18. package/dist/hooks/use-gql.js.flow +29 -0
  19. package/dist/hooks/use-hydratable-effect.d.ts +102 -0
  20. package/dist/hooks/use-hydratable-effect.js.flow +125 -0
  21. package/dist/hooks/use-request-interception.d.ts +14 -0
  22. package/dist/hooks/use-request-interception.js.flow +25 -0
  23. package/dist/hooks/use-server-effect.d.ts +39 -0
  24. package/dist/hooks/use-server-effect.js.flow +51 -0
  25. package/dist/hooks/use-shared-cache.d.ts +32 -0
  26. package/dist/hooks/use-shared-cache.js.flow +43 -0
  27. package/dist/index.d.ts +24 -0
  28. package/dist/index.js +198 -219
  29. package/dist/index.js.flow +48 -2
  30. package/dist/util/data-error.d.ts +45 -0
  31. package/dist/util/data-error.js.flow +64 -0
  32. package/dist/util/get-gql-data-from-response.d.ts +4 -0
  33. package/dist/util/get-gql-data-from-response.js.flow +13 -0
  34. package/dist/util/get-gql-request-id.d.ts +5 -0
  35. package/dist/util/get-gql-request-id.js.flow +20 -0
  36. package/dist/util/gql-error.d.ts +28 -0
  37. package/dist/util/gql-error.js.flow +43 -0
  38. package/dist/util/gql-router-context.d.ts +3 -0
  39. package/dist/util/gql-router-context.js.flow +10 -0
  40. package/dist/util/gql-types.d.ts +34 -0
  41. package/dist/util/gql-types.js.flow +53 -0
  42. package/dist/util/graphql-document-node-parser.d.ts +18 -0
  43. package/dist/util/graphql-document-node-parser.js.flow +31 -0
  44. package/dist/util/graphql-types.d.ts +19 -0
  45. package/dist/util/graphql-types.js.flow +30 -0
  46. package/dist/util/hydration-cache-api.d.ts +17 -0
  47. package/dist/util/hydration-cache-api.js.flow +30 -0
  48. package/dist/util/merge-gql-context.d.ts +8 -0
  49. package/dist/util/merge-gql-context.js.flow +19 -0
  50. package/dist/util/purge-caches.d.ts +8 -0
  51. package/dist/util/purge-caches.js.flow +15 -0
  52. package/dist/util/request-api.d.ts +28 -0
  53. package/dist/util/request-api.js.flow +34 -0
  54. package/dist/util/request-fulfillment.d.ts +37 -0
  55. package/dist/util/request-fulfillment.js.flow +50 -0
  56. package/dist/util/request-tracking.d.ts +62 -0
  57. package/dist/util/request-tracking.js.flow +81 -0
  58. package/dist/util/result-from-cache-response.d.ts +5 -0
  59. package/dist/util/result-from-cache-response.js.flow +15 -0
  60. package/dist/util/scoped-in-memory-cache.d.ts +38 -0
  61. package/dist/util/scoped-in-memory-cache.js.flow +57 -0
  62. package/dist/util/serializable-in-memory-cache.d.ts +16 -0
  63. package/dist/util/serializable-in-memory-cache.js.flow +26 -0
  64. package/dist/util/ssr-cache.d.ts +51 -0
  65. package/dist/util/ssr-cache.js.flow +87 -0
  66. package/dist/util/status.d.ts +10 -0
  67. package/dist/util/status.js.flow +19 -0
  68. package/dist/util/to-gql-operation.d.ts +32 -0
  69. package/dist/util/to-gql-operation.js.flow +45 -0
  70. package/dist/util/types.d.ts +111 -0
  71. package/dist/util/types.js.flow +151 -0
  72. package/package.json +5 -6
  73. package/src/components/__tests__/{data.test.js → data.test.tsx} +50 -16
  74. package/src/components/__tests__/{gql-router.test.js → gql-router.test.tsx} +6 -7
  75. package/src/components/__tests__/{intercept-requests.test.js → intercept-requests.test.tsx} +4 -5
  76. package/src/components/__tests__/{track-data.test.js → track-data.test.tsx} +4 -5
  77. package/src/components/{data.js → data.ts} +13 -21
  78. package/src/components/{gql-router.js → gql-router.tsx} +14 -16
  79. package/src/components/{intercept-context.js → intercept-context.ts} +5 -4
  80. package/src/components/{intercept-requests.js → intercept-requests.tsx} +9 -10
  81. package/src/components/{track-data.js → track-data.tsx} +5 -6
  82. package/src/hooks/__tests__/{use-cached-effect.test.js → use-cached-effect.test.tsx} +65 -63
  83. package/src/hooks/__tests__/{use-gql-router-context.test.js → use-gql-router-context.test.tsx} +9 -9
  84. package/src/hooks/__tests__/{use-gql.test.js → use-gql.test.tsx} +23 -24
  85. package/src/hooks/__tests__/{use-hydratable-effect.test.js → use-hydratable-effect.test.ts} +52 -54
  86. package/src/hooks/__tests__/{use-request-interception.test.js → use-request-interception.test.tsx} +7 -5
  87. package/src/hooks/__tests__/{use-server-effect.test.js → use-server-effect.test.ts} +16 -10
  88. package/src/hooks/__tests__/{use-shared-cache.test.js → use-shared-cache.test.ts} +13 -13
  89. package/src/hooks/{use-cached-effect.js → use-cached-effect.ts} +34 -31
  90. package/src/hooks/{use-gql-router-context.js → use-gql-router-context.ts} +6 -7
  91. package/src/hooks/{use-gql.js → use-gql.ts} +9 -9
  92. package/src/hooks/{use-hydratable-effect.js → use-hydratable-effect.ts} +60 -67
  93. package/src/hooks/{use-request-interception.js → use-request-interception.ts} +6 -6
  94. package/src/hooks/{use-server-effect.js → use-server-effect.ts} +12 -14
  95. package/src/hooks/{use-shared-cache.js → use-shared-cache.ts} +16 -11
  96. package/src/index.ts +46 -0
  97. package/src/util/__tests__/{get-gql-data-from-response.test.js → get-gql-data-from-response.test.ts} +1 -2
  98. package/src/util/__tests__/{get-gql-request-id.test.js → get-gql-request-id.test.ts} +10 -12
  99. package/src/util/__tests__/{graphql-document-node-parser.test.js → graphql-document-node-parser.test.ts} +12 -13
  100. package/src/util/__tests__/{hydration-cache-api.test.js → hydration-cache-api.test.ts} +3 -4
  101. package/src/util/__tests__/{merge-gql-context.test.js → merge-gql-context.test.ts} +5 -6
  102. package/src/util/__tests__/{purge-caches.test.js → purge-caches.test.ts} +3 -4
  103. package/src/util/__tests__/{request-api.test.js → request-api.test.ts} +5 -5
  104. package/src/util/__tests__/{request-fulfillment.test.js → request-fulfillment.test.ts} +2 -3
  105. package/src/util/__tests__/{request-tracking.test.js → request-tracking.test.tsx} +15 -8
  106. package/src/util/__tests__/{result-from-cache-response.test.js → result-from-cache-response.test.ts} +3 -5
  107. package/src/util/__tests__/{scoped-in-memory-cache.test.js → scoped-in-memory-cache.test.ts} +5 -6
  108. package/src/util/__tests__/{serializable-in-memory-cache.test.js → serializable-in-memory-cache.test.ts} +8 -8
  109. package/src/util/__tests__/{ssr-cache.test.js → ssr-cache.test.ts} +5 -4
  110. package/src/util/__tests__/{to-gql-operation.test.js → to-gql-operation.test.ts} +5 -4
  111. package/src/util/{data-error.js → data-error.ts} +3 -4
  112. package/src/util/{get-gql-data-from-response.js → get-gql-data-from-response.ts} +3 -8
  113. package/src/util/{get-gql-request-id.js → get-gql-request-id.ts} +13 -17
  114. package/src/util/{gql-error.js → gql-error.ts} +3 -4
  115. package/src/util/gql-router-context.ts +6 -0
  116. package/src/util/{gql-types.js → gql-types.ts} +27 -23
  117. package/src/util/{graphql-document-node-parser.js → graphql-document-node-parser.ts} +8 -9
  118. package/src/util/graphql-types.ts +27 -0
  119. package/src/util/{hydration-cache-api.js → hydration-cache-api.ts} +6 -4
  120. package/src/util/{merge-gql-context.js → merge-gql-context.ts} +3 -3
  121. package/src/util/{purge-caches.js → purge-caches.ts} +2 -3
  122. package/src/util/{request-api.js → request-api.ts} +4 -5
  123. package/src/util/{request-fulfillment.js → request-fulfillment.ts} +15 -14
  124. package/src/util/{request-tracking.js → request-tracking.ts} +15 -16
  125. package/src/util/{result-from-cache-response.js → result-from-cache-response.ts} +6 -7
  126. package/src/util/{scoped-in-memory-cache.js → scoped-in-memory-cache.ts} +3 -4
  127. package/src/util/{serializable-in-memory-cache.js → serializable-in-memory-cache.ts} +5 -6
  128. package/src/util/{ssr-cache.js → ssr-cache.ts} +21 -20
  129. package/src/util/{status.js → status.ts} +5 -6
  130. package/src/util/{to-gql-operation.js → to-gql-operation.ts} +4 -5
  131. package/src/util/{types.js → types.ts} +41 -49
  132. package/tsconfig.json +11 -0
  133. package/tsconfig.tsbuildinfo +1 -0
  134. package/src/__docs__/_overview_.stories.mdx +0 -18
  135. package/src/__docs__/_overview_graphql.stories.mdx +0 -35
  136. package/src/__docs__/_overview_ssr_.stories.mdx +0 -185
  137. package/src/__docs__/_overview_testing_.stories.mdx +0 -123
  138. package/src/__docs__/exports.abort-inflight-requests.stories.mdx +0 -20
  139. package/src/__docs__/exports.data-error.stories.mdx +0 -23
  140. package/src/__docs__/exports.data-errors.stories.mdx +0 -23
  141. package/src/__docs__/exports.data.stories.mdx +0 -146
  142. package/src/__docs__/exports.fetch-tracked-requests.stories.mdx +0 -24
  143. package/src/__docs__/exports.get-gql-request-id.stories.mdx +0 -24
  144. package/src/__docs__/exports.gql-error.stories.mdx +0 -23
  145. package/src/__docs__/exports.gql-errors.stories.mdx +0 -20
  146. package/src/__docs__/exports.gql-router.stories.mdx +0 -29
  147. package/src/__docs__/exports.has-tracked-requests-to-be-fetched.stories.mdx +0 -20
  148. package/src/__docs__/exports.intercept-requests.stories.mdx +0 -69
  149. package/src/__docs__/exports.intialize-hydration-cache.stories.mdx +0 -29
  150. package/src/__docs__/exports.purge-caches.stories.mdx +0 -23
  151. package/src/__docs__/exports.purge-hydration-cache.stories.mdx +0 -24
  152. package/src/__docs__/exports.scoped-in-memory-cache.stories.mdx +0 -92
  153. package/src/__docs__/exports.serializable-in-memory-cache.stories.mdx +0 -112
  154. package/src/__docs__/exports.shared-cache.stories.mdx +0 -16
  155. package/src/__docs__/exports.status.stories.mdx +0 -31
  156. package/src/__docs__/exports.track-data.stories.mdx +0 -209
  157. package/src/__docs__/exports.use-cached-effect.stories.mdx +0 -44
  158. package/src/__docs__/exports.use-gql.stories.mdx +0 -41
  159. package/src/__docs__/exports.use-hydratable-effect.stories.mdx +0 -43
  160. package/src/__docs__/exports.use-server-effect.stories.mdx +0 -50
  161. package/src/__docs__/exports.use-shared-cache.stories.mdx +0 -30
  162. package/src/__docs__/exports.when-client-side.stories.mdx +0 -33
  163. package/src/__docs__/types.cached-response.stories.mdx +0 -29
  164. package/src/__docs__/types.error-options.stories.mdx +0 -21
  165. package/src/__docs__/types.fetch-policy.stories.mdx +0 -44
  166. package/src/__docs__/types.gql-context.stories.mdx +0 -20
  167. package/src/__docs__/types.gql-fetch-fn.stories.mdx +0 -24
  168. package/src/__docs__/types.gql-fetch-options.stories.mdx +0 -24
  169. package/src/__docs__/types.gql-operation-type.stories.mdx +0 -24
  170. package/src/__docs__/types.gql-operation.stories.mdx +0 -67
  171. package/src/__docs__/types.raw-scoped-cache.stories.mdx +0 -27
  172. package/src/__docs__/types.response-cache.stories.mdx +0 -33
  173. package/src/__docs__/types.result.stories.mdx +0 -39
  174. package/src/__docs__/types.scoped-cache.stories.mdx +0 -114
  175. package/src/__docs__/types.valid-cache-data.stories.mdx +0 -23
  176. package/src/index.js +0 -55
  177. package/src/util/gql-router-context.js +0 -6
  178. package/src/util/graphql-types.js +0 -30
  179. /package/src/hooks/__tests__/__snapshots__/{use-shared-cache.test.js.snap → use-shared-cache.test.ts.snap} +0 -0
  180. /package/src/util/__tests__/__snapshots__/{scoped-in-memory-cache.test.js.snap → scoped-in-memory-cache.test.ts.snap} +0 -0
  181. /package/src/util/__tests__/__snapshots__/{serializable-in-memory-cache.test.js.snap → serializable-in-memory-cache.test.ts.snap} +0 -0
@@ -1,6 +1,5 @@
1
- // @flow
2
- import {DataError, DataErrors} from "./data-error.js";
3
- import {GqlError, GqlErrors} from "./gql-error.js";
1
+ import {DataError, DataErrors} from "./data-error";
2
+ import {GqlError, GqlErrors} from "./gql-error";
4
3
 
5
4
  /**
6
5
  * Validate a GQL operation response and extract the data.
@@ -14,7 +13,7 @@ export const getGqlDataFromResponse = async <TData>(
14
13
  let result;
15
14
  try {
16
15
  result = JSON.parse(bodyText);
17
- } catch (e) {
16
+ } catch (e: any) {
18
17
  throw new DataError("Failed to parse response", DataErrors.Parse, {
19
18
  metadata: {
20
19
  statusCode: response.status,
@@ -36,11 +35,7 @@ export const getGqlDataFromResponse = async <TData>(
36
35
 
37
36
  // Check that we have a valid result payload.
38
37
  if (
39
- // Flow shouldn't be warning about this.
40
- // $FlowIgnore[method-unbinding]
41
38
  !Object.prototype.hasOwnProperty.call(result, "data") &&
42
- // Flow shouldn't be warning about this.
43
- // $FlowIgnore[method-unbinding]
44
39
  !Object.prototype.hasOwnProperty.call(result, "errors")
45
40
  ) {
46
41
  throw new GqlError("Server response missing", GqlErrors.BadResponse, {
@@ -1,8 +1,7 @@
1
- // @flow
2
1
  import {entries} from "@khanacademy/wonder-stuff-core";
3
- import type {GqlOperation, GqlContext} from "./gql-types.js";
2
+ import type {GqlOperation, GqlContext} from "./gql-types";
4
3
 
5
- const toString = (value: mixed): string => {
4
+ const toString = (value: unknown): string => {
6
5
  if (typeof value === "string") {
7
6
  return value;
8
7
  }
@@ -17,7 +16,7 @@ const toString = (value: mixed): string => {
17
16
  return JSON.stringify(value) ?? "";
18
17
  };
19
18
 
20
- const toStringifiedVariables = (acc: any, key: string, value: mixed): any => {
19
+ const toStringifiedVariables = (acc: any, key: string, value: unknown): any => {
21
20
  if (typeof value === "object" && value !== null) {
22
21
  // If we have an object or array, we build sub-variables so that
23
22
  // the ID is easily human-readable rather than having lots of
@@ -30,7 +29,7 @@ const toStringifiedVariables = (acc: any, key: string, value: mixed): any => {
30
29
  // or some other non-standard value. While these generally should be
31
30
  // avoided as variables, we should handle them gracefully.
32
31
  if (subValues.length !== 0) {
33
- return subValues.reduce((innerAcc, [i, v]) => {
32
+ return subValues.reduce((innerAcc, [i, v]: [any, any]) => {
34
33
  const subKey = `${key}.${i}`;
35
34
  return toStringifiedVariables(innerAcc, subKey, v);
36
35
  }, acc);
@@ -44,18 +43,17 @@ const toStringifiedVariables = (acc: any, key: string, value: mixed): any => {
44
43
  /**
45
44
  * Get an identifier for a given request.
46
45
  */
47
- export const getGqlRequestId = <TData, TVariables: {...}>(
46
+ export const getGqlRequestId = <TData, TVariables extends Record<any, any>>(
48
47
  operation: GqlOperation<TData, TVariables>,
49
- variables: ?TVariables,
48
+ variables: TVariables | null | undefined,
50
49
  context: GqlContext,
51
50
  ): string => {
52
51
  // We add all the bits for this into an array and then join them with
53
52
  // a chosen separator.
54
- const parts = [];
53
+ const parts: Array<string> = [];
55
54
 
56
55
  // First, we push the context values.
57
56
  const sortableContext = new URLSearchParams(context);
58
- // $FlowIgnore[prop-missing] Flow has incomplete support for URLSearchParams
59
57
  sortableContext.sort();
60
58
  parts.push(sortableContext.toString());
61
59
 
@@ -92,17 +90,15 @@ export const getGqlRequestId = <TData, TVariables: {...}>(
92
90
  // Thus allowing our use of URLSearchParams to both sort and easily
93
91
  // encode the variables into an idempotent identifier for those
94
92
  // variable values that is also human-readable.
95
- const stringifiedVariables = Object.keys(variables).reduce(
96
- (acc, key) => {
97
- const value = variables[key];
98
- return toStringifiedVariables(acc, key, value);
99
- },
100
- {},
101
- );
93
+ const stringifiedVariables = Object.keys(variables).reduce<
94
+ Record<string, any>
95
+ >((acc, key) => {
96
+ const value = variables[key];
97
+ return toStringifiedVariables(acc, key, value);
98
+ }, {});
102
99
  // We use the same mechanism as context to sort and arrange the
103
100
  // variables.
104
101
  const sortableVariables = new URLSearchParams(stringifiedVariables);
105
- // $FlowIgnore[prop-missing] Flow has incomplete support for URLSearchParams
106
102
  sortableVariables.sort();
107
103
  parts.push(sortableVariables.toString());
108
104
  }
@@ -1,7 +1,6 @@
1
- // @flow
2
1
  import {KindError} from "@khanacademy/wonder-stuff-core";
3
2
 
4
- import type {ErrorOptions} from "./types.js";
3
+ import type {ErrorOptions} from "./types";
5
4
 
6
5
  /**
7
6
  * Error kinds for GqlError.
@@ -32,8 +31,8 @@ export const GqlErrors = Object.freeze({
32
31
  export class GqlError extends KindError {
33
32
  constructor(
34
33
  message: string,
35
- kind: $Values<typeof GqlErrors>,
36
- {metadata, cause}: ErrorOptions = ({}: $Shape<ErrorOptions>),
34
+ kind: typeof GqlErrors[keyof typeof GqlErrors],
35
+ {metadata, cause}: ErrorOptions = {} as Partial<ErrorOptions>,
37
36
  ) {
38
37
  super(message, kind, {
39
38
  metadata,
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import type {GqlRouterConfiguration} from "./gql-types";
3
+
4
+ export const GqlRouterContext: React.Context<
5
+ GqlRouterConfiguration<any> | null | undefined
6
+ > = React.createContext<GqlRouterConfiguration<any> | null | undefined>(null);
@@ -1,4 +1,3 @@
1
- // @flow
2
1
  /**
3
2
  * Operation types.
4
3
  */
@@ -11,50 +10,55 @@ export type GqlOperation<
11
10
  // TData is not used to define a field on this type, but it is used
12
11
  // to ensure that calls using this operation will properly return the
13
12
  // correct data type.
14
- // eslint-disable-next-line no-unused-vars
15
- TData,
16
- // TVariables is not used to define a field on this type, but it is used
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+ TData, // TVariables is not used to define a field on this type, but it is used
17
15
  // to ensure that calls using this operation will properly consume the
18
16
  // correct variables type.
19
- // eslint-disable-next-line no-unused-vars
20
- TVariables: {...} = Empty,
17
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
+ TVariables extends object = Empty,
21
19
  > = {
22
- type: GqlOperationType,
23
- id: string,
20
+ type: GqlOperationType;
21
+ id: string;
24
22
  // We allow other things here to be passed along to the fetch function.
25
23
  // For example, we might want to pass the full query/mutation definition
26
24
  // as a string here to allow that to be sent to an Apollo server that
27
25
  // expects it. This is a courtesy to calling code; these additional
28
26
  // values are ignored by WB Data, and passed through as-is.
29
- [key: string]: mixed,
30
- ...
27
+ [key: string]: unknown;
31
28
  };
32
29
 
33
- export type GqlContext = {|
34
- [key: string]: string,
35
- |};
30
+ export type GqlContext = {
31
+ [key: string]: string;
32
+ };
36
33
 
37
34
  /**
38
35
  * Functions that make fetches of GQL operations.
39
36
  */
40
- export type GqlFetchFn<TData, TVariables: {...}, TContext: GqlContext> = (
37
+ export type GqlFetchFn<
38
+ TData,
39
+ TVariables extends Record<any, any>,
40
+ TContext extends GqlContext,
41
+ > = (
41
42
  operation: GqlOperation<TData, TVariables>,
42
- variables: ?TVariables,
43
+ variables: TVariables | null | undefined,
43
44
  context: TContext,
44
45
  ) => Promise<Response>;
45
46
 
46
47
  /**
47
48
  * The configuration stored in the GqlRouterContext context.
48
49
  */
49
- export type GqlRouterConfiguration<TContext: GqlContext> = {|
50
- fetch: GqlFetchFn<any, any, any>,
51
- defaultContext: TContext,
52
- |};
50
+ export type GqlRouterConfiguration<TContext extends GqlContext> = {
51
+ fetch: GqlFetchFn<any, any, any>;
52
+ defaultContext: TContext;
53
+ };
53
54
 
54
55
  /**
55
56
  * Options for configuring a GQL fetch.
56
57
  */
57
- export type GqlFetchOptions<TVariables: {...}, TContext: GqlContext> = {|
58
- variables?: TVariables,
59
- context?: Partial<TContext>,
60
- |};
58
+ export type GqlFetchOptions<
59
+ TVariables extends Record<any, any>,
60
+ TContext extends GqlContext,
61
+ > = {
62
+ variables?: TVariables;
63
+ context?: Partial<TContext>;
64
+ };
@@ -1,23 +1,22 @@
1
- // @flow
2
1
  import type {
3
2
  DocumentNode,
4
3
  DefinitionNode,
5
4
  VariableDefinitionNode,
6
5
  OperationDefinitionNode,
7
- } from "./graphql-types.js";
8
- import {DataError, DataErrors} from "./data-error.js";
6
+ } from "./graphql-types";
7
+ import {DataError, DataErrors} from "./data-error";
9
8
 
10
9
  export const DocumentTypes = Object.freeze({
11
10
  query: "query",
12
11
  mutation: "mutation",
13
12
  });
14
13
 
15
- export type DocumentType = $Values<typeof DocumentTypes>;
14
+ export type DocumentType = typeof DocumentTypes[keyof typeof DocumentTypes];
16
15
 
17
16
  export interface IDocumentDefinition {
18
17
  type: DocumentType;
19
18
  name: string;
20
- variables: $ReadOnlyArray<VariableDefinitionNode>;
19
+ variables: ReadonlyArray<VariableDefinitionNode>;
21
20
  }
22
21
 
23
22
  const cache = new Map<DocumentNode, IDocumentDefinition>();
@@ -60,19 +59,19 @@ export function graphQLDocumentNodeParser(
60
59
 
61
60
  const queries = document.definitions.filter(
62
61
  (x: DefinitionNode) =>
63
- // $FlowIgnore[prop-missing]
62
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'operation' does not exist on type 'DefinitionNode'.
64
63
  x.kind === "OperationDefinition" && x.operation === "query",
65
64
  );
66
65
 
67
66
  const mutations = document.definitions.filter(
68
67
  (x: DefinitionNode) =>
69
- // $FlowIgnore[prop-missing]
68
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'operation' does not exist on type 'DefinitionNode'.
70
69
  x.kind === "OperationDefinition" && x.operation === "mutation",
71
70
  );
72
71
 
73
72
  const subscriptions = document.definitions.filter(
74
73
  (x: DefinitionNode) =>
75
- // $FlowIgnore[prop-missing]
74
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'operation' does not exist on type 'DefinitionNode'.
76
75
  x.kind === "OperationDefinition" && x.operation === "subscription",
77
76
  );
78
77
 
@@ -120,7 +119,7 @@ export function graphQLDocumentNodeParser(
120
119
  const type = queries.length ? DocumentTypes.query : DocumentTypes.mutation;
121
120
  const definitions = queries.length ? queries : mutations;
122
121
 
123
- const definition: OperationDefinitionNode = (definitions[0]: any);
122
+ const definition: OperationDefinitionNode = definitions[0] as any;
124
123
  const variables = definition.variableDefinitions || [];
125
124
 
126
125
  // fallback to using data if no name
@@ -0,0 +1,27 @@
1
+ // NOTE(somewhatabstract):
2
+ // These types are bare minimum to support document parsing. They're derived
3
+ // from graphql@14.5.8, the last version that provided TypeScript types.
4
+ // Doing this avoids us having to take a dependency on that library just for
5
+ // these types.
6
+ export interface DefinitionNode {
7
+ readonly kind: string;
8
+ }
9
+
10
+ export type VariableDefinitionNode = {
11
+ readonly kind: "VariableDefinition";
12
+ };
13
+
14
+ export interface OperationDefinitionNode extends DefinitionNode {
15
+ readonly kind: "OperationDefinition";
16
+ readonly operation: string;
17
+ readonly variableDefinitions: ReadonlyArray<VariableDefinitionNode>;
18
+ readonly name?: {
19
+ readonly kind: unknown;
20
+ readonly value: string;
21
+ };
22
+ }
23
+
24
+ export type DocumentNode = {
25
+ readonly kind: "Document";
26
+ readonly definitions: ReadonlyArray<DefinitionNode>;
27
+ };
@@ -1,7 +1,6 @@
1
- // @flow
2
- import {SsrCache} from "./ssr-cache.js";
1
+ import {SsrCache} from "./ssr-cache";
3
2
 
4
- import type {ValidCacheData, CachedResponse, ResponseCache} from "./types.js";
3
+ import type {ValidCacheData, CachedResponse, ResponseCache} from "./types";
5
4
 
6
5
  /**
7
6
  * Initialize the hydration cache.
@@ -23,6 +22,9 @@ export const initializeHydrationCache = (source: ResponseCache): void =>
23
22
  export const purgeHydrationCache = (
24
23
  predicate?: (
25
24
  key: string,
26
- cacheEntry: ?$ReadOnly<CachedResponse<ValidCacheData>>,
25
+ cacheEntry?:
26
+ | Readonly<CachedResponse<ValidCacheData>>
27
+ | null
28
+ | undefined,
27
29
  ) => boolean,
28
30
  ): void => SsrCache.Default.purgeData(predicate);
@@ -1,5 +1,4 @@
1
- // @flow
2
- import type {GqlContext} from "./gql-types.js";
1
+ import type {GqlContext} from "./gql-types";
3
2
 
4
3
  /**
5
4
  * Construct a complete GqlContext from current defaults and a partial context.
@@ -7,7 +6,7 @@ import type {GqlContext} from "./gql-types.js";
7
6
  * Values in the partial context that are `undefined` will be ignored.
8
7
  * Values in the partial context that are `null` will be deleted.
9
8
  */
10
- export const mergeGqlContext = <TContext: GqlContext>(
9
+ export const mergeGqlContext = <TContext extends GqlContext>(
11
10
  defaultContext: TContext,
12
11
  overrides: Partial<TContext>,
13
12
  ): TContext => {
@@ -24,6 +23,7 @@ export const mergeGqlContext = <TContext: GqlContext>(
24
23
  delete acc[key];
25
24
  } else {
26
25
  // Otherwise, we set it.
26
+ // @ts-expect-error [FEI-5019] - TS2536 - Type 'string' cannot be used to index type 'TContext'.
27
27
  acc[key] = overrides[key];
28
28
  }
29
29
  }
@@ -1,6 +1,5 @@
1
- // @flow
2
- import {SharedCache} from "../hooks/use-shared-cache.js";
3
- import {purgeHydrationCache} from "./hydration-cache-api.js";
1
+ import {SharedCache} from "../hooks/use-shared-cache";
2
+ import {purgeHydrationCache} from "./hydration-cache-api";
4
3
 
5
4
  /**
6
5
  * Purge all caches managed by Wonder Blocks Data.
@@ -1,10 +1,9 @@
1
- // @flow
2
1
  import {Server} from "@khanacademy/wonder-blocks-core";
3
- import {RequestTracker} from "./request-tracking.js";
4
- import {RequestFulfillment} from "./request-fulfillment.js";
5
- import {DataError, DataErrors} from "./data-error.js";
2
+ import {RequestTracker} from "./request-tracking";
3
+ import {RequestFulfillment} from "./request-fulfillment";
4
+ import {DataError, DataErrors} from "./data-error";
6
5
 
7
- import type {ResponseCache} from "./types.js";
6
+ import type {ResponseCache} from "./types";
8
7
 
9
8
  const SSRCheck = () => {
10
9
  if (Server.isServerSide()) {
@@ -1,16 +1,15 @@
1
- // @flow
2
- import type {Result, ValidCacheData} from "./types.js";
1
+ import type {Result, ValidCacheData} from "./types";
3
2
 
4
- import {DataError, DataErrors} from "./data-error.js";
3
+ import {DataError, DataErrors} from "./data-error";
5
4
 
6
5
  type RequestCache = {
7
- [id: string]: Promise<Result<any>>,
6
+ [id: string]: Promise<Result<any>>;
8
7
  };
9
8
 
10
- type FulfillOptions<TData: ValidCacheData> = {|
11
- handler: () => Promise<TData>,
12
- hydrate?: boolean,
13
- |};
9
+ type FulfillOptions<TData extends ValidCacheData> = {
10
+ handler: () => Promise<TData>;
11
+ hydrate?: boolean;
12
+ };
14
13
 
15
14
  let _default: RequestFulfillment;
16
15
 
@@ -33,10 +32,10 @@ export class RequestFulfillment {
33
32
  * This will return an inflight request if one exists, otherwise it will
34
33
  * make a new request. Inflight requests are deleted once they resolve.
35
34
  */
36
- fulfill: <TData: ValidCacheData>(
35
+ fulfill: <TData extends ValidCacheData>(
37
36
  id: string,
38
37
  options: FulfillOptions<TData>,
39
- ) => Promise<Result<TData>> = <TData: ValidCacheData>(
38
+ ) => Promise<Result<TData>> = <TData extends ValidCacheData>(
40
39
  id: string,
41
40
  {handler, hydrate = true}: FulfillOptions<TData>,
42
41
  ): Promise<Result<TData>> => {
@@ -52,10 +51,12 @@ export class RequestFulfillment {
52
51
  * We don't have an inflight request, so let's set one up.
53
52
  */
54
53
  const request = handler()
55
- .then((data: TData): Result<TData> => ({
56
- status: "success",
57
- data,
58
- }))
54
+ .then(
55
+ (data: TData): Result<TData> => ({
56
+ status: "success",
57
+ data,
58
+ }),
59
+ )
59
60
  .catch((error: string | Error): Result<TData> => {
60
61
  const actualError =
61
62
  typeof error === "string"
@@ -1,22 +1,20 @@
1
- // @flow
2
1
  import * as React from "react";
3
- import {SsrCache} from "./ssr-cache.js";
4
- import {RequestFulfillment} from "./request-fulfillment.js";
2
+ import {SsrCache} from "./ssr-cache";
3
+ import {RequestFulfillment} from "./request-fulfillment";
5
4
 
6
- import type {ResponseCache, ValidCacheData} from "./types.js";
5
+ import type {ResponseCache, ValidCacheData} from "./types";
7
6
 
8
- type TrackerFn = <TData: ValidCacheData>(
7
+ type TrackerFn = <TData extends ValidCacheData>(
9
8
  id: string,
10
9
  handler: () => Promise<TData>,
11
10
  hydrate: boolean,
12
11
  ) => void;
13
12
 
14
13
  type RequestCache = {
15
- [id: string]: {|
16
- hydrate: boolean,
17
- handler: () => Promise<any>,
18
- |},
19
- ...
14
+ [id: string]: {
15
+ hydrate: boolean;
16
+ handler: () => Promise<any>;
17
+ };
20
18
  };
21
19
 
22
20
  /**
@@ -24,8 +22,8 @@ type RequestCache = {
24
22
  *
25
23
  * INTERNAL USE ONLY
26
24
  */
27
- export const TrackerContext: React.Context<?TrackerFn> =
28
- React.createContext<?TrackerFn>(null);
25
+ export const TrackerContext: React.Context<TrackerFn | null | undefined> =
26
+ React.createContext<TrackerFn | null | undefined>(null);
29
27
 
30
28
  /**
31
29
  * The default instance is stored here.
@@ -53,7 +51,8 @@ export class RequestTracker {
53
51
  _responseCache: SsrCache;
54
52
  _requestFulfillment: RequestFulfillment;
55
53
 
56
- constructor(responseCache: ?SsrCache = undefined) {
54
+ // @ts-expect-error [FEI-5019] - TS2322 - Type 'undefined' is not assignable to type 'SsrCache | null'.
55
+ constructor(responseCache: SsrCache | null = undefined) {
57
56
  this._responseCache = responseCache || SsrCache.Default;
58
57
  this._requestFulfillment = new RequestFulfillment();
59
58
  }
@@ -64,11 +63,11 @@ export class RequestTracker {
64
63
  * This method caches a request and its handler for use during server-side
65
64
  * rendering to allow us to fulfill requests before producing a final render.
66
65
  */
67
- trackDataRequest: <TData: ValidCacheData>(
66
+ trackDataRequest: <TData extends ValidCacheData>(
68
67
  id: string,
69
68
  handler: () => Promise<TData>,
70
69
  hydrate: boolean,
71
- ) => void = <TData: ValidCacheData>(
70
+ ) => void = <TData extends ValidCacheData>(
72
71
  id: string,
73
72
  handler: () => Promise<TData>,
74
73
  hydrate: boolean,
@@ -167,7 +166,7 @@ export class RequestTracker {
167
166
  return;
168
167
  }),
169
168
  );
170
- } catch (e) {
169
+ } catch (e: any) {
171
170
  // This captures if there are problems in the code that
172
171
  // begins the requests.
173
172
  promises.push(
@@ -1,14 +1,13 @@
1
- // @flow
2
- import {Status} from "./status.js";
3
- import {DataError, DataErrors} from "./data-error.js";
4
- import type {ValidCacheData, CachedResponse, Result} from "./types.js";
1
+ import {Status} from "./status";
2
+ import {DataError, DataErrors} from "./data-error";
3
+ import type {ValidCacheData, CachedResponse, Result} from "./types";
5
4
 
6
5
  /**
7
6
  * Turns a cache entry into a stateful result.
8
7
  */
9
- export const resultFromCachedResponse = <TData: ValidCacheData>(
10
- cacheEntry: ?CachedResponse<TData>,
11
- ): ?Result<TData> => {
8
+ export const resultFromCachedResponse = <TData extends ValidCacheData>(
9
+ cacheEntry?: CachedResponse<TData> | null,
10
+ ): Result<TData> | null | undefined => {
12
11
  // No cache entry means no result to be hydrated.
13
12
  if (cacheEntry == null) {
14
13
  return null;
@@ -1,6 +1,5 @@
1
- // @flow
2
- import {DataError, DataErrors} from "./data-error.js";
3
- import type {ScopedCache, RawScopedCache, ValidCacheData} from "./types.js";
1
+ import {DataError, DataErrors} from "./data-error";
2
+ import type {ScopedCache, RawScopedCache, ValidCacheData} from "./types";
4
3
 
5
4
  /**
6
5
  * Describe an in-memory cache.
@@ -53,7 +52,7 @@ export class ScopedInMemoryCache implements ScopedCache {
53
52
  /**
54
53
  * Retrieve a value from the cache.
55
54
  */
56
- get(scope: string, id: string): ?ValidCacheData {
55
+ get(scope: string, id: string): ValidCacheData | null | undefined {
57
56
  return this._cache[scope]?.[id] ?? null;
58
57
  }
59
58
 
@@ -1,8 +1,7 @@
1
- // @flow
2
1
  import {clone} from "@khanacademy/wonder-stuff-core";
3
- import {DataError, DataErrors} from "./data-error.js";
4
- import {ScopedInMemoryCache} from "./scoped-in-memory-cache.js";
5
- import type {ValidCacheData, RawScopedCache} from "./types.js";
2
+ import {DataError, DataErrors} from "./data-error";
3
+ import {ScopedInMemoryCache} from "./scoped-in-memory-cache";
4
+ import type {ValidCacheData, RawScopedCache} from "./types";
6
5
 
7
6
  /**
8
7
  * Describe a serializable in-memory cache.
@@ -11,7 +10,7 @@ export class SerializableInMemoryCache extends ScopedInMemoryCache {
11
10
  constructor(initialCache: RawScopedCache = {}) {
12
11
  try {
13
12
  super(clone(initialCache));
14
- } catch (e) {
13
+ } catch (e: any) {
15
14
  throw new DataError(
16
15
  `An error occurred trying to initialize from a response cache snapshot: ${e}`,
17
16
  DataErrors.InvalidInput,
@@ -32,7 +31,7 @@ export class SerializableInMemoryCache extends ScopedInMemoryCache {
32
31
  clone(): RawScopedCache {
33
32
  try {
34
33
  return clone(this._cache);
35
- } catch (e) {
34
+ } catch (e: any) {
36
35
  throw new DataError(
37
36
  "An error occurred while trying to clone the cache",
38
37
  DataErrors.Internal,