1818
1919import { QueryResult } from '../api' ;
2020
21- /** Value is any FDC scalar value. */
21+ /** Internal utility type. Value is any FDC scalar value. */
2222// TODO: make this more accurate... what type should we use to represent any FDC scalar value?
2323type Value = string | number | boolean | null | undefined | object | Value [ ] ;
2424
2525/**
26- * Defines the shape of query result data that represents a single entity.
26+ * Internal utility type. Defines the shape of query result data that represents a single entity.
2727 * It must have __typename and __id for normalization.
2828 */
29- // TODO: this is just a StubDataObject isn't it...?
30- export interface QueryResultData {
29+ interface QueryResultData {
3130 [ key : string ] : Value ;
3231 __typename ?: string ;
3332 __id ?: string ;
3433}
3534
3635/**
37- * A type guard to check if a value is a QueryResultData object .
36+ * A type guard to check if a value is normalizeable .
3837 * @param value The value to check.
39- * @returns True if the value is a QueryResultData object .
38+ * @returns True if the value is normalizeable (it has the fields __typename and __id) .
4039 */
41- function isCacheableQueryResultData ( value : unknown ) : value is QueryResultData {
40+ function isNormalizeable ( value : unknown ) : value is QueryResultData {
4241 return (
42+ value !== undefined &&
4343 value !== null &&
4444 typeof value === 'object' &&
4545 ! Array . isArray ( value ) &&
@@ -49,27 +49,16 @@ function isCacheableQueryResultData(value: unknown): value is QueryResultData {
4949}
5050
5151/**
52- * Interface for a stub result tree, with fields which are stub data objects
52+ * Interface for a stub result tree, with fields which are stub data objects.
53+ * @public
5354 */
54- // TODO: need a better way to represent that a query may return a single entity or a list of entities
55- // ! ex: queryResult.data =
56- // ! {
57- // ! movies: [ <-- list
58- // ! {...movie1...},
59- // ! {...movie2...},
60- // ! {...movie3...}
61- // ! ],
62- // ! currentUser: { <-- singleton
63- // ! ...user...
64- // ! }
65- // ! }
66- interface StubResultTree {
55+ export interface StubResultTree {
6756 [ key : string ] : StubDataObject | StubDataObjectList ;
6857}
6958
7059/**
71- * Interface for a stub data object, which acts as a "live" view into cached data.
72- * Generated Data implements this interface.
60+ * Interface for a stub data object, which acts as a snapshot view of cached data.
61+ * Selection sets in generated data types extend this interface.
7362 * @public
7463 */
7564export interface StubDataObject {
@@ -84,7 +73,7 @@ export interface StubDataObject {
8473class StubDataObjectList extends Array < StubDataObject > { }
8574
8675/**
87- * A class used to hold the single source of truth for an entity's values across all queries.
76+ * A class used to hold an entity's normalized cached values across all queries.
8877 * @public
8978 */
9079export class BackingDataObject {
@@ -107,14 +96,17 @@ export class BackingDataObject {
10796 }
10897
10998 /**
110- * Updates the value for a named property from the server and notifies all listeners.
99+ * Updates the value for a named property from the server and notifies all listeners which depend
100+ * on that value.
111101 * @param value The new value from the server.
112102 * @param key The key of the property to update.
113103 */
114104 updateFromServer ( value : Value , key : string ) : void {
115105 this . serverValues . set ( key , value ) ;
116106 for ( const listener of this . listeners ) {
117- listener [ key ] = value ;
107+ if ( key in listener ) {
108+ listener [ key ] = value ;
109+ }
118110 }
119111 }
120112
@@ -138,7 +130,9 @@ export class BackingDataObject {
138130 updateLocal ( value : Value , key : string ) : void {
139131 this . localValues . set ( key , value ) ;
140132 for ( const listener of this . listeners ) {
141- listener [ key ] = value ;
133+ if ( key in listener ) {
134+ listener [ key ] = value ;
135+ }
142136 }
143137 }
144138}
@@ -148,8 +142,8 @@ export class BackingDataObject {
148142 * @public
149143 */
150144export class Cache {
151- /** A map of [query + variables] --> StubDataObjects returned from that query. */
152- resultTreeCache = new Map < string , StubResultTree > ( ) ;
145+ /** A map of [query + variables] --> StubResultTree returned from that query. */
146+ srtCache = new Map < string , StubResultTree > ( ) ;
153147
154148 /** A map of [entity typename + id] --> BackingDataObject for that entity. */
155149 bdoCache = new Map < string , BackingDataObject > ( ) ;
@@ -160,7 +154,7 @@ export class Cache {
160154 * @param vars The variables used in the query.
161155 * @returns A unique cache key string.
162156 */
163- static makeResultTreeCacheKey ( queryName : string , vars : unknown ) : string {
157+ static srtCacheKey ( queryName : string , vars : unknown ) : string {
164158 return queryName + '|' + JSON . stringify ( vars ) ;
165159 }
166160
@@ -170,7 +164,7 @@ export class Cache {
170164 * @param id The unique id / primary key of this entity.
171165 * @returns A unique cache key string.
172166 */
173- static makeBdoCacheKey ( typename : string , id : unknown ) : string {
167+ static bdoCacheKey ( typename : string , id : unknown ) : string {
174168 return typename + '|' + JSON . stringify ( id ) ;
175169 }
176170
@@ -181,12 +175,12 @@ export class Cache {
181175 updateCache < Data extends object , Variables > (
182176 queryResult : QueryResult < Data , Variables >
183177 ) : void {
184- const resultTreeCacheKey = Cache . makeResultTreeCacheKey (
178+ const resultTreeCacheKey = Cache . srtCacheKey (
185179 queryResult . ref . name ,
186180 queryResult . ref . variables
187181 ) ;
188182 const stubResultTree = this . normalize ( queryResult . data ) as StubResultTree ;
189- this . resultTreeCache . set ( resultTreeCacheKey , stubResultTree ) ;
183+ this . srtCache . set ( resultTreeCacheKey , stubResultTree ) ;
190184 }
191185
192186 /**
@@ -200,9 +194,9 @@ export class Cache {
200194 return data . map ( item => this . normalize ( item ) ) ;
201195 }
202196
203- if ( isCacheableQueryResultData ( data ) ) {
197+ if ( isNormalizeable ( data ) ) {
204198 const stub : StubDataObject = { } ;
205- const bdoCacheKey = Cache . makeBdoCacheKey ( data . __typename , data . __id ) ;
199+ const bdoCacheKey = Cache . bdoCacheKey ( data . __typename , data . __id ) ;
206200 const existingBdo = this . bdoCache . get ( bdoCacheKey ) ;
207201
208202 // data is a single "movie" or "actor"
0 commit comments