Skip to content

Commit c6a5683

Browse files
committed
think interactions between data classes to implement caching should be good. now to test
1 parent b2cc7c1 commit c6a5683

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

packages/data-connect/src/core/Cache.ts

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,36 @@
1818

1919
import { QueryResult } from '../api';
2020

21-
/** Value is any FDC scalar value. */
21+
/** Value is any FDC scalar value. */ // TODO: make this more accurate
2222
type Value = string | number | boolean | null | undefined | object | Value[];
2323

24+
/**
25+
* Defines the shape of query result data - "movies", "actor", etc.
26+
*/
2427
export interface QueryResultData {
2528
[key: string]: Value;
2629
__typename?: string;
2730
__id?: string;
2831
}
2932

3033
/**
31-
* Interface representing the result tree for an operation.
32-
* @public
33-
*/
34-
export interface StubResultTree {
35-
[key: string]: StubDataObject | StubDataObjectList;
36-
}
37-
38-
/**
39-
* Creates a unique cache key for a given query and its variables.
34+
* Creates a unique StrubResultTree cache key for a given query and its variables.
4035
* @param queryName The name of the query.
4136
* @param vars The variables used in the query.
4237
* @returns A unique cache key string.
4338
* @public
4439
*/
45-
export function makeStubCacheKey(queryName: string, vars: unknown): string {
40+
export function makeResultTreeCacheKey(
41+
queryName: string,
42+
vars: unknown
43+
): string {
4644
return queryName + '|' + JSON.stringify(vars);
4745
}
4846

4947
/**
50-
* Creates a unique cache key for a given query and its variables.
51-
* @param queryName The name of the query.
52-
* @param vars The variables used in the query.
48+
* Creates a unique BackingDataObject cache key for a given entity.
49+
* @param typename The typename of the entity being cached.
50+
* @param id The unique id / primary key of this entity.
5351
* @returns A unique cache key string.
5452
* @public
5553
*/
@@ -63,8 +61,6 @@ export function makeBdoCacheKey(typename: string, id: unknown): string {
6361
* @public
6462
*/
6563
export interface StubDataObject {
66-
/** A stable unique key identifying the entity across types. */
67-
readonly typedKey: string;
6864
[key: string]: Value | StubDataObject;
6965
}
7066

@@ -84,7 +80,7 @@ export class BackingDataObject {
8480
* Stable unique key identifying the entity across types.
8581
* TypeName + CompositePrimaryKey.
8682
*/
87-
private typedKey: string;
83+
readonly typedKey: string;
8884

8985
/** Represents values received from the server. */
9086
private serverValues: Map<string, Value>;
@@ -147,7 +143,7 @@ export class Cache {
147143
* A map of ([query + variables] --> stubs returned from that query).
148144
* @public
149145
*/
150-
stubTreeCache = new Map<string, StubDataObject>();
146+
resultTreeCache = new Map<string, StubDataObject[]>();
151147

152148
/**
153149
* A map of ([entity typename + id] --> BackingDataObject for that entity).
@@ -163,53 +159,79 @@ export class Cache {
163159
updateCache<Data extends QueryResultData | QueryResultData[], Variables>(
164160
queryResult: QueryResult<Data, Variables>
165161
): void {
166-
const queryKey = makeStubCacheKey(
167-
queryResult.ref.name,
168-
queryResult.ref.variables
169-
);
170-
162+
const stubDataObjects: StubDataObject[] = []; // ! if this is going to be mapped to the query name | variables, consider the fact that not all queries return a list of objects...
171163
// key = "movies" or "actor", etc.
172164
// eslint-disable-next-line guard-for-in
173165
for (const key in queryResult.data) {
174166
const queryData = queryResult.data[key];
175167
if (Array.isArray(queryData)) {
176-
queryData.forEach(qd => this.updateBdoCache(qd));
168+
queryData.forEach(qd => {
169+
const sdo: StubDataObject = {
170+
...Object.entries(qd)
171+
// todo: add in non-cacheable fields
172+
};
173+
stubDataObjects.push(sdo);
174+
const bdo: BackingDataObject = this.updateBdoCache(qd, sdo);
175+
});
177176
} else {
178-
this.updateBdoCache(queryData as QueryResultData); // ! i don't think i should need a type assertion here, yet TS complains without it...
177+
const sdo: StubDataObject = {
178+
...Object.entries(queryData)
179+
// todo: add in non-cacheable fields
180+
};
181+
stubDataObjects.push(sdo);
182+
const bdo = this.updateBdoCache(queryData as QueryResultData, sdo); // ! i don't think i should need a type assertion here, yet TS complains without it...
179183
}
180184
}
181-
182-
// todo: add StubDataObjects to StrubResultTree
185+
this.updateResultTreeCache(
186+
queryResult.ref.name,
187+
queryResult.ref.variables,
188+
stubDataObjects
189+
);
183190
}
184191

185192
/**
186193
* Update the BackingDataObject cache, either adding a new BDO or updating an existing BDO
187194
* @param data A single entity from the database.
195+
* @returns the BackingDataObject created/upated.
188196
*/
189-
private updateBdoCache<Data extends QueryResultData>(data: Data): void {
190-
const typedKey = makeBdoCacheKey(data['__typename'], data['__id']);
191-
const existingBdo = this.bdoCache.get(typedKey);
192-
const stubDataObject: StubDataObject = {
193-
typedKey
194-
// todo: add in non-cacheable fields
195-
};
196-
197-
if (existingBdo) {
197+
private updateBdoCache<Data extends QueryResultData>(
198+
data: Data,
199+
stubDataObject: StubDataObject
200+
): BackingDataObject {
201+
const bdoCacheKey = makeBdoCacheKey(data['__typename'], data['__id']);
202+
let backingDataObject = this.bdoCache.get(bdoCacheKey);
203+
204+
if (backingDataObject) {
198205
// BDO already exists, so update its values from the new data.
199206
for (const [key, value] of Object.entries(data)) {
200207
// key = "id" or "title", etc.
201-
existingBdo.updateFromServer(value, key);
208+
backingDataObject.updateFromServer(value, key);
202209
}
203-
existingBdo.listeners.add(stubDataObject);
210+
backingDataObject.listeners.add(stubDataObject);
204211
} else {
205212
// BDO does not exist, so create a new one.
206213
const serverValues = new Map<string, Value>(Object.entries(data));
207-
const backingDataObject = new BackingDataObject(
208-
typedKey,
214+
backingDataObject = new BackingDataObject(
215+
bdoCacheKey,
209216
[stubDataObject],
210217
serverValues
211218
);
212-
this.bdoCache.set(typedKey, backingDataObject);
219+
this.bdoCache.set(bdoCacheKey, backingDataObject);
213220
}
221+
return backingDataObject;
222+
}
223+
224+
/**
225+
* Update the StubResultTree cache, either adding a new StubResultTree or updating an existing
226+
* StubResultTree
227+
* @param data A single entity from the database.
228+
*/
229+
private updateResultTreeCache<Variables>(
230+
queryName: string,
231+
variables: Variables,
232+
stubDataObjects: StubDataObject[]
233+
): void {
234+
const resultTreeCacheKey = makeResultTreeCacheKey(queryName, variables);
235+
this.resultTreeCache.set(resultTreeCacheKey, stubDataObjects);
214236
}
215237
}

0 commit comments

Comments
 (0)