@@ -3,9 +3,13 @@ import { definePlugin } from '@zenstackhq/orm';
33import stableStringify from 'json-stable-stringify' ;
44import murmurhash from 'murmurhash' ;
55import { cacheEnvelopeSchema } from './schemas' ;
6- import type { CacheEnvelope , CacheInvalidationOptions , CachePluginOptions } from './types' ;
6+ import type { CacheEnvelope , CacheInvalidationOptions , CachePluginOptions , CacheStatus } from './types' ;
7+ import { entryIsFresh , entryIsStale } from './utils'
78
89export function defineCachePlugin ( pluginOptions : CachePluginOptions ) {
10+ let status : CacheStatus | null = null ;
11+ let revalidation : Promise < void > | null = null ;
12+
913 return definePlugin ( {
1014 id : 'cache' ,
1115 name : 'Cache' ,
@@ -24,6 +28,23 @@ export function defineCachePlugin(pluginOptions: CachePluginOptions) {
2428 invalidateAll ( ) {
2529 return pluginOptions . provider . invalidateAll ( ) ;
2630 } ,
31+
32+ /**
33+ * Returns the status of the last result returned, or `null`
34+ * if a result has yet to be returned.
35+ */
36+ get status ( ) {
37+ return status ;
38+ } ,
39+
40+ /**
41+ * Returns a `Promise` that fulfills when the last stale result
42+ * returned has been revalidated, or `null` if a stale result has
43+ * yet to be returned.
44+ */
45+ get revalidation ( ) {
46+ return revalidation ;
47+ }
2748 } ,
2849 } ,
2950
@@ -45,7 +66,26 @@ export function defineCachePlugin(pluginOptions: CachePluginOptions) {
4566 const queryResultEntry = await cache . getQueryResult ( key ) ;
4667
4768 if ( queryResultEntry ) {
48- return queryResultEntry . result ;
69+ if ( entryIsFresh ( queryResultEntry ) ) {
70+ status = 'hit' ;
71+ return queryResultEntry . result ;
72+ } else if ( entryIsStale ( queryResultEntry ) ) {
73+ revalidation = proceed ( args ) . then ( async ( result ) => {
74+ try {
75+ await cache . setQueryResult ( key , {
76+ createdAt : Date . now ( ) ,
77+ options,
78+ result,
79+ } )
80+ }
81+ catch ( err ) {
82+ console . error ( `Failed to cache query result: ${ err } ` )
83+ }
84+ } ) ;
85+
86+ status = 'stale' ;
87+ return queryResultEntry . result ;
88+ }
4989 }
5090
5191 const result = await proceed ( args ) ;
@@ -56,6 +96,7 @@ export function defineCachePlugin(pluginOptions: CachePluginOptions) {
5696 result,
5797 } ) . catch ( ( err ) => console . error ( `Failed to cache query result: ${ err } ` ) ) ;
5898
99+ status = 'miss' ;
59100 return result ;
60101 }
61102
0 commit comments