@@ -47,6 +47,7 @@ import { ProcessorError } from "./ProcessorError";
47
47
import { RequestInitGenerator } from "./RequestInitGenerator" ;
48
48
49
49
const SAFE_METHODS = [ "GET" , "HEAD" , "OPTIONS" , "CONNECT" , "TRACE" ] ;
50
+ const FETCHER_CALLBACKS = [ "done" , "fail" , "refresh" , "request" , "retract" ] ;
50
51
51
52
async function handleStatus ( res : ResponseAndFallbacks ) : Promise < ResponseAndFallbacks > {
52
53
if ( res . status === NOT_FOUND ) {
@@ -127,7 +128,7 @@ export const emptyRequest = Object.freeze({
127
128
requested : false ,
128
129
status : null ,
129
130
timesRequested : 0 ,
130
- } ) ;
131
+ } ) as EmptyRequestStatus ;
131
132
132
133
/**
133
134
* The client (User Agent) has closed the connection, e.g. due to CORS or going offline.
@@ -154,6 +155,7 @@ export class DataProcessor {
154
155
private readonly requestInitGenerator : RequestInitGenerator ;
155
156
private readonly mapping : { [ k : string ] : ResponseTransformer [ ] } ;
156
157
private readonly requestMap : Map < NamedNode , Promise < Statement [ ] > | undefined > ;
158
+ private readonly statusMap : Map < NamedNode , EmptyRequestStatus | FulfilledRequestStatus > ;
157
159
private readonly requestNotifier ?: RequestCallbackHandler ;
158
160
private readonly store : RDFStore ;
159
161
@@ -163,11 +165,12 @@ export class DataProcessor {
163
165
fetch : window && window . fetch . bind ( window ) ,
164
166
timeout : this . timeout ,
165
167
} ) ;
166
- if ( typeof this . requestNotifier !== "undefined" ) {
167
- [ "done" , "fail" , "refresh" , "request" , "retract" ] . forEach ( ( hook ) => {
168
- this . _fetcher ! . addCallback ( hook , this . requestNotifier ! ) ;
169
- } ) ;
170
- }
168
+ FETCHER_CALLBACKS . forEach ( ( hook ) => {
169
+ this . _fetcher ! . addCallback ( hook , this . invalidateCache . bind ( this ) ) ;
170
+ if ( typeof this . requestNotifier === "function" ) {
171
+ this . _fetcher ! . addCallback ( hook , this . requestNotifier ) ;
172
+ }
173
+ } ) ;
171
174
}
172
175
return this . _fetcher ;
173
176
}
@@ -183,6 +186,7 @@ export class DataProcessor {
183
186
this . requestInitGenerator = opts . requestInitGenerator || new RequestInitGenerator ( ) ;
184
187
this . mapping = opts . mapping || { } ;
185
188
this . requestMap = new Map ( ) ;
189
+ this . statusMap = new Map ( ) ;
186
190
this . store = opts . store ;
187
191
this . requestNotifier = opts . requestNotifier ;
188
192
if ( opts . fetcher ) {
@@ -318,13 +322,17 @@ export class DataProcessor {
318
322
*/
319
323
public getStatus ( iri : NamedNode ) : EmptyRequestStatus | FulfilledRequestStatus {
320
324
const irl = namedNodeByIRI ( iri . value . split ( "#" ) . shift ( ) ! ) ;
325
+
326
+ if ( this . statusMap . has ( irl ) ) {
327
+ return this . statusMap . get ( irl ) ! ;
328
+ }
321
329
const fetcherStatus = this . fetcher . requested [ irl . value ] ;
322
330
323
331
if ( fetcherStatus === undefined ) {
324
332
if ( irl . value in this . fetcher . requested ) {
325
- return failedRequest ( ) ;
333
+ return this . memoizeStatus ( irl , failedRequest ( ) ) ;
326
334
}
327
- return emptyRequest as EmptyRequestStatus ;
335
+ return this . memoizeStatus ( irl , emptyRequest ) ;
328
336
}
329
337
330
338
const requests = this . store . match (
@@ -334,18 +342,21 @@ export class DataProcessor {
334
342
) ;
335
343
const totalRequested = requests . length ;
336
344
if ( requests . length === 0 ) {
337
- return emptyRequest as EmptyRequestStatus ;
345
+ return this . memoizeStatus ( irl , emptyRequest ) ;
338
346
}
339
347
if ( fetcherStatus === true ) {
340
- return {
341
- lastRequested : new Date ( ) ,
342
- requested : true ,
343
- status : 202 ,
344
- timesRequested : totalRequested ,
345
- } ;
348
+ return this . memoizeStatus (
349
+ irl ,
350
+ {
351
+ lastRequested : new Date ( ) ,
352
+ requested : true ,
353
+ status : 202 ,
354
+ timesRequested : totalRequested ,
355
+ } ,
356
+ ) ;
346
357
}
347
358
if ( fetcherStatus === "timeout" ) {
348
- return timedOutRequest ( totalRequested ) ;
359
+ return this . memoizeStatus ( irl , timedOutRequest ( totalRequested ) ) ;
349
360
}
350
361
const requestIRI = requests . pop ( ) ! . subject as BlankNode ;
351
362
const requestObj = anyRDFValue (
@@ -354,7 +365,7 @@ export class DataProcessor {
354
365
) ;
355
366
356
367
if ( ! requestObj ) {
357
- return emptyRequest as EmptyRequestStatus ;
368
+ return this . memoizeStatus ( irl , emptyRequest ) ;
358
369
}
359
370
360
371
const requestObjData = this . store . statementsFor ( requestObj as BlankNode ) ;
@@ -367,17 +378,20 @@ export class DataProcessor {
367
378
368
379
if ( ! requestStatus ) {
369
380
if ( fetcherStatus === "done" ) {
370
- return timedOutRequest ( totalRequested ) ;
381
+ return this . memoizeStatus ( irl , timedOutRequest ( totalRequested ) ) ;
371
382
}
372
- return emptyRequest as EmptyRequestStatus ;
383
+ return this . memoizeStatus ( irl , emptyRequest ) ;
373
384
}
374
385
375
- return {
376
- lastRequested : requestDate ? new Date ( requestDate . value ) : new Date ( 0 ) ,
377
- requested : true ,
378
- status : Number . parseInt ( requestStatus . value , 10 ) ,
379
- timesRequested : totalRequested ,
380
- } ;
386
+ return this . memoizeStatus (
387
+ irl ,
388
+ {
389
+ lastRequested : requestDate ? new Date ( requestDate . value ) : new Date ( 0 ) ,
390
+ requested : true ,
391
+ status : Number . parseInt ( requestStatus . value , 10 ) ,
392
+ timesRequested : totalRequested ,
393
+ } ,
394
+ ) ;
381
395
}
382
396
383
397
public processExternalResponse ( response : Response ) : Promise < Statement [ ] | undefined > {
@@ -411,4 +425,16 @@ export class DataProcessor {
411
425
412
426
return processor ( res ) ;
413
427
}
428
+
429
+ private invalidateCache ( iri : string | NamedNode , _err ?: Error ) : boolean {
430
+ this . statusMap . delete ( typeof iri === "string" ? namedNodeByIRI ( iri ) : iri ) ;
431
+ return true ;
432
+ }
433
+
434
+ private memoizeStatus ( iri : NamedNode ,
435
+ s : EmptyRequestStatus | FulfilledRequestStatus ) : EmptyRequestStatus | FulfilledRequestStatus {
436
+ this . statusMap . set ( iri , s ) ;
437
+
438
+ return s ;
439
+ }
414
440
}
0 commit comments