-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.ts
More file actions
150 lines (134 loc) · 4.32 KB
/
cache.ts
File metadata and controls
150 lines (134 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import { DocumentNode } from 'graphql';
import { getFragmentQueryDocument } from 'apollo-utilities';
import { DataProxy, Cache } from './types';
import { justTypenameQuery, queryFromPojo, fragmentFromPojo } from './utils';
export type Transaction<T> = (c: ApolloCache<T>) => void;
export abstract class ApolloCache<TSerialized> implements DataProxy {
// required to implement
// core API
public abstract read<T, TVariables = any>(
query: Cache.ReadOptions<TVariables>,
): T | null;
public abstract write<TResult = any, TVariables = any>(
write: Cache.WriteOptions<TResult, TVariables>,
): void;
public abstract diff<T>(query: Cache.DiffOptions): Cache.DiffResult<T>;
public abstract watch(watch: Cache.WatchOptions): () => void;
public abstract evict<TVariables = any>(
query: Cache.EvictOptions<TVariables>,
): Cache.EvictionResult;
public abstract reset(): Promise<void>;
// intializer / offline / ssr API
/**
* Replaces existing state in the cache (if any) with the values expressed by
* `serializedState`.
*
* Called when hydrating a cache (server side rendering, or offline storage),
* and also (potentially) during hot reloads.
*/
public abstract restore(
serializedState: TSerialized,
): ApolloCache<TSerialized>;
/**
* Exposes the cache's complete state, in a serializable format for later restoration.
*/
public abstract extract(optimistic?: boolean): TSerialized;
// optimistic API
public abstract removeOptimistic(id: string): void;
// transactional API
public abstract performTransaction(
transaction: Transaction<TSerialized>,
): void;
public abstract recordOptimisticTransaction(
transaction: Transaction<TSerialized>,
id: string,
): void;
// optional API
public transformDocument(document: DocumentNode): DocumentNode {
return document;
}
// experimental
public transformForLink(document: DocumentNode): DocumentNode {
return document;
}
// DataProxy API
/**
*
* @param options
* @param optimistic
*/
public readQuery<QueryType, TVariables = any>(
options: DataProxy.Query<TVariables>,
optimistic: boolean = false,
): QueryType | null {
return this.read({
query: options.query,
variables: options.variables,
optimistic,
});
}
public readFragment<FragmentType, TVariables = any>(
options: DataProxy.Fragment<TVariables>,
optimistic: boolean = false,
): FragmentType | null {
return this.read({
query: getFragmentQueryDocument(options.fragment, options.fragmentName),
variables: options.variables,
rootId: options.id,
optimistic,
});
}
public writeQuery<TData = any, TVariables = any>(
options: Cache.WriteQueryOptions<TData, TVariables>,
): void {
this.write({
dataId: 'ROOT_QUERY',
result: options.data,
query: options.query,
variables: options.variables,
});
}
public writeFragment<TData = any, TVariables = any>(
options: Cache.WriteFragmentOptions<TData, TVariables>,
): void {
this.write({
dataId: options.id,
result: options.data,
variables: options.variables,
query: getFragmentQueryDocument(options.fragment, options.fragmentName),
});
}
public writeData<TData = any>({
id,
data,
}: Cache.WriteDataOptions<TData>): void {
if (typeof id !== 'undefined') {
let typenameResult = null;
// Since we can't use fragments without having a typename in the store,
// we need to make sure we have one.
// To avoid overwriting an existing typename, we need to read it out first
// and generate a fake one if none exists.
try {
typenameResult = this.read<any>({
rootId: id,
optimistic: false,
query: justTypenameQuery,
});
} catch (e) {
// Do nothing, since an error just means no typename exists
}
// tslint:disable-next-line
const __typename =
(typenameResult && typenameResult.__typename) || '__ClientData';
// Add a type here to satisfy the inmemory cache
const dataToWrite = Object.assign({ __typename }, data);
this.writeFragment({
id,
fragment: fragmentFromPojo(dataToWrite, __typename),
data: dataToWrite,
});
} else {
this.writeQuery({ query: queryFromPojo(data), data });
}
}
}