From 95479db2fd29ddc5504b490151b51bf6bac26f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eloy=20Dur=C3=A1n?= Date: Wed, 18 Oct 2017 00:15:58 +0200 Subject: [PATCH] [Relay] Simplify modules by removing namespaces. --- types/react-relay/classic.d.ts | 18 +- types/react-relay/compat.d.ts | 25 +- types/react-relay/index.d.ts | 165 +- types/react-relay/modern.d.ts | 146 -- types/react-relay/test/react-relay-tests.tsx | 7 +- types/react-relay/tsconfig.json | 1 - types/relay-runtime/index.d.ts | 2115 +++++++++--------- 7 files changed, 1216 insertions(+), 1261 deletions(-) delete mode 100644 types/react-relay/modern.d.ts diff --git a/types/react-relay/classic.d.ts b/types/react-relay/classic.d.ts index 9345199d27..0db5308975 100644 --- a/types/react-relay/classic.d.ts +++ b/types/react-relay/classic.d.ts @@ -1,5 +1,5 @@ import * as React from "react"; -import { RelayCommonTypes } from "relay-runtime"; +import * as RelayRuntimeTypes from "relay-runtime"; // ~~~~~~~~~~~~~~~~~~~~~ // Maybe Fix @@ -20,24 +20,24 @@ export interface FragmentResolver { dispose(): void; resolve( fragment: RelayQuery["Fragment"], - dataIDs: RelayCommonTypes.DataID | RelayCommonTypes.DataID[] + dataIDs: RelayRuntimeTypes.DataID | RelayRuntimeTypes.DataID[] ): StoreReaderData | StoreReaderData[] | undefined | null; } export interface RelayEnvironmentInterface { forceFetch( - querySet: RelayCommonTypes.RelayQuerySet, - onReadyStateChange: RelayCommonTypes.ReadyStateChangeCallback - ): RelayCommonTypes.Abortable; + querySet: RelayRuntimeTypes.RelayQuerySet, + onReadyStateChange: RelayRuntimeTypes.ReadyStateChangeCallback + ): RelayRuntimeTypes.Abortable; getFragmentResolver(fragment: RelayQuery["Fragment"], onNext: () => void): FragmentResolver; getStoreData(): RelayStoreData; primeCache( - querySet: RelayCommonTypes.RelayQuerySet, - onReadyStateChange: RelayCommonTypes.ReadyStateChangeCallback - ): RelayCommonTypes.Abortable; + querySet: RelayRuntimeTypes.RelayQuerySet, + onReadyStateChange: RelayRuntimeTypes.ReadyStateChangeCallback + ): RelayRuntimeTypes.Abortable; read( node: RelayQuery["Node"], - dataID: RelayCommonTypes.DataID, + dataID: RelayRuntimeTypes.DataID, options?: StoreReaderOptions ): StoreReaderData | void; readQuery(root: RelayQuery["Root"], options?: StoreReaderOptions): StoreReaderData[] | void; diff --git a/types/react-relay/compat.d.ts b/types/react-relay/compat.d.ts index 74f7f55a03..bbc69a3cc4 100644 --- a/types/react-relay/compat.d.ts +++ b/types/react-relay/compat.d.ts @@ -1,6 +1,15 @@ -import { RelayRuntimeTypes, RelayCommonTypes } from "relay-runtime"; +export { + QueryRenderer, + commitMutation, + createFragmentContainer, + createPaginationContainer, + createRefetchContainer, + fetchQuery, + graphql, +} from "react-relay"; + +import * as RelayRuntimeTypes from "relay-runtime"; import { RelayEnvironmentInterface } from "react-relay/classic"; -import {} from "react-relay/modern"; // ~~~~~~~~~~~~~~~~~~~~~ // Maybe Fix @@ -13,7 +22,7 @@ type ConcreteOperationDefinition = object; // ~~~~~~~~~~~~~~~~~~~~~ // Util // ~~~~~~~~~~~~~~~~~~~~~ -export function getFragment(q: string, v?: RelayCommonTypes.Variables): string; +export function getFragment(q: string, v?: RelayRuntimeTypes.Variables): string; export interface ComponentWithFragment extends React.ComponentClass { getFragment: typeof getFragment; } @@ -35,25 +44,25 @@ export type CompatEnvironment = RelayRuntimeTypes.Environment | RelayClassicEnvi export function commitUpdate( environment: CompatEnvironment, config: RelayRuntimeTypes.MutationConfig -): RelayCommonTypes.Disposable; +): RelayRuntimeTypes.Disposable; export function applyUpdate( environment: CompatEnvironment, config: RelayRuntimeTypes.OptimisticMutationConfig -): RelayCommonTypes.Disposable; +): RelayRuntimeTypes.Disposable; // ~~~~~~~~~~~~~~~~~~~~~ // RelayCompatContainer // ~~~~~~~~~~~~~~~~~~~~~ export interface GeneratedNodeMap { - [key: string]: RelayCommonTypes.GraphQLTaggedNode; + [key: string]: RelayRuntimeTypes.GraphQLTaggedNode; } export function createContainer( Component: ReactBaseComponent, - fragmentSpec: RelayCommonTypes.GraphQLTaggedNode | GeneratedNodeMap + fragmentSpec: RelayRuntimeTypes.GraphQLTaggedNode | GeneratedNodeMap ): ReactFragmentComponent; // ~~~~~~~~~~~~~~~~~~~~~ // injectDefaultVariablesProvider // ~~~~~~~~~~~~~~~~~~~~~ -export type VariablesProvider = () => RelayCommonTypes.Variables; +export type VariablesProvider = () => RelayRuntimeTypes.Variables; export function injectDefaultVariablesProvider(variablesProvider: VariablesProvider): void; diff --git a/types/react-relay/index.d.ts b/types/react-relay/index.d.ts index cdb38afae6..fa23ac4dd7 100644 --- a/types/react-relay/index.d.ts +++ b/types/react-relay/index.d.ts @@ -6,20 +6,157 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.4 -import { RelayRuntimeTypes } from "relay-runtime"; -import * as ReactRelayModernTypes from "react-relay/modern"; +export { + commitLocalUpdate, + commitRelayModernMutation as commitMutation, + fetchRelayModernQuery as fetchQuery, + requestRelaySubscription as requestSubscription, +} from "relay-runtime"; + +import * as React from "react"; +import * as RelayRuntimeTypes from "relay-runtime"; // ~~~~~~~~~~~~~~~~~~~~~ -// React-Relay Modern +// Maybe Fix // ~~~~~~~~~~~~~~~~~~~~~ -export import QueryRenderer = ReactRelayModernTypes.ReactRelayQueryRenderer; -export import createFragmentContainer = ReactRelayModernTypes.createFragmentContainer; -export import createPaginationContainer = ReactRelayModernTypes.createPaginationContainer; -export import createRefetchContainer = ReactRelayModernTypes.createRefetchContainer; -export import graphql = ReactRelayModernTypes.graphql; -export import commitLocalUpdate = RelayRuntimeTypes.commitLocalUpdate; -export import commitMutation = RelayRuntimeTypes.commitRelayModernMutation; -export import fetchQuery = RelayRuntimeTypes.fetchRelayModernQuery; -export import requestSubscription = RelayRuntimeTypes.requestRelaySubscription; -// exported for convenience -export import ModernTypes = ReactRelayModernTypes; +type ConcreteFragment = any; +type ConcreteBatch = any; +type ConcreteFragmentDefinition = object; +type ConcreteOperationDefinition = object; +type ReactBaseComponent = React.ComponentClass | React.StatelessComponent; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayProp +// ~~~~~~~~~~~~~~~~~~~~~ +// note: refetch and pagination containers augment this +export interface RelayProp { + environment: RelayRuntimeTypes.Environment; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayQL +// ~~~~~~~~~~~~~~~~~~~~~ +export function RelayQL(strings: string[], ...substitutions: any[]): RelayRuntimeTypes.RelayConcreteNode; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayModernGraphQLTag +// ~~~~~~~~~~~~~~~~~~~~~ +export interface GeneratedNodeMap { + [key: string]: GraphQLTaggedNode; +} +export type GraphQLTaggedNode = + | (() => ConcreteFragment | ConcreteBatch) + | { + modern(): ConcreteFragment | ConcreteBatch; + classic(relayQL: typeof RelayQL): ConcreteFragmentDefinition | ConcreteOperationDefinition; + }; +/** + * Runtime function to correspond to the `graphql` tagged template function. + * All calls to this function should be transformed by the plugin. + */ +export interface GraphqlInterface { + (strings: string[] | TemplateStringsArray): GraphQLTaggedNode; + experimental(strings: string[] | TemplateStringsArray): GraphQLTaggedNode; +} +export const graphql: GraphqlInterface; + +// ~~~~~~~~~~~~~~~~~~~~~ +// ReactRelayQueryRenderer +// ~~~~~~~~~~~~~~~~~~~~~ +export interface QueryRendererProps { + cacheConfig?: RelayRuntimeTypes.CacheConfig; + environment: RelayRuntimeTypes.Environment; + query: GraphQLTaggedNode; + render(readyState: ReadyState): React.ReactElement | undefined | null; + variables: RelayRuntimeTypes.Variables; + rerunParamExperimental?: RelayRuntimeTypes.RerunParam; +} +export interface ReadyState { + error: Error | undefined | null; + props: { [propName: string]: any } | undefined | null; + retry?(): void; +} +export interface QueryRendererState { + readyState: ReadyState; +} +export class ReactRelayQueryRenderer extends React.Component {} +export class QueryRenderer extends ReactRelayQueryRenderer {} + +// ~~~~~~~~~~~~~~~~~~~~~ +// createFragmentContainer +// ~~~~~~~~~~~~~~~~~~~~~ +export function createFragmentContainer( + Component: ReactBaseComponent, + fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap +): ReactBaseComponent; + +// ~~~~~~~~~~~~~~~~~~~~~ +// createPaginationContainer +// ~~~~~~~~~~~~~~~~~~~~~ +export interface PageInfo { + endCursor: string | undefined | null; + hasNextPage: boolean; + hasPreviousPage: boolean; + startCursor: string | undefined | null; +} +export interface ConnectionData { + edges?: any[]; + pageInfo?: PageInfo; +} +export type RelayPaginationProp = RelayProp & { + hasMore(): boolean; + isLoading(): boolean; + loadMore( + pageSize: number, + callback: (error?: Error) => void, + options?: RefetchOptions + ): RelayRuntimeTypes.Disposable | undefined | null; + refetchConnection( + totalCount: number, + callback: (error?: Error) => void, + refetchVariables?: RelayRuntimeTypes.Variables + ): RelayRuntimeTypes.Disposable | undefined | null; +}; +export function FragmentVariablesGetter( + prevVars: RelayRuntimeTypes.Variables, + totalCount: number +): RelayRuntimeTypes.Variables; +export interface ConnectionConfig { + direction?: "backward" | "forward"; + getConnectionFromProps?(props: T): ConnectionData | undefined | null; + getFragmentVariables?: typeof FragmentVariablesGetter; + getVariables( + props: { [propName: string]: any }, + paginationInfo: { count: number; cursor?: string }, + fragmentVariables: RelayRuntimeTypes.Variables + ): RelayRuntimeTypes.Variables; + query: GraphQLTaggedNode; +} +export function createPaginationContainer( + Component: ReactBaseComponent, + fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap, + connectionConfig: ConnectionConfig +): ReactBaseComponent; + +// ~~~~~~~~~~~~~~~~~~~~~ +// createFragmentContainer +// ~~~~~~~~~~~~~~~~~~~~~ +export interface RefetchOptions { + force?: boolean; + rerunParamExperimental?: RelayRuntimeTypes.RerunParam; +} +export type RelayRefetchProp = RelayProp & { + refetch( + refetchVariables: + | RelayRuntimeTypes.Variables + | ((fragmentVariables: RelayRuntimeTypes.Variables) => RelayRuntimeTypes.Variables), + renderVariables?: RelayRuntimeTypes.Variables, + callback?: (error?: Error) => void, + options?: RefetchOptions + ): RelayRuntimeTypes.Disposable; +}; +export function createRefetchContainer( + Component: ReactBaseComponent, + fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap, + taggedNode: GraphQLTaggedNode +): ReactBaseComponent; diff --git a/types/react-relay/modern.d.ts b/types/react-relay/modern.d.ts deleted file mode 100644 index d4c422b823..0000000000 --- a/types/react-relay/modern.d.ts +++ /dev/null @@ -1,146 +0,0 @@ -import * as React from "react"; -import { RelayCommonTypes, RelayRuntimeTypes } from "relay-runtime"; - -// ~~~~~~~~~~~~~~~~~~~~~ -// Maybe Fix -// ~~~~~~~~~~~~~~~~~~~~~ -type ConcreteFragment = any; -type ConcreteBatch = any; -type ConcreteFragmentDefinition = object; -type ConcreteOperationDefinition = object; -type ReactBaseComponent = React.ComponentClass | React.StatelessComponent; - -// ~~~~~~~~~~~~~~~~~~~~~ -// RelayProp -// ~~~~~~~~~~~~~~~~~~~~~ -// note: refetch and pagination containers augment this -export interface RelayProp { - environment: RelayRuntimeTypes.Environment; -} - -// ~~~~~~~~~~~~~~~~~~~~~ -// RelayQL -// ~~~~~~~~~~~~~~~~~~~~~ -export function RelayQL(strings: string[], ...substitutions: any[]): RelayCommonTypes.RelayConcreteNode; - -// ~~~~~~~~~~~~~~~~~~~~~ -// RelayModernGraphQLTag -// ~~~~~~~~~~~~~~~~~~~~~ -export interface GeneratedNodeMap { - [key: string]: GraphQLTaggedNode; -} -export type GraphQLTaggedNode = - | (() => ConcreteFragment | ConcreteBatch) - | { - modern(): ConcreteFragment | ConcreteBatch; - classic(relayQL: typeof RelayQL): ConcreteFragmentDefinition | ConcreteOperationDefinition; - }; -/** - * Runtime function to correspond to the `graphql` tagged template function. - * All calls to this function should be transformed by the plugin. - */ -export interface GraphqlInterface { - (strings: string[] | TemplateStringsArray): GraphQLTaggedNode; - experimental(strings: string[] | TemplateStringsArray): GraphQLTaggedNode; -} -export const graphql: GraphqlInterface; - -// ~~~~~~~~~~~~~~~~~~~~~ -// ReactRelayQueryRenderer -// ~~~~~~~~~~~~~~~~~~~~~ -export interface QueryRendererProps { - cacheConfig?: RelayCommonTypes.CacheConfig; - environment: RelayRuntimeTypes.Environment; - query: GraphQLTaggedNode; - render(readyState: ReadyState): React.ReactElement | undefined | null; - variables: RelayCommonTypes.Variables; - rerunParamExperimental?: RelayCommonTypes.RerunParam; -} -export interface ReadyState { - error: Error | undefined | null; - props: { [propName: string]: any } | undefined | null; - retry?(): void; -} -export interface QueryRendererState { - readyState: ReadyState; -} -export class ReactRelayQueryRenderer extends React.Component {} - -// ~~~~~~~~~~~~~~~~~~~~~ -// createFragmentContainer -// ~~~~~~~~~~~~~~~~~~~~~ -export function createFragmentContainer( - Component: ReactBaseComponent, - fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap -): ReactBaseComponent; - -// ~~~~~~~~~~~~~~~~~~~~~ -// createPaginationContainer -// ~~~~~~~~~~~~~~~~~~~~~ -export interface PageInfo { - endCursor: string | undefined | null; - hasNextPage: boolean; - hasPreviousPage: boolean; - startCursor: string | undefined | null; -} -export interface ConnectionData { - edges?: any[]; - pageInfo?: PageInfo; -} -export type RelayPaginationProp = RelayProp & { - hasMore(): boolean; - isLoading(): boolean; - loadMore( - pageSize: number, - callback: (error?: Error) => void, - options?: RefetchOptions - ): RelayCommonTypes.Disposable | undefined | null; - refetchConnection( - totalCount: number, - callback: (error?: Error) => void, - refetchVariables?: RelayCommonTypes.Variables - ): RelayCommonTypes.Disposable | undefined | null; -}; -export function FragmentVariablesGetter( - prevVars: RelayCommonTypes.Variables, - totalCount: number -): RelayCommonTypes.Variables; -export interface ConnectionConfig { - direction?: "backward" | "forward"; - getConnectionFromProps?(props: T): ConnectionData | undefined | null; - getFragmentVariables?: typeof FragmentVariablesGetter; - getVariables( - props: { [propName: string]: any }, - paginationInfo: { count: number; cursor?: string }, - fragmentVariables: RelayCommonTypes.Variables - ): RelayCommonTypes.Variables; - query: GraphQLTaggedNode; -} -export function createPaginationContainer( - Component: ReactBaseComponent, - fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap, - connectionConfig: ConnectionConfig -): ReactBaseComponent; - -// ~~~~~~~~~~~~~~~~~~~~~ -// createFragmentContainer -// ~~~~~~~~~~~~~~~~~~~~~ -export interface RefetchOptions { - force?: boolean; - rerunParamExperimental?: RelayCommonTypes.RerunParam; -} -export type RelayRefetchProp = RelayProp & { - refetch( - refetchVariables: - | RelayCommonTypes.Variables - | ((fragmentVariables: RelayCommonTypes.Variables) => RelayCommonTypes.Variables), - renderVariables?: RelayCommonTypes.Variables, - callback?: (error?: Error) => void, - options?: RefetchOptions - ): RelayCommonTypes.Disposable; -}; -export function createRefetchContainer( - Component: ReactBaseComponent, - fragmentSpec: GraphQLTaggedNode | GeneratedNodeMap, - taggedNode: GraphQLTaggedNode -): ReactBaseComponent; diff --git a/types/react-relay/test/react-relay-tests.tsx b/types/react-relay/test/react-relay-tests.tsx index 80380122f7..6caf997dba 100644 --- a/types/react-relay/test/react-relay-tests.tsx +++ b/types/react-relay/test/react-relay-tests.tsx @@ -12,7 +12,8 @@ import { createRefetchContainer, requestSubscription, QueryRenderer, - ModernTypes, + RelayRefetchProp, + RelayPaginationProp } from "react-relay"; // ~~~~~~~~~~~~~~~~~~~~~ @@ -79,7 +80,7 @@ interface StoryInterface { id: string; } interface FeedStoriesProps { - relay: ModernTypes.RelayRefetchProp; + relay: RelayRefetchProp; feed: { stories: { edges: Array<{ node: StoryInterface }> }; }; @@ -134,7 +135,7 @@ const FeedRefetchContainer = createRefetchContainer( // ~~~~~~~~~~~~~~~~~~~~~ interface FeedProps { user: { feed: { edges: Array<{ node: StoryInterface }> } }; - relay: ModernTypes.RelayPaginationProp; + relay: RelayPaginationProp; } class Feed extends React.Component { render() { diff --git a/types/react-relay/tsconfig.json b/types/react-relay/tsconfig.json index 2b992f91c8..ef2af0375f 100644 --- a/types/react-relay/tsconfig.json +++ b/types/react-relay/tsconfig.json @@ -20,7 +20,6 @@ "files": [ "index.d.ts", "classic.d.ts", - "modern.d.ts", "compat.d.ts", "test/react-relay-tests.tsx", "test/react-relay-classic-tests.tsx" diff --git a/types/relay-runtime/index.d.ts b/types/relay-runtime/index.d.ts index 69f5088ab4..bbc3e07a7a 100644 --- a/types/relay-runtime/index.d.ts +++ b/types/relay-runtime/index.d.ts @@ -5,1092 +5,1047 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.4 -// note: namespace is used so react-relay can access and inter-op -export namespace RelayCommonTypes { - /** - * SOURCE: - * Relay 1.3.0 - * https://github.com/facebook/relay/blob/b85a1d69bb72be4ace67179f55c2a54a8d761c8b/packages/react-relay/classic/environment/RelayCombinedEnvironmentTypes.js - */ - // ~~~~~~~~~~~~~~~~~~~~~ - // Maybe Fix - // ~~~~~~~~~~~~~~~~~~~~~ - type RelayConcreteNode = any; - type RelayMutationTransaction = any; - type RelayMutationRequest = any; - type RelayQueryRequest = any; - type ConcreteFragment = any; - type ConcreteBatch = any; - type ConcreteFragmentDefinition = object; - type ConcreteOperationDefinition = object; +/** + * SOURCE: + * Relay 1.3.0 + * https://github.com/facebook/relay/blob/b85a1d69bb72be4ace67179f55c2a54a8d761c8b/packages/react-relay/classic/environment/RelayCombinedEnvironmentTypes.js + */ +// ~~~~~~~~~~~~~~~~~~~~~ +// Maybe Fix +// ~~~~~~~~~~~~~~~~~~~~~ +type RelayConcreteNode = any; +type RelayMutationTransaction = any; +type RelayMutationRequest = any; +type RelayQueryRequest = any; +type ConcreteFragment = any; +type ConcreteBatch = any; +type ConcreteFragmentDefinition = object; +type ConcreteOperationDefinition = object; - /** - * FIXME: RelayContainer used to be typed with ReactClass, but - * ReactClass is broken and allows for access to any property. For example - * ReactClass.getFragment('foo') is valid even though ReactClass has no - * such getFragment() type definition. When ReactClass is fixed this causes a - * lot of errors in Relay code since methods like getFragment() are used often - * but have no definition in Relay's types. Suppressing for now. - */ - type RelayContainer = any; +/** + * FIXME: RelayContainer used to be typed with ReactClass, but + * ReactClass is broken and allows for access to any property. For example + * ReactClass.getFragment('foo') is valid even though ReactClass has no + * such getFragment() type definition. When ReactClass is fixed this causes a + * lot of errors in Relay code since methods like getFragment() are used often + * but have no definition in Relay's types. Suppressing for now. + */ +type RelayContainer = any; - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayQL - // ~~~~~~~~~~~~~~~~~~~~~ - type RelayQL = (strings: string[], ...substitutions: any[]) => RelayConcreteNode; +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayQL +// ~~~~~~~~~~~~~~~~~~~~~ +type RelayQL = (strings: string[], ...substitutions: any[]) => RelayConcreteNode; - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayModernGraphQLTag - // ~~~~~~~~~~~~~~~~~~~~~ - interface GeneratedNodeMap { - [key: string]: GraphQLTaggedNode; - } - type GraphQLTaggedNode = - | (() => ConcreteFragment | ConcreteBatch) - | { - modern(): ConcreteFragment | ConcreteBatch; - classic(relayQL: RelayQL): ConcreteFragmentDefinition | ConcreteOperationDefinition; - }; - // ~~~~~~~~~~~~~~~~~~~~~ - // General Usage - // ~~~~~~~~~~~~~~~~~~~~~ - type DataID = string; - interface Variables { - [name: string]: any; - } - type Uploadable = File | Blob; - interface UploadableMap { - [key: string]: Uploadable; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayNetworkTypes - // Version: Relay 1.3.0 - // File: https://github.com/facebook/relay/blob/master/packages/relay-runtime/network/RelayNetworkTypes.js - // ~~~~~~~~~~~~~~~~~~~~~ - - interface LegacyObserver { - onCompleted?(): void; - onError?(error: Error): void; - onNext?(data: T): void; - } - interface PayloadError { - message: string; - locations?: Array<{ - line: number; - column: number; - }>; - } - /** - * A function that executes a GraphQL operation with request/response semantics. - * - * May return an Observable or Promise of a raw server response. - */ - function FetchFunction( - operation: ConcreteBatch, - variables: Variables, - cacheConfig: CacheConfig, - uploadables?: UploadableMap - ): RelayRuntimeTypes.ObservableFromValue; - - /** - * A function that executes a GraphQL subscription operation, returning one or - * more raw server responses over time. - * - * May return an Observable, otherwise must call the callbacks found in the - * fourth parameter. - */ - type SubscribeFunction = ( - operation: ConcreteBatch, - variables: Variables, - cacheConfig: CacheConfig, - observer: LegacyObserver - ) => RelayRuntimeTypes.RelayObservable | Disposable; - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayStoreTypes - // Version: Relay 1.3.0 - // File: https://github.com/facebook/relay/blob/master/packages/relay-runtime/store/RelayStoreTypes.js - // ~~~~~~~~~~~~~~~~~~~~~ - /** - * A function that receives a proxy over the store and may trigger side-effects - * (indirectly) by calling `set*` methods on the store or its record proxies. - */ - type StoreUpdater = (store: RecordSourceProxy) => void; - - /** - * Similar to StoreUpdater, but accepts a proxy tied to a specific selector in - * order to easily access the root fields of a query/mutation as well as a - * second argument of the response object of the mutation. - */ - type SelectorStoreUpdater = ( - store: RecordSourceSelectorProxy, - // Actually RelayCombinedEnvironmentTypes#SelectorData, but mixed is - // inconvenient to access deeply in product code. - data: any // FLOW FIXME - ) => void; - - /** - * Extends the RecordSourceProxy interface with methods for accessing the root - * fields of a Selector. - */ - interface RecordSourceSelectorProxy { - create(dataID: DataID, typeName: string): RecordProxy; - delete(dataID: DataID): void; - get(dataID: DataID): RecordProxy | null; - getRoot(): RecordProxy; - getRootField(fieldName: string): RecordProxy | null; - getPluralRootField(fieldName: string): RecordProxy[] | null; - } - - interface RecordProxy { - copyFieldsFrom(source: RecordProxy): void; - getDataID(): DataID; - getLinkedRecord(name: string, args?: Variables): RecordProxy | null; - getLinkedRecords(name: string, args?: Variables): Array | null; - getOrCreateLinkedRecord(name: string, typeName: string, args?: Variables): RecordProxy; - getType(): string; - getValue(name: string, args?: Variables): any; - setLinkedRecord(record: RecordProxy, name: string, args?: Variables): RecordProxy; - setLinkedRecords( - records: Array | undefined | null, - name: string, - args?: Variables - ): RecordProxy; - setValue(value: any, name: string, args?: Variables): RecordProxy; - } - - interface RecordSourceProxy { - create(dataID: DataID, typeName: string): RecordProxy; - delete(dataID: DataID): void; - get(dataID: DataID): Array | null; - getRoot(): RecordProxy; - } - - interface HandleFieldPayload { - // The arguments that were fetched. - args: Variables; - // The __id of the record containing the source/handle field. - dataID: DataID; - // The (storage) key at which the original server data was written. - fieldKey: string; - // The name of the handle - handle: string; - // The (storage) key at which the handle's data should be written by the - // handler - handleKey: string; - } - interface HandlerInterface { - update(store: RecordSourceProxy, fieldPayload: HandleFieldPayload): void; - [functionName: string]: (...args: any[]) => any; - } - const Handler: HandlerInterface; - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayCombinedEnvironmentTypes - // Version: Relay 1.3.0 - // File: https://github.com/facebook/relay/blob/b85a1d69bb72be4ace67179f55c2a54a8d761c8b/packages/react-relay/classic/environment/RelayCombinedEnvironmentTypes.js - // ~~~~~~~~~~~~~~~~~~~~~ - /** - * Settings for how a query response may be cached. - * - * - `force`: causes a query to be issued unconditionally, irrespective of the - * state of any configured response cache. - * - `poll`: causes a query to live update by polling at the specified interval - * in milliseconds. (This value will be passed to setTimeout.) - */ - interface CacheConfig { - force?: boolean; - poll?: number; - } - - /** - * Represents any resource that must be explicitly disposed of. The most common - * use-case is as a return value for subscriptions, where calling `dispose()` - * would cancel the subscription. - */ - interface Disposable { - dispose(): void; - } - - /** - * Arbitrary data e.g. received by a container as props. - */ - interface Props { - [key: string]: any; - } - - /* - * An individual cached graph object. - */ - interface Record { - [key: string]: any; - } - - /** - * A collection of records keyed by id. - */ - interface RecordMap { - [dataID: string]: Record | null | undefined; - } - - /** - * A selector defines the starting point for a traversal into the graph for the - * purposes of targeting a subgraph. - */ - interface CSelector { - dataID: DataID; - node: TNode; - variables: Variables; - } - - /** - * A representation of a selector and its results at a particular point in time. - */ - type CSnapshot = CSelector & { - data: SelectorData | null | undefined; - seenRecords: RecordMap; - }; - - /** - * The results of a selector given a store/RecordSource. - */ - interface SelectorData { - [key: string]: any; - } - - /** - * The results of reading the results of a FragmentMap given some input - * `Props`. - */ - interface FragmentSpecResults { - [key: string]: any; - } - - /** - * A utility for resolving and subscribing to the results of a fragment spec - * (key -> fragment mapping) given some "props" that determine the root ID - * and variables to use when reading each fragment. When props are changed via - * `setProps()`, the resolver will update its results and subscriptions - * accordingly. Internally, the resolver: - * - Converts the fragment map & props map into a map of `Selector`s. - * - Removes any resolvers for any props that became null. - * - Creates resolvers for any props that became non-null. - * - Updates resolvers with the latest props. - */ - interface FragmentSpecResolver { - /** - * Stop watching for changes to the results of the fragments. - */ - dispose(): void; - - /** - * Get the current results. - */ - resolve(): FragmentSpecResults; - - /** - * Update the resolver with new inputs. Call `resolve()` to get the updated - * results. - */ - setProps(props: Props): void; - - /** - * Override the variables used to read the results of the fragments. Call - * `resolve()` to get the updated results. - */ - setVariables(variables: Variables): void; - } - - interface CFragmentMap { - [key: string]: TFragment; - } - - /** - * An operation selector describes a specific instance of a GraphQL operation - * with variables applied. - * - * - `root`: a selector intended for processing server results or retaining - * response data in the store. - * - `fragment`: a selector intended for use in reading or subscribing to - * the results of the the operation. - */ - interface COperationSelector { - fragment: CSelector; - node: TOperation; - root: CSelector; - variables: Variables; - } - - /** - * The public API of Relay core. Represents an encapsulated environment with its - * own in-memory cache. - */ - interface CEnvironment { - /** - * Read the results of a selector from in-memory records in the store. - */ - lookup(selector: CSelector): CSnapshot; - - /** - * Subscribe to changes to the results of a selector. The callback is called - * when data has been committed to the store that would cause the results of - * the snapshot's selector to change. - */ - subscribe(snapshot: CSnapshot, callback: (snapshot: CSnapshot) => void): Disposable; - - /** - * Ensure that all the records necessary to fulfill the given selector are - * retained in-memory. The records will not be eligible for garbage collection - * until the returned reference is disposed. - * - * Note: This is a no-op in the classic core. - */ - retain(selector: CSelector): Disposable; - - /** - * Send a query to the server with request/response semantics: the query will - * either complete successfully (calling `onNext` and `onCompleted`) or fail - * (calling `onError`). - * - * Note: Most applications should use `streamQuery` in order to - * optionally receive updated information over time, should that feature be - * supported by the network/server. A good rule of thumb is to use this method - * if you would otherwise immediately dispose the `streamQuery()` - * after receving the first `onNext` result. - */ - sendQuery(config: { - cacheConfig?: CacheConfig; - onCompleted?(): void; - onError?(error: Error): void; - onNext?(payload: TPayload): void; - operation: COperationSelector; - }): Disposable; - - /** - * Send a query to the server with request/subscription semantics: one or more - * responses may be returned (via `onNext`) over time followed by either - * the request completing (`onCompleted`) or an error (`onError`). - * - * Networks/servers that support subscriptions may choose to hold the - * subscription open indefinitely such that `onCompleted` is not called. - */ - streamQuery(config: { - cacheConfig?: CacheConfig; - onCompleted?(): void; - onError?(error: Error): void; - onNext?(payload: TPayload): void; - operation: COperationSelector; - }): Disposable; - - unstable_internal: CUnstableEnvironmentCore; - } - - interface CUnstableEnvironmentCore { - /** - * Create an instance of a FragmentSpecResolver. - * - * TODO: The FragmentSpecResolver *can* be implemented via the other methods - * defined here, so this could be moved out of core. It's convenient to have - * separate implementations until the experimental core is in OSS. - */ - createFragmentSpecResolver( - context: CRelayContext, - containerName: string, - fragments: CFragmentMap, - props: Props, - callback: () => void - ): FragmentSpecResolver; - - /** - * Creates an instance of an OperationSelector given an operation definition - * (see `getOperation`) and the variables to apply. The input variables are - * filtered to exclude variables that do not matche defined arguments on the - * operation, and default values are populated for null values. - */ - createOperationSelector(operation: TOperation, variables: Variables): COperationSelector; - - /** - * Given a graphql`...` tagged template, extract a fragment definition usable - * by this version of Relay core. Throws if the value is not a fragment. - */ - getFragment(node: TGraphQLTaggedNode): TFragment; - - /** - * Given a graphql`...` tagged template, extract an operation definition - * usable by this version of Relay core. Throws if the value is not an - * operation. - */ - getOperation(node: TGraphQLTaggedNode): TOperation; - - /** - * Determine if two selectors are equal (represent the same selection). Note - * that this function returns `false` when the two queries/fragments are - * different objects, even if they select the same fields. - */ - areEqualSelectors(a: CSelector, b: CSelector): boolean; - - /** - * Given the result `item` from a parent that fetched `fragment`, creates a - * selector that can be used to read the results of that fragment for that item. - * - * Example: - * - * Given two fragments as follows: - * - * ``` - * fragment Parent on User { - * id - * ...Child - * } - * fragment Child on User { - * name - * } - * ``` - * - * And given some object `parent` that is the results of `Parent` for id "4", - * the results of `Child` can be accessed by first getting a selector and then - * using that selector to `lookup()` the results against the environment: - * - * ``` - * const childSelector = getSelector(queryVariables, Child, parent); - * const childData = environment.lookup(childSelector).data; - * ``` - */ - getSelector(operationVariables: Variables, fragment: TFragment, prop: any): CSelector | null; - - /** - * Given the result `items` from a parent that fetched `fragment`, creates a - * selector that can be used to read the results of that fragment on those - * items. This is similar to `getSelector` but for "plural" fragments that - * expect an array of results and therefore return an array of selectors. - */ - getSelectorList( - operationVariables: Variables, - fragment: TFragment, - props: any[] - ): Array> | null; - - /** - * Given a mapping of keys -> results and a mapping of keys -> fragments, - * extracts the selectors for those fragments from the results. - * - * The canonical use-case for this function are Relay Containers, which - * use this function to convert (props, fragments) into selectors so that they - * can read the results to pass to the inner component. - */ - getSelectorsFromObject( - operationVariables: Variables, - fragments: CFragmentMap, - props: Props - ): { [key: string]: CSelector | Array> | null | undefined }; - - /** - * Given a mapping of keys -> results and a mapping of keys -> fragments, - * extracts a mapping of keys -> id(s) of the results. - * - * Similar to `getSelectorsFromObject()`, this function can be useful in - * determining the "identity" of the props passed to a component. - */ - getDataIDsFromObject( - fragments: CFragmentMap, - props: Props - ): { [key: string]: DataID | DataID[] | null | undefined }; - - /** - * Given a mapping of keys -> results and a mapping of keys -> fragments, - * extracts the merged variables that would be in scope for those - * fragments/results. - * - * This can be useful in determing what varaibles were used to fetch the data - * for a Relay container, for example. - */ - getVariablesFromObject( - operationVariables: Variables, - fragments: CFragmentMap, - props: Props - ): Variables; - } - - /** - * The type of the `relay` property set on React context by the React/Relay - * integration layer (e.g. QueryRenderer, FragmentContainer, etc). - */ - interface CRelayContext { - environment: TEnvironment; - variables: Variables; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayTypes - /** - * Version: Relay 1.3.0 - * File: - * https://github.com/facebook/relay/blob/fa9f48ea209ee2402d433b59a84d1cbc046574e2/packages/react-relay/classic/tools/RelayTypes.js - */ - // ~~~~~~~~~~~~~~~~~~~~~ - interface RerunParam { - param: string; - import: string; - max_runs: number; - } - interface FIELDS_CHANGE { - type: "FIELDS_CHANGE"; - fieldIDs: { [fieldName: string]: DataID | DataID[] }; - } - interface RANGE_ADD { - type: "RANGE_ADD"; - parentName?: string; - parentID?: string; - connectionInfo?: Array<{ - key: string; - filters?: Variables; - rangeBehavior: string; - }>; - connectionName?: string; - edgeName: string; - rangeBehaviors?: RangeBehaviors; - } - interface NODE_DELETE { - type: "NODE_DELETE"; - parentName?: string; - parentID?: string; - connectionName?: string; - deletedIDFieldName: string; - } - interface RANGE_DELETE { - type: "RANGE_DELETE"; - parentName?: string; - parentID?: string; - connectionKeys?: Array<{ - key: string; - filters?: Variables; - }>; - connectionName?: string; - deletedIDFieldName: string | string[]; - pathToConnection: string[]; - } - interface REQUIRED_CHILDREN { - type: "REQUIRED_CHILDREN"; - children: RelayConcreteNode[]; - } - type RelayMutationConfig = FIELDS_CHANGE | RANGE_ADD | NODE_DELETE | RANGE_DELETE | REQUIRED_CHILDREN; - - interface RelayMutationTransactionCommitCallbacks { - onFailure?: RelayMutationTransactionCommitFailureCallback; - onSuccess?: RelayMutationTransactionCommitSuccessCallback; - } - type RelayMutationTransactionCommitFailureCallback = ( - transaction: RelayMutationTransaction, - preventAutoRollback: () => void - ) => void; - type RelayMutationTransactionCommitSuccessCallback = ( - response: { - [key: string]: any; - } - ) => void; - interface NetworkLayer { - sendMutation(request: RelayMutationRequest): Promise | null; - sendQueries(requests: RelayQueryRequest[]): Promise | null; - supports(...options: string[]): boolean; - } - interface QueryResult { - error?: Error; - ref_params?: { [name: string]: any }; - response: QueryPayload; - } - interface ReadyState { - aborted: boolean; - done: boolean; - error: Error | null; - events: ReadyStateEvent[]; - ready: boolean; - stale: boolean; - } - type RelayContainerErrorEventType = "CACHE_RESTORE_FAILED" | "NETWORK_QUERY_ERROR"; - type RelayContainerLoadingEventType = - | "ABORT" - | "CACHE_RESTORED_REQUIRED" - | "CACHE_RESTORE_START" - | "NETWORK_QUERY_RECEIVED_ALL" - | "NETWORK_QUERY_RECEIVED_REQUIRED" - | "NETWORK_QUERY_START" - | "STORE_FOUND_ALL" - | "STORE_FOUND_REQUIRED"; - type ReadyStateChangeCallback = (readyState: ReadyState) => void; - interface ReadyStateEvent { - type: RelayContainerLoadingEventType | RelayContainerErrorEventType; - error?: Error; - } - interface Abortable { - abort(): void; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayInternalTypes - /** - * Version: Relay 1.3.0 - * File: - * https://github.com/facebook/relay/blob/master/packages/react-relay/classic/tools/RelayInternalTypes.js - */ - // ~~~~~~~~~~~~~~~~~~~~~ - interface QueryPayload { - [key: string]: any; - } - interface RelayQuerySet { - [queryName: string]: any; - } - type RangeBehaviorsFunction = ( - connectionArgs: { - [argName: string]: any; - } - ) => "APPEND" | "IGNORE" | "PREPEND" | "REFETCH" | "REMOVE"; - interface RangeBehaviorsObject { - [key: string]: "APPEND" | "IGNORE" | "PREPEND" | "REFETCH" | "REMOVE"; - } - type RangeBehaviors = RangeBehaviorsFunction | RangeBehaviorsObject; +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayModernGraphQLTag +// ~~~~~~~~~~~~~~~~~~~~~ +interface GeneratedNodeMap { + [key: string]: GraphQLTaggedNode; } - -export namespace RelayRuntimeTypes { - // ~~~~~~~~~~~~~~~~~~~~~ - // Maybe Fix - // ~~~~~~~~~~~~~~~~~~~~~ - type RelayDebugger = any; - type OptimisticUpdate = any; - type OperationSelector = RelayCommonTypes.COperationSelector; - type Selector = RelayCommonTypes.CSelector; - type PayloadData = any; - type Snapshot = RelayCommonTypes.CSnapshot; - type RelayResponsePayload = any; - type MutableRecordSource = RecordSource; - - /** - * A function that returns an Observable representing the response of executing - * a GraphQL operation. - */ - type ExecuteFunction = ( - operation: object, - variables: RelayCommonTypes.Variables, - cacheConfig: RelayCommonTypes.CacheConfig, - uploadables?: RelayCommonTypes.UploadableMap - ) => Promise; - interface RelayNetwork { - execute: ExecuteFunction; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayDefaultHandlerProvider - // ~~~~~~~~~~~~~~~~~~~~~ - function HandlerProvider(name: string): typeof RelayCommonTypes.Handler | null; - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayModernEnvironment - // ~~~~~~~~~~~~~~~~~~~~~ - interface EnvironmentConfig { - configName?: string; - handlerProvider?: typeof HandlerProvider; - network: Network; - store: Store; - } - class Environment { - constructor(config: EnvironmentConfig); - getStore(): Store; - getDebugger(): RelayDebugger; - applyUpdate(optimisticUpdate: OptimisticUpdate): RelayCommonTypes.Disposable; - revertUpdate(update: OptimisticUpdate): void; - replaceUpdate(update: OptimisticUpdate, newUpdate: OptimisticUpdate): void; - applyMutation(config: { - operation: OperationSelector; - optimisticUpdater?: RelayCommonTypes.SelectorStoreUpdater; - optimisticResponse?: object; - }): RelayCommonTypes.Disposable; - check(readSelector: Selector): boolean; - commitPayload(operationSelector: OperationSelector, payload: PayloadData): void; - commitUpdate(updater: RelayCommonTypes.StoreUpdater): void; - lookup(readSelector: Selector): Snapshot; - subscribe(snapshot: Snapshot, callback: (snapshot: Snapshot) => void): RelayCommonTypes.Disposable; - retain(selector: Selector): RelayCommonTypes.Disposable; - execute(config: { - operation: OperationSelector; - cacheConfig?: RelayCommonTypes.CacheConfig; - updater?: RelayCommonTypes.SelectorStoreUpdater; - }): RelayObservable; - executeMutation(config: { - operation: OperationSelector; - optimisticUpdater?: RelayCommonTypes.SelectorStoreUpdater; - optimisticResponse?: object; - updater?: RelayCommonTypes.SelectorStoreUpdater; - uploadables?: RelayCommonTypes.UploadableMap; - }): RelayObservable; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayInMemoryRecordSource - // ~~~~~~~~~~~~~~~~~~~~~ - interface Record { - [key: string]: any; - } - interface RecordMap { - [dataID: string]: Record | null | undefined; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // Network - // ~~~~~~~~~~~~~~~~~~~~~ - class Network { - /** - * Creates an implementation of the `Network` interface defined in - * `RelayNetworkTypes` given `fetch` and `subscribe` functions. - */ - static create( - fetchFn: typeof RelayCommonTypes.FetchFunction, - subscribeFn?: RelayCommonTypes.SubscribeFunction - ): RelayNetwork; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // Network - // ~~~~~~~~~~~~~~~~~~~~~ - class RecordSource { - constructor(records?: RecordMap); - clear(): void; - delete(dataID: RelayCommonTypes.DataID): void; - get(dataID: RelayCommonTypes.DataID): Record | null; - getRecordIDs(): RelayCommonTypes.DataID[]; - getStatus(dataID: RelayCommonTypes.DataID): "EXISTENT" | "NONEXISTENT" | "UNKNOWN"; - has(dataID: RelayCommonTypes.DataID): boolean; - load(dataID: RelayCommonTypes.DataID, callback: (error: Error | null, record: Record | null) => void): void; - remove(dataID: RelayCommonTypes.DataID): void; - set(dataID: RelayCommonTypes.DataID, record: Record): void; - size(): number; - toJSON(): RecordMap; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // ModernStore - // ~~~~~~~~~~~~~~~~~~~~~ - class Store { - constructor(source: RecordSource); - getSource(): MutableRecordSource; - check(selector: Selector): boolean; - retain(selector: Selector): RelayCommonTypes.Disposable; - lookup(selector: Selector): Snapshot; - notify(): void; - publish(source: RecordSource): void; - subscribe(snapshot: Snapshot, callback: (snapshot: Snapshot) => void): RelayCommonTypes.Disposable; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayRecordSourceInspector - // ~~~~~~~~~~~~~~~~~~~~~ - /** - * An internal class to provide a console-friendly string representation of a - * Record. - */ - class RecordSummary { - id: RelayCommonTypes.DataID; - type: string | null | undefined; - static createFromRecord(id: RelayCommonTypes.DataID, record: any): RecordSummary; - constructor(id: RelayCommonTypes.DataID, type: string | null | undefined); - toString(): string; - } - /** - * Internal class for inspecting a single Record. - */ - class RecordInspector { - constructor(sourceInspector: RelayRecordSourceInspector, record: Record); - /** - * Get the cache id of the given record. For types that implement the `Node` - * interface (or that have an `id`) this will be `id`, for other types it will be - * a synthesized identifier based on the field path from the nearest ancestor - * record that does have an `id`. - */ - getDataID(): RelayCommonTypes.DataID; - - /** - * Returns a list of the fields that have been fetched on the current record. - */ - getFields(): string[]; - - /** - * Returns the type of the record. - */ - getType(): string; - - /** - * Returns a copy of the internal representation of the record. - */ - inspect(): any; - - /** - * Returns the value of a scalar field. May throw if the given field is - * present but not actually scalar. - */ - getValue(name: string, args?: RelayCommonTypes.Variables): any; - - /** - * Returns an inspector for the given scalar "linked" field (a field whose - * value is another Record instead of a scalar). May throw if the field is - * present but not a scalar linked record. - */ - getLinkedRecord(name: string, args?: RelayCommonTypes.Variables): RecordInspector | null; - - /** - * Returns an array of inspectors for the given plural "linked" field (a field - * whose value is an array of Records instead of a scalar). May throw if the - * field is present but not a plural linked record. - */ - getLinkedRecords(name: string, args?: RelayCommonTypes.Variables): RecordInspector[] | null; - } - - class RelayRecordSourceInspector { - constructor(source: RecordSource); - static getForEnvironment(environment: Environment): RelayRecordSourceInspector; - /** - * Returns an inspector for the record with the given id, or null/undefined if - * that record is deleted/unfetched. - */ - get(dataID: RelayCommonTypes.DataID): RecordInspector | null; - /** - * Returns a list of ": " for each record in the store that has an - * `id`. - */ - getNodes(): RecordSummary[]; - /** - * Returns a list of ": " for all records in the store including - * those that do not have an `id`. - */ - getRecords(): RecordSummary[]; - - /** - * Returns an inspector for the synthesized "root" object, allowing access to - * e.g. the `viewer` object or the results of other fields on the "Query" - * type. - */ - getRoot(): RecordInspector; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // RelayObservable - // ~~~~~~~~~~~~~~~~~~~~~ - interface Subscription { - unsubscribe(): void; - readonly closed: boolean; - } - interface Observer { - start?(subscription: Subscription): any; - next?(nextThing: T): any; - error?(error: Error): any; - complete?(): any; - unsubscribe?(subscription: Subscription): any; - } - type Source = () => any; - interface Subscribable { - subscribe(observer: Observer): Subscription; - } - type ObservableFromValue = RelayObservable | Promise | T; - class RelayObservable implements Subscribable { - _source: Source; - - constructor(source: Source); - - /** - * When an unhandled error is detected, it is reported to the host environment - * (the ESObservable spec refers to this method as "HostReportErrors()"). - * - * The default implementation in development builds re-throws errors in a - * separate frame, and from production builds does nothing (swallowing - * uncaught errors). - * - * Called during application initialization, this method allows - * application-specific handling of uncaught errors. Allowing, for example, - * integration with error logging or developer tools. - */ - static onUnhandledError(callback: (error: Error) => any): void; - - /** - * Accepts various kinds of data sources, and always returns a RelayObservable - * useful for accepting the result of a user-provided FetchFunction. - */ - static from(obj: ObservableFromValue): RelayObservable; - - /** - * Creates a RelayObservable, given a function which expects a legacy - * Relay Observer as the last argument and which returns a Disposable. - * - * To support migration to Observable, the function may ignore the - * legacy Relay observer and directly return an Observable instead. - */ - static fromLegacy( - callback: ( - legacyObserver: RelayCommonTypes.LegacyObserver - ) => RelayCommonTypes.Disposable | RelayObservable - ): RelayObservable; - - /** - * Returns a new Observable which returns the same values as this one, but - * modified so that the provided Observer is called to perform a side-effects - * for all events emitted by the source. - * - * Any errors that are thrown in the side-effect Observer are unhandled, and - * do not affect the source Observable or its Observer. - * - * This is useful for when debugging your Observables or performing other - * side-effects such as logging or performance monitoring. - */ - do(observer: Observer): RelayObservable; - - /** - * Returns a new Observable which returns the same values as this one, but - * modified so that the finally callback is performed after completion, - * whether normal or due to error or unsubscription. - * - * This is useful for cleanup such as resource finalization. - */ - finally(fn: () => any): RelayObservable; - - /** - * Returns a new Observable which is identical to this one, unless this - * Observable completes before yielding any values, in which case the new - * Observable will yield the values from the alternate Observable. - * - * If this Observable does yield values, the alternate is never subscribed to. - * - * This is useful for scenarios where values may come from multiple sources - * which should be tried in order, i.e. from a cache before a network. - */ - ifEmpty(alternate: RelayObservable): RelayObservable; - - /** - * Observable's primary API: returns an unsubscribable Subscription to the - * source of this Observable. - */ - subscribe(observer: Observer): Subscription; - - /** - * Supports subscription of a legacy Relay Observer, returning a Disposable. - */ - subscribeLegacy(legacyObserver: RelayCommonTypes.LegacyObserver): RelayCommonTypes.Disposable; - - /** - * Returns a new Observerable where each value has been transformed by - * the mapping function. - */ - map(fn: (thing: T) => U): RelayObservable; - - /** - * Returns a new Observable where each value is replaced with a new Observable - * by the mapping function, the results of which returned as a single - * concattenated Observable. - */ - concatMap(fn: (thing: T) => ObservableFromValue): RelayObservable; - - /** - * Returns a new Observable which first mirrors this Observable, then when it - * completes, waits for `pollInterval` milliseconds before re-subscribing to - * this Observable again, looping in this manner until unsubscribed. - * - * The returned Observable never completes. - */ - poll(pollInterval: number): RelayObservable; - - /** - * Returns a Promise which resolves when this Observable yields a first value - * or when it completes with no value. - */ - toPromise(): Promise; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // commitLocalUpdate - // ~~~~~~~~~~~~~~~~~~~~~ - // exposed through RelayModern, not Runtime directly - type commitLocalUpdate = (environment: Environment, updater: RelayCommonTypes.StoreUpdater) => void; - - // ~~~~~~~~~~~~~~~~~~~~~ - // commitRelayModernMutation - // ~~~~~~~~~~~~~~~~~~~~~ - // exposed through RelayModern, not Runtime directly - interface MutationConfig { - configs?: RelayCommonTypes.RelayMutationConfig[]; - mutation: RelayCommonTypes.GraphQLTaggedNode; - variables: RelayCommonTypes.Variables; - uploadables?: RelayCommonTypes.UploadableMap; - onCompleted?(response: T, errors: RelayCommonTypes.PayloadError[] | null | undefined): void; - onError?(error?: Error): void; - optimisticUpdater?: RelayCommonTypes.SelectorStoreUpdater; - optimisticResponse?: object; - updater?: RelayCommonTypes.SelectorStoreUpdater; - } - function commitRelayModernMutation( - environment: Environment, - config: MutationConfig - ): RelayCommonTypes.Disposable; - - // ~~~~~~~~~~~~~~~~~~~~~ - // applyRelayModernOptimisticMutation - // ~~~~~~~~~~~~~~~~~~~~~ - // exposed through RelayModern, not Runtime directly - interface OptimisticMutationConfig { - configs?: RelayCommonTypes.RelayMutationConfig[]; - mutation: RelayCommonTypes.GraphQLTaggedNode; - variables: RelayCommonTypes.Variables; - optimisticUpdater?: RelayCommonTypes.SelectorStoreUpdater; - optimisticResponse?: object; - } - - // ~~~~~~~~~~~~~~~~~~~~~ - // fetchRelayModernQuery - // ~~~~~~~~~~~~~~~~~~~~~ - // exposed through RelayModern, not Runtime directly - /** - * A helper function to fetch the results of a query. Note that results for - * fragment spreads are masked: fields must be explicitly listed in the query in - * order to be accessible in the result object. - * - * NOTE: This module is primarily intended for integrating with classic APIs. - * Most product code should use a Renderer or Container. - * - * TODO(t16875667): The return type should be `Promise`, but - * that's not really helpful as `SelectorData` is essentially just `mixed`. We - * can probably leverage generated flow types here to return the real expected - * shape. - */ - function fetchRelayModernQuery( - environment: any, // FIXME - $FlowFixMe in facebook source code - taggedNode: RelayCommonTypes.GraphQLTaggedNode, - variables: RelayCommonTypes.Variables, - cacheConfig?: RelayCommonTypes.CacheConfig - ): Promise; // FIXME - $FlowFixMe in facebook source code - - // ~~~~~~~~~~~~~~~~~~~~~ - // requestRelaySubscription - // ~~~~~~~~~~~~~~~~~~~~~ - // exposed through RelayModern, not Runtime directly - interface GraphQLSubscriptionConfig { - configs?: RelayCommonTypes.RelayMutationConfig[]; - subscription: RelayCommonTypes.GraphQLTaggedNode; - variables: RelayCommonTypes.Variables; - onCompleted?(): void; - onError?(error: Error): void; - onNext?(response: object | null | undefined): void; - updater?(store: RelayCommonTypes.RecordSourceSelectorProxy): void; - } - function requestRelaySubscription( - environment: Environment, - config: GraphQLSubscriptionConfig - ): RelayCommonTypes.Disposable; +type GraphQLTaggedNode = + | (() => ConcreteFragment | ConcreteBatch) + | { + modern(): ConcreteFragment | ConcreteBatch; + classic(relayQL: RelayQL): ConcreteFragmentDefinition | ConcreteOperationDefinition; + }; +// ~~~~~~~~~~~~~~~~~~~~~ +// General Usage +// ~~~~~~~~~~~~~~~~~~~~~ +type DataID = string; +interface Variables { + [name: string]: any; +} +type Uploadable = File | Blob; +interface UploadableMap { + [key: string]: Uploadable; } // ~~~~~~~~~~~~~~~~~~~~~ -// Package Exports +// RelayNetworkTypes +// Version: Relay 1.3.0 +// File: https://github.com/facebook/relay/blob/master/packages/relay-runtime/network/RelayNetworkTypes.js // ~~~~~~~~~~~~~~~~~~~~~ -export import Environment = RelayRuntimeTypes.Environment; -export import Network = RelayRuntimeTypes.Network; -export import RecordSource = RelayRuntimeTypes.RecordSource; -export import Store = RelayRuntimeTypes.Store; -export import Observable = RelayRuntimeTypes.RelayObservable; + +interface LegacyObserver { + onCompleted?(): void; + onError?(error: Error): void; + onNext?(data: T): void; +} +interface PayloadError { + message: string; + locations?: Array<{ + line: number; + column: number; + }>; +} +/** + * A function that executes a GraphQL operation with request/response semantics. + * + * May return an Observable or Promise of a raw server response. + */ +declare function FetchFunction( + operation: ConcreteBatch, + variables: Variables, + cacheConfig: CacheConfig, + uploadables?: UploadableMap +): ObservableFromValue; + +/** + * A function that executes a GraphQL subscription operation, returning one or + * more raw server responses over time. + * + * May return an Observable, otherwise must call the callbacks found in the + * fourth parameter. + */ +type SubscribeFunction = ( + operation: ConcreteBatch, + variables: Variables, + cacheConfig: CacheConfig, + observer: LegacyObserver +) => RelayObservable | Disposable; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayStoreTypes +// Version: Relay 1.3.0 +// File: https://github.com/facebook/relay/blob/master/packages/relay-runtime/store/RelayStoreTypes.js +// ~~~~~~~~~~~~~~~~~~~~~ +/** + * A function that receives a proxy over the store and may trigger side-effects + * (indirectly) by calling `set*` methods on the store or its record proxies. + */ +type StoreUpdater = (store: RecordSourceProxy) => void; + +/** + * Similar to StoreUpdater, but accepts a proxy tied to a specific selector in + * order to easily access the root fields of a query/mutation as well as a + * second argument of the response object of the mutation. + */ +type SelectorStoreUpdater = ( + store: RecordSourceSelectorProxy, + // Actually RelayCombinedEnvironmentTypes#SelectorData, but mixed is + // inconvenient to access deeply in product code. + data: any // FLOW FIXME +) => void; + +/** + * Extends the RecordSourceProxy interface with methods for accessing the root + * fields of a Selector. + */ +interface RecordSourceSelectorProxy { + create(dataID: DataID, typeName: string): RecordProxy; + delete(dataID: DataID): void; + get(dataID: DataID): RecordProxy | null; + getRoot(): RecordProxy; + getRootField(fieldName: string): RecordProxy | null; + getPluralRootField(fieldName: string): RecordProxy[] | null; +} + +interface RecordProxy { + copyFieldsFrom(source: RecordProxy): void; + getDataID(): DataID; + getLinkedRecord(name: string, args?: Variables): RecordProxy | null; + getLinkedRecords(name: string, args?: Variables): Array | null; + getOrCreateLinkedRecord(name: string, typeName: string, args?: Variables): RecordProxy; + getType(): string; + getValue(name: string, args?: Variables): any; + setLinkedRecord(record: RecordProxy, name: string, args?: Variables): RecordProxy; + setLinkedRecords( + records: Array | undefined | null, + name: string, + args?: Variables + ): RecordProxy; + setValue(value: any, name: string, args?: Variables): RecordProxy; +} + +interface RecordSourceProxy { + create(dataID: DataID, typeName: string): RecordProxy; + delete(dataID: DataID): void; + get(dataID: DataID): Array | null; + getRoot(): RecordProxy; +} + +interface HandleFieldPayload { + // The arguments that were fetched. + args: Variables; + // The __id of the record containing the source/handle field. + dataID: DataID; + // The (storage) key at which the original server data was written. + fieldKey: string; + // The name of the handle + handle: string; + // The (storage) key at which the handle's data should be written by the + // handler + handleKey: string; +} +interface HandlerInterface { + update(store: RecordSourceProxy, fieldPayload: HandleFieldPayload): void; + [functionName: string]: (...args: any[]) => any; +} +export const ConnectionHandler: HandlerInterface; +export const ViewerHandler: HandlerInterface; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayCombinedEnvironmentTypes +// Version: Relay 1.3.0 +// File: https://github.com/facebook/relay/blob/b85a1d69bb72be4ace67179f55c2a54a8d761c8b/packages/react-relay/classic/environment/RelayCombinedEnvironmentTypes.js +// ~~~~~~~~~~~~~~~~~~~~~ +/** + * Settings for how a query response may be cached. + * + * - `force`: causes a query to be issued unconditionally, irrespective of the + * state of any configured response cache. + * - `poll`: causes a query to live update by polling at the specified interval + * in milliseconds. (This value will be passed to setTimeout.) + */ +interface CacheConfig { + force?: boolean; + poll?: number; +} + +/** + * Represents any resource that must be explicitly disposed of. The most common + * use-case is as a return value for subscriptions, where calling `dispose()` + * would cancel the subscription. + */ +interface Disposable { + dispose(): void; +} + +/** + * Arbitrary data e.g. received by a container as props. + */ +interface Props { + [key: string]: any; +} + +/** + * A selector defines the starting point for a traversal into the graph for the + * purposes of targeting a subgraph. + */ +interface CSelector { + dataID: DataID; + node: TNode; + variables: Variables; +} + +/** + * A representation of a selector and its results at a particular point in time. + */ +type CSnapshot = CSelector & { + data: SelectorData | null | undefined; + seenRecords: RecordMap; +}; + +/** + * The results of a selector given a store/RecordSource. + */ +interface SelectorData { + [key: string]: any; +} + +/** + * The results of reading the results of a FragmentMap given some input + * `Props`. + */ +interface FragmentSpecResults { + [key: string]: any; +} + +/** + * A utility for resolving and subscribing to the results of a fragment spec + * (key -> fragment mapping) given some "props" that determine the root ID + * and variables to use when reading each fragment. When props are changed via + * `setProps()`, the resolver will update its results and subscriptions + * accordingly. Internally, the resolver: + * - Converts the fragment map & props map into a map of `Selector`s. + * - Removes any resolvers for any props that became null. + * - Creates resolvers for any props that became non-null. + * - Updates resolvers with the latest props. + */ +interface FragmentSpecResolver { + /** + * Stop watching for changes to the results of the fragments. + */ + dispose(): void; + + /** + * Get the current results. + */ + resolve(): FragmentSpecResults; + + /** + * Update the resolver with new inputs. Call `resolve()` to get the updated + * results. + */ + setProps(props: Props): void; + + /** + * Override the variables used to read the results of the fragments. Call + * `resolve()` to get the updated results. + */ + setVariables(variables: Variables): void; +} + +interface CFragmentMap { + [key: string]: TFragment; +} + +/** + * An operation selector describes a specific instance of a GraphQL operation + * with variables applied. + * + * - `root`: a selector intended for processing server results or retaining + * response data in the store. + * - `fragment`: a selector intended for use in reading or subscribing to + * the results of the the operation. + */ +interface COperationSelector { + fragment: CSelector; + node: TOperation; + root: CSelector; + variables: Variables; +} + +/** + * The public API of Relay core. Represents an encapsulated environment with its + * own in-memory cache. + */ +interface CEnvironment { + /** + * Read the results of a selector from in-memory records in the store. + */ + lookup(selector: CSelector): CSnapshot; + + /** + * Subscribe to changes to the results of a selector. The callback is called + * when data has been committed to the store that would cause the results of + * the snapshot's selector to change. + */ + subscribe(snapshot: CSnapshot, callback: (snapshot: CSnapshot) => void): Disposable; + + /** + * Ensure that all the records necessary to fulfill the given selector are + * retained in-memory. The records will not be eligible for garbage collection + * until the returned reference is disposed. + * + * Note: This is a no-op in the classic core. + */ + retain(selector: CSelector): Disposable; + + /** + * Send a query to the server with request/response semantics: the query will + * either complete successfully (calling `onNext` and `onCompleted`) or fail + * (calling `onError`). + * + * Note: Most applications should use `streamQuery` in order to + * optionally receive updated information over time, should that feature be + * supported by the network/server. A good rule of thumb is to use this method + * if you would otherwise immediately dispose the `streamQuery()` + * after receving the first `onNext` result. + */ + sendQuery(config: { + cacheConfig?: CacheConfig; + onCompleted?(): void; + onError?(error: Error): void; + onNext?(payload: TPayload): void; + operation: COperationSelector; + }): Disposable; + + /** + * Send a query to the server with request/subscription semantics: one or more + * responses may be returned (via `onNext`) over time followed by either + * the request completing (`onCompleted`) or an error (`onError`). + * + * Networks/servers that support subscriptions may choose to hold the + * subscription open indefinitely such that `onCompleted` is not called. + */ + streamQuery(config: { + cacheConfig?: CacheConfig; + onCompleted?(): void; + onError?(error: Error): void; + onNext?(payload: TPayload): void; + operation: COperationSelector; + }): Disposable; + + unstable_internal: CUnstableEnvironmentCore; +} + +interface CUnstableEnvironmentCore { + /** + * Create an instance of a FragmentSpecResolver. + * + * TODO: The FragmentSpecResolver *can* be implemented via the other methods + * defined here, so this could be moved out of core. It's convenient to have + * separate implementations until the experimental core is in OSS. + */ + createFragmentSpecResolver( + context: CRelayContext, + containerName: string, + fragments: CFragmentMap, + props: Props, + callback: () => void + ): FragmentSpecResolver; + + /** + * Creates an instance of an OperationSelector given an operation definition + * (see `getOperation`) and the variables to apply. The input variables are + * filtered to exclude variables that do not matche defined arguments on the + * operation, and default values are populated for null values. + */ + createOperationSelector(operation: TOperation, variables: Variables): COperationSelector; + + /** + * Given a graphql`...` tagged template, extract a fragment definition usable + * by this version of Relay core. Throws if the value is not a fragment. + */ + getFragment(node: TGraphQLTaggedNode): TFragment; + + /** + * Given a graphql`...` tagged template, extract an operation definition + * usable by this version of Relay core. Throws if the value is not an + * operation. + */ + getOperation(node: TGraphQLTaggedNode): TOperation; + + /** + * Determine if two selectors are equal (represent the same selection). Note + * that this function returns `false` when the two queries/fragments are + * different objects, even if they select the same fields. + */ + areEqualSelectors(a: CSelector, b: CSelector): boolean; + + /** + * Given the result `item` from a parent that fetched `fragment`, creates a + * selector that can be used to read the results of that fragment for that item. + * + * Example: + * + * Given two fragments as follows: + * + * ``` + * fragment Parent on User { + * id + * ...Child + * } + * fragment Child on User { + * name + * } + * ``` + * + * And given some object `parent` that is the results of `Parent` for id "4", + * the results of `Child` can be accessed by first getting a selector and then + * using that selector to `lookup()` the results against the environment: + * + * ``` + * const childSelector = getSelector(queryVariables, Child, parent); + * const childData = environment.lookup(childSelector).data; + * ``` + */ + getSelector(operationVariables: Variables, fragment: TFragment, prop: any): CSelector | null; + + /** + * Given the result `items` from a parent that fetched `fragment`, creates a + * selector that can be used to read the results of that fragment on those + * items. This is similar to `getSelector` but for "plural" fragments that + * expect an array of results and therefore return an array of selectors. + */ + getSelectorList(operationVariables: Variables, fragment: TFragment, props: any[]): Array> | null; + + /** + * Given a mapping of keys -> results and a mapping of keys -> fragments, + * extracts the selectors for those fragments from the results. + * + * The canonical use-case for this function are Relay Containers, which + * use this function to convert (props, fragments) into selectors so that they + * can read the results to pass to the inner component. + */ + getSelectorsFromObject( + operationVariables: Variables, + fragments: CFragmentMap, + props: Props + ): { [key: string]: CSelector | Array> | null | undefined }; + + /** + * Given a mapping of keys -> results and a mapping of keys -> fragments, + * extracts a mapping of keys -> id(s) of the results. + * + * Similar to `getSelectorsFromObject()`, this function can be useful in + * determining the "identity" of the props passed to a component. + */ + getDataIDsFromObject( + fragments: CFragmentMap, + props: Props + ): { [key: string]: DataID | DataID[] | null | undefined }; + + /** + * Given a mapping of keys -> results and a mapping of keys -> fragments, + * extracts the merged variables that would be in scope for those + * fragments/results. + * + * This can be useful in determing what varaibles were used to fetch the data + * for a Relay container, for example. + */ + getVariablesFromObject(operationVariables: Variables, fragments: CFragmentMap, props: Props): Variables; +} + +/** + * The type of the `relay` property set on React context by the React/Relay + * integration layer (e.g. QueryRenderer, FragmentContainer, etc). + */ +interface CRelayContext { + environment: TEnvironment; + variables: Variables; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayTypes +/** + * Version: Relay 1.3.0 + * File: + * https://github.com/facebook/relay/blob/fa9f48ea209ee2402d433b59a84d1cbc046574e2/packages/react-relay/classic/tools/RelayTypes.js + */ +// ~~~~~~~~~~~~~~~~~~~~~ +interface RerunParam { + param: string; + import: string; + max_runs: number; +} +interface FIELDS_CHANGE { + type: "FIELDS_CHANGE"; + fieldIDs: { [fieldName: string]: DataID | DataID[] }; +} +interface RANGE_ADD { + type: "RANGE_ADD"; + parentName?: string; + parentID?: string; + connectionInfo?: Array<{ + key: string; + filters?: Variables; + rangeBehavior: string; + }>; + connectionName?: string; + edgeName: string; + rangeBehaviors?: RangeBehaviors; +} +interface NODE_DELETE { + type: "NODE_DELETE"; + parentName?: string; + parentID?: string; + connectionName?: string; + deletedIDFieldName: string; +} +interface RANGE_DELETE { + type: "RANGE_DELETE"; + parentName?: string; + parentID?: string; + connectionKeys?: Array<{ + key: string; + filters?: Variables; + }>; + connectionName?: string; + deletedIDFieldName: string | string[]; + pathToConnection: string[]; +} +interface REQUIRED_CHILDREN { + type: "REQUIRED_CHILDREN"; + children: RelayConcreteNode[]; +} +type RelayMutationConfig = FIELDS_CHANGE | RANGE_ADD | NODE_DELETE | RANGE_DELETE | REQUIRED_CHILDREN; + +interface RelayMutationTransactionCommitCallbacks { + onFailure?: RelayMutationTransactionCommitFailureCallback; + onSuccess?: RelayMutationTransactionCommitSuccessCallback; +} +type RelayMutationTransactionCommitFailureCallback = ( + transaction: RelayMutationTransaction, + preventAutoRollback: () => void +) => void; +type RelayMutationTransactionCommitSuccessCallback = ( + response: { + [key: string]: any; + } +) => void; +interface NetworkLayer { + sendMutation(request: RelayMutationRequest): Promise | null; + sendQueries(requests: RelayQueryRequest[]): Promise | null; + supports(...options: string[]): boolean; +} +interface QueryResult { + error?: Error; + ref_params?: { [name: string]: any }; + response: QueryPayload; +} +interface ReadyState { + aborted: boolean; + done: boolean; + error: Error | null; + events: ReadyStateEvent[]; + ready: boolean; + stale: boolean; +} +type RelayContainerErrorEventType = "CACHE_RESTORE_FAILED" | "NETWORK_QUERY_ERROR"; +type RelayContainerLoadingEventType = + | "ABORT" + | "CACHE_RESTORED_REQUIRED" + | "CACHE_RESTORE_START" + | "NETWORK_QUERY_RECEIVED_ALL" + | "NETWORK_QUERY_RECEIVED_REQUIRED" + | "NETWORK_QUERY_START" + | "STORE_FOUND_ALL" + | "STORE_FOUND_REQUIRED"; +type ReadyStateChangeCallback = (readyState: ReadyState) => void; +interface ReadyStateEvent { + type: RelayContainerLoadingEventType | RelayContainerErrorEventType; + error?: Error; +} +interface Abortable { + abort(): void; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayInternalTypes +/** + * Version: Relay 1.3.0 + * File: + * https://github.com/facebook/relay/blob/master/packages/react-relay/classic/tools/RelayInternalTypes.js + */ +// ~~~~~~~~~~~~~~~~~~~~~ +interface QueryPayload { + [key: string]: any; +} +interface RelayQuerySet { + [queryName: string]: any; +} +type RangeBehaviorsFunction = ( + connectionArgs: { + [argName: string]: any; + } +) => "APPEND" | "IGNORE" | "PREPEND" | "REFETCH" | "REMOVE"; +interface RangeBehaviorsObject { + [key: string]: "APPEND" | "IGNORE" | "PREPEND" | "REFETCH" | "REMOVE"; +} +type RangeBehaviors = RangeBehaviorsFunction | RangeBehaviorsObject; + +// ~~~~~~~~~~~~~~~~~~~~~ +// Maybe Fix +// ~~~~~~~~~~~~~~~~~~~~~ +type RelayDebugger = any; +type OptimisticUpdate = any; +type OperationSelector = COperationSelector; +type Selector = CSelector; +type PayloadData = any; +type Snapshot = CSnapshot; +type RelayResponsePayload = any; +type MutableRecordSource = RecordSource; + +/** + * A function that returns an Observable representing the response of executing + * a GraphQL operation. + */ +type ExecuteFunction = ( + operation: object, + variables: Variables, + cacheConfig: CacheConfig, + uploadables?: UploadableMap +) => Promise; +interface RelayNetwork { + execute: ExecuteFunction; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayDefaultHandlerProvider +// ~~~~~~~~~~~~~~~~~~~~~ +declare function HandlerProvider(name: string): HandlerInterface | null; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayModernEnvironment +// ~~~~~~~~~~~~~~~~~~~~~ +interface EnvironmentConfig { + configName?: string; + handlerProvider?: typeof HandlerProvider; + network: Network; + store: Store; +} +export class Environment { + constructor(config: EnvironmentConfig); + getStore(): Store; + getDebugger(): RelayDebugger; + applyUpdate(optimisticUpdate: OptimisticUpdate): Disposable; + revertUpdate(update: OptimisticUpdate): void; + replaceUpdate(update: OptimisticUpdate, newUpdate: OptimisticUpdate): void; + applyMutation(config: { + operation: OperationSelector; + optimisticUpdater?: SelectorStoreUpdater; + optimisticResponse?: object; + }): Disposable; + check(readSelector: Selector): boolean; + commitPayload(operationSelector: OperationSelector, payload: PayloadData): void; + commitUpdate(updater: StoreUpdater): void; + lookup(readSelector: Selector): Snapshot; + subscribe(snapshot: Snapshot, callback: (snapshot: Snapshot) => void): Disposable; + retain(selector: Selector): Disposable; + execute(config: { + operation: OperationSelector; + cacheConfig?: CacheConfig; + updater?: SelectorStoreUpdater; + }): RelayObservable; + executeMutation(config: { + operation: OperationSelector; + optimisticUpdater?: SelectorStoreUpdater; + optimisticResponse?: object; + updater?: SelectorStoreUpdater; + uploadables?: UploadableMap; + }): RelayObservable; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayInMemoryRecordSource +// ~~~~~~~~~~~~~~~~~~~~~ +interface RelayInMemoryRecordSource { + [key: string]: any; +} +interface RecordMap { + [dataID: string]: RelayInMemoryRecordSource | null | undefined; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// Network +// ~~~~~~~~~~~~~~~~~~~~~ +export class Network { + /** + * Creates an implementation of the `Network` interface defined in + * `RelayNetworkTypes` given `fetch` and `subscribe` functions. + */ + static create(fetchFn: typeof FetchFunction, subscribeFn?: SubscribeFunction): RelayNetwork; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// Network +// ~~~~~~~~~~~~~~~~~~~~~ +declare class RecordSource { + constructor(records?: RecordMap); + clear(): void; + delete(dataID: DataID): void; + get(dataID: DataID): RelayInMemoryRecordSource | null; + getRecordIDs(): DataID[]; + getStatus(dataID: DataID): "EXISTENT" | "NONEXISTENT" | "UNKNOWN"; + has(dataID: DataID): boolean; + load(dataID: DataID, callback: (error: Error | null, record: RelayInMemoryRecordSource | null) => void): void; + remove(dataID: DataID): void; + set(dataID: DataID, record: RelayInMemoryRecordSource): void; + size(): number; + toJSON(): RecordMap; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// ModernStore +// ~~~~~~~~~~~~~~~~~~~~~ +export class Store { + constructor(source: RecordSource); + getSource(): MutableRecordSource; + check(selector: Selector): boolean; + retain(selector: Selector): Disposable; + lookup(selector: Selector): Snapshot; + notify(): void; + publish(source: RecordSource): void; + subscribe(snapshot: Snapshot, callback: (snapshot: Snapshot) => void): Disposable; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayRecordSourceInspector +// ~~~~~~~~~~~~~~~~~~~~~ +/** + * An internal class to provide a console-friendly string representation of a + * RelayInMemoryRecordSource. + */ +declare class RecordSummary { + id: DataID; + type: string | null | undefined; + static createFromRecord(id: DataID, record: any): RecordSummary; + constructor(id: DataID, type: string | null | undefined); + toString(): string; +} +/** + * Internal class for inspecting a single RelayInMemoryRecordSource. + */ +declare class RecordInspector { + constructor(sourceInspector: RelayRecordSourceInspector, record: RelayInMemoryRecordSource); + /** + * Get the cache id of the given record. For types that implement the `Node` + * interface (or that have an `id`) this will be `id`, for other types it will be + * a synthesized identifier based on the field path from the nearest ancestor + * record that does have an `id`. + */ + getDataID(): DataID; + + /** + * Returns a list of the fields that have been fetched on the current record. + */ + getFields(): string[]; + + /** + * Returns the type of the record. + */ + getType(): string; + + /** + * Returns a copy of the internal representation of the record. + */ + inspect(): any; + + /** + * Returns the value of a scalar field. May throw if the given field is + * present but not actually scalar. + */ + getValue(name: string, args?: Variables): any; + + /** + * Returns an inspector for the given scalar "linked" field (a field whose + * value is another RelayInMemoryRecordSource instead of a scalar). May throw if the field is + * present but not a scalar linked record. + */ + getLinkedRecord(name: string, args?: Variables): RecordInspector | null; + + /** + * Returns an array of inspectors for the given plural "linked" field (a field + * whose value is an array of Records instead of a scalar). May throw if the + * field is present but not a plural linked record. + */ + getLinkedRecords(name: string, args?: Variables): RecordInspector[] | null; +} + +declare class RelayRecordSourceInspector { + constructor(source: RecordSource); + static getForEnvironment(environment: Environment): RelayRecordSourceInspector; + /** + * Returns an inspector for the record with the given id, or null/undefined if + * that record is deleted/unfetched. + */ + get(dataID: DataID): RecordInspector | null; + /** + * Returns a list of ": " for each record in the store that has an + * `id`. + */ + getNodes(): RecordSummary[]; + /** + * Returns a list of ": " for all records in the store including + * those that do not have an `id`. + */ + getRecords(): RecordSummary[]; + + /** + * Returns an inspector for the synthesized "root" object, allowing access to + * e.g. the `viewer` object or the results of other fields on the "Query" + * type. + */ + getRoot(): RecordInspector; +} + // note RecordSourceInspector is only available in dev environment -export import RecordSourceInspector = RelayRuntimeTypes.RelayRecordSourceInspector; -export import ConnectionHandler = RelayCommonTypes.Handler; -export import ViewerHandler = RelayCommonTypes.Handler; +export type RecordSourceInspector = RelayRecordSourceInspector; + +// ~~~~~~~~~~~~~~~~~~~~~ +// RelayObservable +// ~~~~~~~~~~~~~~~~~~~~~ +interface Subscription { + unsubscribe(): void; + readonly closed: boolean; +} +interface Observer { + start?(subscription: Subscription): any; + next?(nextThing: T): any; + error?(error: Error): any; + complete?(): any; + unsubscribe?(subscription: Subscription): any; +} +type Source = () => any; +interface Subscribable { + subscribe(observer: Observer): Subscription; +} +type ObservableFromValue = RelayObservable | Promise | T; +declare class RelayObservable implements Subscribable { + _source: Source; + + constructor(source: Source); + + /** + * When an unhandled error is detected, it is reported to the host environment + * (the ESObservable spec refers to this method as "HostReportErrors()"). + * + * The default implementation in development builds re-throws errors in a + * separate frame, and from production builds does nothing (swallowing + * uncaught errors). + * + * Called during application initialization, this method allows + * application-specific handling of uncaught errors. Allowing, for example, + * integration with error logging or developer tools. + */ + static onUnhandledError(callback: (error: Error) => any): void; + + /** + * Accepts various kinds of data sources, and always returns a RelayObservable + * useful for accepting the result of a user-provided FetchFunction. + */ + static from(obj: ObservableFromValue): RelayObservable; + + /** + * Creates a RelayObservable, given a function which expects a legacy + * Relay Observer as the last argument and which returns a Disposable. + * + * To support migration to Observable, the function may ignore the + * legacy Relay observer and directly return an Observable instead. + */ + static fromLegacy( + callback: (legacyObserver: LegacyObserver) => Disposable | RelayObservable + ): RelayObservable; + + /** + * Returns a new Observable which returns the same values as this one, but + * modified so that the provided Observer is called to perform a side-effects + * for all events emitted by the source. + * + * Any errors that are thrown in the side-effect Observer are unhandled, and + * do not affect the source Observable or its Observer. + * + * This is useful for when debugging your Observables or performing other + * side-effects such as logging or performance monitoring. + */ + do(observer: Observer): RelayObservable; + + /** + * Returns a new Observable which returns the same values as this one, but + * modified so that the finally callback is performed after completion, + * whether normal or due to error or unsubscription. + * + * This is useful for cleanup such as resource finalization. + */ + finally(fn: () => any): RelayObservable; + + /** + * Returns a new Observable which is identical to this one, unless this + * Observable completes before yielding any values, in which case the new + * Observable will yield the values from the alternate Observable. + * + * If this Observable does yield values, the alternate is never subscribed to. + * + * This is useful for scenarios where values may come from multiple sources + * which should be tried in order, i.e. from a cache before a network. + */ + ifEmpty(alternate: RelayObservable): RelayObservable; + + /** + * Observable's primary API: returns an unsubscribable Subscription to the + * source of this Observable. + */ + subscribe(observer: Observer): Subscription; + + /** + * Supports subscription of a legacy Relay Observer, returning a Disposable. + */ + subscribeLegacy(legacyObserver: LegacyObserver): Disposable; + + /** + * Returns a new Observerable where each value has been transformed by + * the mapping function. + */ + map(fn: (thing: T) => U): RelayObservable; + + /** + * Returns a new Observable where each value is replaced with a new Observable + * by the mapping function, the results of which returned as a single + * concattenated Observable. + */ + concatMap(fn: (thing: T) => ObservableFromValue): RelayObservable; + + /** + * Returns a new Observable which first mirrors this Observable, then when it + * completes, waits for `pollInterval` milliseconds before re-subscribing to + * this Observable again, looping in this manner until unsubscribed. + * + * The returned Observable never completes. + */ + poll(pollInterval: number): RelayObservable; + + /** + * Returns a Promise which resolves when this Observable yields a first value + * or when it completes with no value. + */ + toPromise(): Promise; +} + +export type Observable = RelayObservable; + +// ~~~~~~~~~~~~~~~~~~~~~ +// commitLocalUpdate +// ~~~~~~~~~~~~~~~~~~~~~ +// exposed through RelayModern, not Runtime directly +type commitLocalUpdate = (environment: Environment, updater: StoreUpdater) => void; + +// ~~~~~~~~~~~~~~~~~~~~~ +// commitRelayModernMutation +// ~~~~~~~~~~~~~~~~~~~~~ +// exposed through RelayModern, not Runtime directly +interface MutationConfig { + configs?: RelayMutationConfig[]; + mutation: GraphQLTaggedNode; + variables: Variables; + uploadables?: UploadableMap; + onCompleted?(response: T, errors: PayloadError[] | null | undefined): void; + onError?(error?: Error): void; + optimisticUpdater?: SelectorStoreUpdater; + optimisticResponse?: object; + updater?: SelectorStoreUpdater; +} +declare function commitRelayModernMutation(environment: Environment, config: MutationConfig): Disposable; + +// ~~~~~~~~~~~~~~~~~~~~~ +// applyRelayModernOptimisticMutation +// ~~~~~~~~~~~~~~~~~~~~~ +// exposed through RelayModern, not Runtime directly +interface OptimisticMutationConfig { + configs?: RelayMutationConfig[]; + mutation: GraphQLTaggedNode; + variables: Variables; + optimisticUpdater?: SelectorStoreUpdater; + optimisticResponse?: object; +} + +// ~~~~~~~~~~~~~~~~~~~~~ +// fetchRelayModernQuery +// ~~~~~~~~~~~~~~~~~~~~~ +// exposed through RelayModern, not Runtime directly +/** + * A helper function to fetch the results of a query. Note that results for + * fragment spreads are masked: fields must be explicitly listed in the query in + * order to be accessible in the result object. + * + * NOTE: This module is primarily intended for integrating with classic APIs. + * Most product code should use a Renderer or Container. + * + * TODO(t16875667): The return type should be `Promise`, but + * that's not really helpful as `SelectorData` is essentially just `mixed`. We + * can probably leverage generated flow types here to return the real expected + * shape. + */ +declare function fetchRelayModernQuery( + environment: any, // FIXME - $FlowFixMe in facebook source code + taggedNode: GraphQLTaggedNode, + variables: Variables, + cacheConfig?: CacheConfig +): Promise; // FIXME - $FlowFixMe in facebook source code + +// ~~~~~~~~~~~~~~~~~~~~~ +// requestRelaySubscription +// ~~~~~~~~~~~~~~~~~~~~~ +// exposed through RelayModern, not Runtime directly +interface GraphQLSubscriptionConfig { + configs?: RelayMutationConfig[]; + subscription: GraphQLTaggedNode; + variables: Variables; + onCompleted?(): void; + onError?(error: Error): void; + onNext?(response: object | null | undefined): void; + updater?(store: RecordSourceSelectorProxy): void; +} +declare function requestRelaySubscription(environment: Environment, config: GraphQLSubscriptionConfig): Disposable;