Skip to content

Commit c8dc915

Browse files
alina-zaievaalloy
andauthored
🤖 Merge PR DefinitelyTyped#74036 [relay-runtime] Export readFragment from index and resolverDataInjector from experimental by @alina-zaieva
Co-authored-by: Eloy Durán <eloy.de.enige@gmail.com>
1 parent 87c024f commit c8dc915

5 files changed

Lines changed: 129 additions & 17 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
import { DataID } from "./lib/util/RelayRuntimeTypes";
2+
3+
export { resolverDataInjector } from "./lib/store/live-resolvers/resolverDataInjector";
14
export { observeFragment } from "./lib/store/observeFragmentExperimental";
25
export { observeQuery } from "./lib/store/observeQueryExperimental";
36
export { waitForFragmentData } from "./lib/store/waitForFragmentExperimental";
7+
8+
export type IdOf<_A extends string, Typename extends undefined | string = undefined> = Typename extends undefined
9+
? { id: DataID }
10+
: { id: DataID; __typename: Typename };
11+
12+
interface ErrorResult<E> {
13+
ok: false;
14+
errors: readonly E[];
15+
}
16+
17+
interface OkayResult<T> {
18+
ok: true;
19+
value: T;
20+
}
21+
22+
// The type returned by fields annotated with `@catch`
23+
export type Result<T, E> = OkayResult<T> | ErrorResult<E>;
24+
25+
export function isValueResult<T = unknown>(input: Result<T, unknown>): input is OkayResult<T>;
26+
27+
export function isErrorResult<E = unknown>(input: Result<unknown, E>): input is ErrorResult<E>;

‎types/relay-runtime/index.d.ts‎

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ export { RelayModernRecord as Record } from "./lib/store/RelayModernRecord";
154154
export { default as Store } from "./lib/store/RelayModernStore";
155155
export { RelayRecordSource as RecordSource } from "./lib/store/RelayRecordSource";
156156

157+
export { type IdOf, isErrorResult, isValueResult, type Result } from "./experimental";
157158
export { createFragmentSpecResolver } from "./lib/store/createFragmentSpecResolver";
158159
export { readInlineData } from "./lib/store/readInlineData";
159160
export { createOperationDescriptor, createRequestDescriptor } from "./lib/store/RelayModernOperationDescriptor";
@@ -185,6 +186,7 @@ export {
185186
ROOT_TYPE,
186187
TYPENAME_KEY,
187188
} from "./lib/store/RelayStoreUtils";
189+
export { readFragment } from "./lib/store/ResolverFragments";
188190

