@@ -16,6 +16,16 @@ interface NamedStoreOptions extends BaseStoreOptions {
1616
1717type StoreOptions = DeployStoreOptions | NamedStoreOptions
1818
19+ interface GetWithMetadataOptions {
20+ etag ?: string
21+ }
22+
23+ interface GetWithMetadataResult {
24+ etag ?: string
25+ fresh : boolean
26+ metadata : Metadata
27+ }
28+
1929interface SetOptions {
2030 /**
2131 * Arbitrary metadata object to associate with an entry. Must be seralizable
@@ -24,7 +34,6 @@ interface SetOptions {
2434 metadata ?: Metadata
2535}
2636
27- type BlobWithMetadata = { etag ?: string } & { metadata : Metadata }
2837type BlobResponseType = 'arrayBuffer' | 'blob' | 'json' | 'stream' | 'text'
2938
3039export class Store {
@@ -88,34 +97,53 @@ export class Store {
8897 throw new Error ( `Invalid 'type' property: ${ type } . Expected: arrayBuffer, blob, json, stream, or text.` )
8998 }
9099
91- async getWithMetadata ( key : string ) : Promise < { data : string } & BlobWithMetadata >
100+ async getWithMetadata (
101+ key : string ,
102+ options ?: GetWithMetadataOptions ,
103+ ) : Promise < { data : string } & GetWithMetadataResult >
92104
93105 async getWithMetadata (
94106 key : string ,
95- { type } : { type : 'arrayBuffer' } ,
96- ) : Promise < { data : ArrayBuffer } & BlobWithMetadata >
107+ options : { type : 'arrayBuffer' } & GetWithMetadataOptions ,
108+ ) : Promise < { data : ArrayBuffer } & GetWithMetadataResult >
97109
98- async getWithMetadata ( key : string , { type } : { type : 'blob' } ) : Promise < { data : Blob } & BlobWithMetadata >
110+ async getWithMetadata (
111+ key : string ,
112+ options : { type : 'blob' } & GetWithMetadataOptions ,
113+ ) : Promise < { data : Blob } & GetWithMetadataResult >
99114
100- // eslint-disable-next-line @typescript-eslint/no-explicit-any
101- async getWithMetadata ( key : string , { type } : { type : 'json' } ) : Promise < { data : any } & BlobWithMetadata >
115+ /* eslint-disable @typescript-eslint/no-explicit-any */
102116
103- async getWithMetadata ( key : string , { type } : { type : 'stream' } ) : Promise < { data : ReadableStream } & BlobWithMetadata >
117+ async getWithMetadata (
118+ key : string ,
119+ options : { type : 'json' } & GetWithMetadataOptions ,
120+ ) : Promise < { data : any } & GetWithMetadataResult >
104121
105- async getWithMetadata ( key : string , { type } : { type : 'text' } ) : Promise < { data : string } & BlobWithMetadata >
122+ /* eslint-enable @typescript-eslint/no-explicit-any */
106123
107124 async getWithMetadata (
108125 key : string ,
109- options ?: { type : BlobResponseType } ,
126+ options : { type : 'stream' } & GetWithMetadataOptions ,
127+ ) : Promise < { data : ReadableStream } & GetWithMetadataResult >
128+
129+ async getWithMetadata (
130+ key : string ,
131+ options : { type : 'text' } & GetWithMetadataOptions ,
132+ ) : Promise < { data : string } & GetWithMetadataResult >
133+
134+ async getWithMetadata (
135+ key : string ,
136+ options ?: { type : BlobResponseType } & GetWithMetadataOptions ,
110137 ) : Promise <
111138 | ( {
112139 data : ArrayBuffer | Blob | ReadableStream | string | null
113- } & BlobWithMetadata )
140+ } & GetWithMetadataResult )
114141 | null
115142 > {
116- const { type } = options ?? { }
117- const res = await this . client . makeRequest ( { key, method : HTTPMethod . GET , storeName : this . name } )
118- const etag = res ?. headers . get ( 'etag' ) ?? undefined
143+ const { etag : requestETag , type } = options ?? { }
144+ const headers = requestETag ? { 'if-none-match' : requestETag } : undefined
145+ const res = await this . client . makeRequest ( { headers, key, method : HTTPMethod . GET , storeName : this . name } )
146+ const responseETag = res ?. headers . get ( 'etag' ) ?? undefined
119147
120148 let metadata : Metadata = { }
121149
@@ -131,24 +159,34 @@ export class Store {
131159 return null
132160 }
133161
162+ const result : GetWithMetadataResult = {
163+ etag : responseETag ,
164+ fresh : false ,
165+ metadata,
166+ }
167+
168+ if ( res . status === 304 && requestETag ) {
169+ return { data : null , ...result , fresh : true }
170+ }
171+
134172 if ( type === undefined || type === 'text' ) {
135- return { data : await res . text ( ) , etag , metadata }
173+ return { data : await res . text ( ) , ... result }
136174 }
137175
138176 if ( type === 'arrayBuffer' ) {
139- return { data : await res . arrayBuffer ( ) , etag , metadata }
177+ return { data : await res . arrayBuffer ( ) , ... result }
140178 }
141179
142180 if ( type === 'blob' ) {
143- return { data : await res . blob ( ) , etag , metadata }
181+ return { data : await res . blob ( ) , ... result }
144182 }
145183
146184 if ( type === 'json' ) {
147- return { data : await res . json ( ) , etag , metadata }
185+ return { data : await res . json ( ) , ... result }
148186 }
149187
150188 if ( type === 'stream' ) {
151- return { data : res . body , etag , metadata }
189+ return { data : res . body , ... result }
152190 }
153191
154192 throw new Error ( `Invalid 'type' property: ${ type } . Expected: arrayBuffer, blob, json, stream, or text.` )
0 commit comments