diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index ff7e0764f7c..b3756756a03 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -66,7 +66,7 @@ export abstract class ApolloCache implements DataProxy { return document; } - public identify(object: StoreObject): string | undefined { + public identify(object: StoreObject | Reference): string | undefined { return; } diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 9bee494187f..fd3166df451 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -4,7 +4,7 @@ import { InMemoryCache } from '../inMemoryCache'; import { DocumentNode } from 'graphql'; import { StoreObject } from '../types'; import { ApolloCache } from '../../core/cache'; -import { Reference } from '../../../utilities/graphql/storeUtils'; +import { Reference, makeReference, isReference } from '../../../utilities/graphql/storeUtils'; import { MissingFieldError } from '../..'; describe('EntityStore', () => { @@ -1417,6 +1417,39 @@ describe('EntityStore', () => { }); }); + it("supports cache.identify(reference)", () => { + const cache = new InMemoryCache({ + typePolicies: { + Task: { + keyFields: ["uuid"], + }, + }, + }); + + expect(cache.identify(makeReference("oyez"))).toBe("oyez"); + + const todoRef = cache.writeFragment({ + fragment: gql`fragment TodoId on Todo { id }`, + data: { + __typename: "Todo", + id: 123, + }, + }); + expect(isReference(todoRef)).toBe(true); + expect(cache.identify(todoRef!)).toBe("Todo:123"); + + const taskRef = cache.writeFragment({ + fragment: gql`fragment TaskId on Task { id }`, + data: { + __typename: "Task", + uuid: "eb8cffcc-7a9e-4d8b-a517-7d987bf42138", + }, + }); + expect(isReference(taskRef)).toBe(true); + expect(cache.identify(taskRef!)).toBe( + 'Task:{"uuid":"eb8cffcc-7a9e-4d8b-a517-7d987bf42138"}'); + }); + it("supports cache.identify(object)", () => { const queryWithAliases: DocumentNode = gql` query { diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index e586a9736f2..a7812a945c1 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -7,7 +7,7 @@ import { dep, wrap } from 'optimism'; import { ApolloCache, Transaction } from '../core/cache'; import { Cache } from '../core/types/Cache'; import { addTypenameToDocument } from '../../utilities/graphql/transform'; -import { StoreObject, Reference } from '../../utilities/graphql/storeUtils'; +import { StoreObject, Reference, isReference } from '../../utilities/graphql/storeUtils'; import { ApolloReducerConfig, NormalizedCacheObject, @@ -206,8 +206,10 @@ export class InMemoryCache extends ApolloCache { // the object must contain a __typename and any primary key fields required // to identify entities of that type. If you pass a query result object, be // sure that none of the primary key fields have been renamed by aliasing. - public identify(object: StoreObject): string | undefined { - return this.policies.identify(object)[0]; + // If you pass a Reference object, its __ref ID string will be returned. + public identify(object: StoreObject | Reference): string | undefined { + return isReference(object) ? object.__ref : + this.policies.identify(object)[0]; } public evict(options: Cache.EvictOptions): boolean {