189191
// Extensions
190192
import RelayDefaultHandlerProvider from "./lib/handlers/RelayDefaultHandlerProvider";
@@ -267,16 +269,3 @@ export type FragmentRefs<Refs extends string> = {
267269

268270
// This is a utility type for converting from a data type to a fragment reference that will resolve to that data type.
269271
export type FragmentRef<Fragment> = Fragment extends _RefType<infer U> ? _FragmentRefs<U> : never;
270-
271-
interface ErrorResult<Error> {
272-
ok: false;
273-
errors: readonly Error[];
274-
}
275-
276-
interface OkayResult<T> {
277-
ok: true;
278-
value: T;
279-
}
280-
281-
// The type returned by fields annotated with `@catch`
282-
export type Result<T, Error> = OkayResult<T> | ErrorResult<Error>;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { GraphQLTaggedNode } from "../../query/RelayModernGraphQLTag";
2+
import type { FragmentType } from "../RelayStoreTypes";
3+
4+
/**
5+
* This a higher order function that returns a relay resolver that can read the data for
6+
* the fragment`.
7+
*
8+
* - fragment: contains fragment Reader AST with resolver's data dependencies.
9+
* - resolverFn: original resolver function that expects a data from the fragment
10+
* - (optional) fieldName: individual field that needs to be read out of the fragment.
11+
*
12+
* This will not call the `resolverFn` if the fragment data for it is null/undefined.
13+
* The compiler generates calls to this function, ensuring the correct set of arguments.
14+
*/
15+
export function resolverDataInjector(
16+
fragment: GraphQLTaggedNode,
17+
_resolverFn: unknown,
18+
fieldName?: string,
19+
isRequiredField?: boolean,
20+
): (fragmentKey: FragmentType, args: unknown) => unknown;

‎types/relay-runtime/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"name": "@types/relay-runtime",
4-
"version": "19.0.9999",
4+
"version": "20.1.9999",
55
"projects": [
66
"https://github.com/facebook/relay",
77
"https://facebook.github.io/relay"

‎types/relay-runtime/relay-runtime-tests.tsx‎

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@ import {
1515
getRefetchMetadata,
1616
getRequest,
1717
graphql,
18+
isErrorResult,
1819
isPromise,
20+
isValueResult,
1921
LiveState,
2022
Network,
2123
PreloadableConcreteRequest,
2224
PreloadableQueryRegistry,
2325
QueryResponseCache,
2426
ReaderFragment,
2527
ReaderInlineDataFragment,
28+
readFragment,
2629
readInlineData,
2730
RecordProxy,
2831
RecordSource,
@@ -35,7 +38,13 @@ import {
3538
suspenseSentinel,
3639
Variables,
3740
} from "relay-runtime";
38-
import { observeFragment, observeQuery, waitForFragmentData } from "relay-runtime/experimental";
41+
import {
42+
IdOf,
43+
observeFragment,
44+
observeQuery,
45+
resolverDataInjector,
46+
waitForFragmentData,
47+
} from "relay-runtime/experimental";
3948

4049
import type { HandlerProvider } from "relay-runtime/lib/handlers/RelayDefaultHandlerProvider";
4150
import * as multiActorEnvironment from "relay-runtime/multi-actor-environment";
@@ -701,8 +710,6 @@ function multiActors() {
701710
// Relay Resolvers
702711
// ~~~~~~~~~~~~~~~~~~~~~~~
703712

704-
const { readFragment } = __internal.ResolverFragments;
705-
706713
// Regular fragment.
707714
interface UserComponent_user {
708715
readonly id: string;
@@ -921,6 +928,20 @@ export function handleResult<T, E>(result: Result<T, E>) {
921928
}
922929
}
923930

931+
// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
932+
export function handleValueResult<T, E>(result: Result<T, E>) {
933+
if (isValueResult(result)) {
934+
const value: T = result.value;
935+
}
936+
}
937+
938+
// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
939+
export function handleErrorResult<T, E>(result: Result<T, E>) {
940+
if (isErrorResult(result)) {
941+
const errors: readonly E[] = result.errors;
942+
}
943+
}
944+
924945
// ~~~~~~~~~~~~~~~~~~
925946
// Metadata
926947
// ~~~~~~~~~~~~~~~~~~
@@ -1048,3 +1069,61 @@ function observeQueryTest() {
10481069

10491070
subscription.unsubscribe();
10501071
}
1072+
1073+
// ~~~~~~~~~~~~~~~~~~
1074+
// resolverDataInjector
1075+
// ~~~~~~~~~~~~~~~~~~
1076+
1077+
const MyResolverType__id_graphql: ReaderFragment = {
1078+
"argumentDefinitions": [],
1079+
"kind": "Fragment",
1080+
"metadata": null,
1081+
"name": "MyResolverType__id",
1082+
"selections": [
1083+
{
1084+
"kind": "ClientExtension",
1085+
"selections": [
1086+
{
1087+
"alias": null,
1088+
"args": null,
1089+
"kind": "ScalarField",
1090+
"name": "id",
1091+
"storageKey": null,
1092+
},
1093+
],
1094+
},
1095+
],
1096+
"type": "MyResolverType",
1097+
"abstractKey": null,
1098+
};
1099+
1100+
interface MyResolverType {
1101+
id: string;
1102+
}
1103+
1104+
function myResolverTypeRelayModelInstanceResolver(id: DataID): MyResolverType {
1105+
return {
1106+
id,
1107+
};
1108+
}
1109+
1110+
export const resolverModule = resolverDataInjector(
1111+
MyResolverType__id_graphql,
1112+
myResolverTypeRelayModelInstanceResolver,
1113+
"id",
1114+
true,
1115+
);
1116+
1117+
// ~~~~~~~~~~~~~~~~~~
1118+
// Client edge resolver
1119+
// ~~~~~~~~~~~~~~~~~~
1120+
1121+
export function myDog(): IdOf<"Dog"> {
1122+
return { id: "5" };
1123+
}
1124+
1125+
type AnimalTypenames = "Cat" | "Dog";
1126+
1127+
export function myAnimal(): IdOf<"Animal", AnimalTypenames> {
1128+
return Math.random() > 0.5 ? { id: "5", __typename: "Dog" } : { id: "6", __typename: "Cat" };
1129+
}

0 commit comments

Comments
 (0)