@@ -16,6 +16,7 @@ import type {
1616 EdgeConfigItems ,
1717 EdgeConfigValue ,
1818 EmbeddedEdgeConfig ,
19+ EdgeConfigFunctionsOptions ,
1920} from './types' ;
2021import { fetchWithCachedResponse } from './utils/fetch-with-cached-response' ;
2122import { trace } from './utils/tracing' ;
@@ -125,7 +126,9 @@ function createGetInMemoryEdgeConfig(
125126 connection : Connection ,
126127 headers : Record < string , string > ,
127128 fetchCache : EdgeConfigClientOptions [ 'cache' ] ,
128- ) : ( ) => Promise < EmbeddedEdgeConfig | null > {
129+ ) : (
130+ localOptions ?: EdgeConfigFunctionsOptions ,
131+ ) => Promise < EmbeddedEdgeConfig | null > {
129132 // Functions as cache to keep track of the Edge Config.
130133 let embeddedEdgeConfigPromise : Promise < EmbeddedEdgeConfig | null > | null =
131134 null ;
@@ -137,8 +140,9 @@ function createGetInMemoryEdgeConfig(
137140 let latestRequest : Promise < EmbeddedEdgeConfig | null > | null = null ;
138141
139142 return trace (
140- ( ) => {
141- if ( ! shouldUseDevelopmentCache ) return Promise . resolve ( null ) ;
143+ ( localOptions ) => {
144+ if ( localOptions ?. consistentRead || ! shouldUseDevelopmentCache )
145+ return Promise . resolve ( null ) ;
142146
143147 if ( ! latestRequest ) {
144148 latestRequest = fetchWithCachedResponse (
@@ -196,11 +200,23 @@ function createGetInMemoryEdgeConfig(
196200}
197201
198202/**
199- *
203+ * Uses `MAX_SAFE_INTEGER` as minimum updated at timestamp to force
204+ * a request to the origin.
205+ */
206+ function addConsistentReadHeader ( headers : Headers ) : void {
207+ headers . set ( 'x-edge-config-min-updated-at' , `${ Number . MAX_SAFE_INTEGER } ` ) ;
208+ }
209+
210+ /**
211+ * Reads the Edge Config from a local provider, if available,
212+ * to avoid Network requests.
200213 */
201214async function getLocalEdgeConfig (
202215 connection : Connection ,
216+ options ?: EdgeConfigFunctionsOptions ,
203217) : Promise < EmbeddedEdgeConfig | null > {
218+ if ( options ?. consistentRead ) return null ;
219+
204220 const edgeConfig =
205221 ( await getPrivateEdgeConfig ( connection ) ) ||
206222 ( await getFileSystemEdgeConfig ( connection ) ) ;
@@ -329,10 +345,11 @@ export const createClient = trace(
329345 get : trace (
330346 async function get < T = EdgeConfigValue > (
331347 key : string ,
348+ localOptions ?: EdgeConfigFunctionsOptions ,
332349 ) : Promise < T | undefined > {
333350 const localEdgeConfig =
334- ( await getInMemoryEdgeConfig ( ) ) ||
335- ( await getLocalEdgeConfig ( connection ) ) ;
351+ ( await getInMemoryEdgeConfig ( localOptions ) ) ||
352+ ( await getLocalEdgeConfig ( connection , localOptions ) ) ;
336353
337354 assertIsKey ( key ) ;
338355 if ( isEmptyKey ( key ) ) return undefined ;
@@ -345,10 +362,14 @@ export const createClient = trace(
345362 return Promise . resolve ( localEdgeConfig . items [ key ] as T ) ;
346363 }
347364
365+ const localHeaders = new Headers ( headers ) ;
366+ if ( localOptions ?. consistentRead )
367+ addConsistentReadHeader ( localHeaders ) ;
368+
348369 return fetchWithCachedResponse (
349370 `${ baseUrl } /item/${ key } ?version=${ version } ` ,
350371 {
351- headers : new Headers ( headers ) ,
372+ headers : localHeaders ,
352373 cache : fetchCache ,
353374 } ,
354375 ) . then < T | undefined , undefined > ( async ( res ) => {
@@ -372,10 +393,13 @@ export const createClient = trace(
372393 { name : 'get' , isVerboseTrace : false , attributes : { edgeConfigId } } ,
373394 ) ,
374395 has : trace (
375- async function has ( key ) : Promise < boolean > {
396+ async function has (
397+ key ,
398+ localOptions ?: EdgeConfigFunctionsOptions ,
399+ ) : Promise < boolean > {
376400 const localEdgeConfig =
377- ( await getInMemoryEdgeConfig ( ) ) ||
378- ( await getLocalEdgeConfig ( connection ) ) ;
401+ ( await getInMemoryEdgeConfig ( localOptions ) ) ||
402+ ( await getLocalEdgeConfig ( connection , localOptions ) ) ;
379403
380404 assertIsKey ( key ) ;
381405 if ( isEmptyKey ( key ) ) return false ;
@@ -384,10 +408,14 @@ export const createClient = trace(
384408 return Promise . resolve ( hasOwnProperty ( localEdgeConfig . items , key ) ) ;
385409 }
386410
411+ const localHeaders = new Headers ( headers ) ;
412+ if ( localOptions ?. consistentRead )
413+ addConsistentReadHeader ( localHeaders ) ;
414+
387415 // this is a HEAD request anyhow, no need for fetchWithCachedResponse
388416 return fetch ( `${ baseUrl } /item/${ key } ?version=${ version } ` , {
389417 method : 'HEAD' ,
390- headers : new Headers ( headers ) ,
418+ headers : localHeaders ,
391419 cache : fetchCache ,
392420 } ) . then ( ( res ) => {
393421 if ( res . status === 401 ) throw new Error ( ERRORS . UNAUTHORIZED ) ;
@@ -408,10 +436,11 @@ export const createClient = trace(
408436 getAll : trace (
409437 async function getAll < T = EdgeConfigItems > (
410438 keys ?: ( keyof T ) [ ] ,
439+ localOptions ?: EdgeConfigFunctionsOptions ,
411440 ) : Promise < T > {
412441 const localEdgeConfig =
413- ( await getInMemoryEdgeConfig ( ) ) ||
414- ( await getLocalEdgeConfig ( connection ) ) ;
442+ ( await getInMemoryEdgeConfig ( localOptions ) ) ||
443+ ( await getLocalEdgeConfig ( connection , localOptions ) ) ;
415444
416445 if ( localEdgeConfig ) {
417446 if ( keys === undefined ) {
@@ -436,12 +465,16 @@ export const createClient = trace(
436465 // so skip the request and return an empty object
437466 if ( search === '' ) return Promise . resolve ( { } as T ) ;
438467
468+ const localHeaders = new Headers ( headers ) ;
469+ if ( localOptions ?. consistentRead )
470+ addConsistentReadHeader ( localHeaders ) ;
471+
439472 return fetchWithCachedResponse (
440473 `${ baseUrl } /items?version=${ version } ${
441474 search === null ? '' : `&${ search } `
442475 } `,
443476 {
444- headers : new Headers ( headers ) ,
477+ headers : localHeaders ,
445478 cache : fetchCache ,
446479 } ,
447480 ) . then < T > ( async ( res ) => {
@@ -461,19 +494,25 @@ export const createClient = trace(
461494 { name : 'getAll' , isVerboseTrace : false , attributes : { edgeConfigId } } ,
462495 ) ,
463496 digest : trace (
464- async function digest ( ) : Promise < string > {
497+ async function digest (
498+ localOptions ?: EdgeConfigFunctionsOptions ,
499+ ) : Promise < string > {
465500 const localEdgeConfig =
466- ( await getInMemoryEdgeConfig ( ) ) ||
467- ( await getLocalEdgeConfig ( connection ) ) ;
501+ ( await getInMemoryEdgeConfig ( localOptions ) ) ||
502+ ( await getLocalEdgeConfig ( connection , localOptions ) ) ;
468503
469504 if ( localEdgeConfig ) {
470505 return Promise . resolve ( localEdgeConfig . digest ) ;
471506 }
472507
508+ const localHeaders = new Headers ( headers ) ;
509+ if ( localOptions ?. consistentRead )
510+ addConsistentReadHeader ( localHeaders ) ;
511+
473512 return fetchWithCachedResponse (
474513 `${ baseUrl } /digest?version=${ version } ` ,
475514 {
476- headers : new Headers ( headers ) ,
515+ headers : localHeaders ,
477516 cache : fetchCache ,
478517 } ,
479518 ) . then ( async ( res ) => {
0 commit comments