-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
preloading.js
82 lines (69 loc) · 2.01 KB
/
preloading.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* WordPress dependencies
*/
import { addQueryArgs, getQueryArgs, normalizePath } from '@wordpress/url';
/**
* @param {Record<string, any>} preloadedData
* @return {import('../types').APIFetchMiddleware} Preloading middleware.
*/
function createPreloadingMiddleware( preloadedData ) {
const cache = Object.fromEntries(
Object.entries( preloadedData ).map( ( [ path, data ] ) => [
normalizePath( path ),
data,
] )
);
return ( options, next ) => {
const { parse = true } = options;
/** @type {string | void} */
let rawPath = options.path;
if ( ! rawPath && options.url ) {
const { rest_route: pathFromQuery, ...queryArgs } = getQueryArgs(
options.url
);
if ( typeof pathFromQuery === 'string' ) {
rawPath = addQueryArgs( pathFromQuery, queryArgs );
}
}
if ( typeof rawPath !== 'string' ) {
return next( options );
}
const method = options.method || 'GET';
const path = normalizePath( rawPath );
if ( 'GET' === method && cache[ path ] ) {
const cacheData = cache[ path ];
// Unsetting the cache key ensures that the data is only used a single time.
delete cache[ path ];
return prepareResponse( cacheData, !! parse );
} else if (
'OPTIONS' === method &&
cache[ method ] &&
cache[ method ][ path ]
) {
const cacheData = cache[ method ][ path ];
// Unsetting the cache key ensures that the data is only used a single time.
delete cache[ method ][ path ];
return prepareResponse( cacheData, !! parse );
}
return next( options );
};
}
/**
* This is a helper function that sends a success response.
*
* @param {Record<string, any>} responseData
* @param {boolean} parse
* @return {Promise<any>} Promise with the response.
*/
function prepareResponse( responseData, parse ) {
return Promise.resolve(
parse
? responseData.body
: new window.Response( JSON.stringify( responseData.body ), {
status: 200,
statusText: 'OK',
headers: responseData.headers,
} )
);
}
export default createPreloadingMiddleware;