-
Notifications
You must be signed in to change notification settings - Fork 2k
/
index.js
120 lines (96 loc) · 3.21 KB
/
index.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import stringify from 'fast-json-stable-stringify';
import { parse } from 'qs';
const readCache = () => {
try {
// load from the project root
// @ts-ignore
return require( '../../../../cached-requests.json' );
} catch ( e ) {
return {};
}
};
const saveRequests = ( requests ) => {
const requestData = {};
requests.forEach( ( value, key ) => {
const path = JSON.parse( key ).path;
if ( ! requestData.hasOwnProperty( path ) ) {
requestData[ path ] = {};
}
requestData[ path ][ key ] = value;
} );
const file = new Blob( [ JSON.stringify( requestData, null, 2 ) ], {
type: 'application/json',
} );
const url = URL.createObjectURL( file );
window.open( url );
};
export const makeOffline = ( wpcom ) => {
// search part includes the leading `?`
const queryParams = parse( window.location.search.substring( 1 ) );
const offlineRequested = queryParams.wpcom_offline;
const primingRequested = queryParams.wpcom_priming;
if ( ! offlineRequested && ! primingRequested ) {
return wpcom;
}
! offlineRequested &&
primingRequested &&
// eslint-disable-next-line no-console
console.log(
'Priming wpcom request cache\n' +
'Run `saveRequests()` in the developer console to save cache file.'
);
offlineRequested &&
// eslint-disable-next-line no-console
console.log( 'Delivering wpcom requests from cache' );
const request = wpcom.request.bind( wpcom );
const requests = new Map();
const storedRequests = readCache();
Object.keys( storedRequests ).forEach( ( path ) => {
Object.keys( storedRequests[ path ] ).forEach( ( key ) => {
requests.set( key, storedRequests[ path ][ key ] );
} );
} );
window.saveRequests = () => saveRequests( requests );
Object.defineProperty( wpcom, 'request', {
value: ( params, callback ) => {
if ( offlineRequested ) {
const stored = requests.get( stringify( params ) );
if ( undefined === callback ) {
if ( undefined === stored ) {
// eslint-disable-next-line no-console
console.error(
`WPCOM Offline: Request made for uncached request to ${ params.path }\n` +
'See client/lib/wp/offline-library/README.md for priming instructions.'
);
return Promise.reject(
new Error( 'Network disconnected and request for path not cached.' )
);
}
return undefined === stored[ 0 ] || null === stored[ 0 ]
? Promise.reject( stored[ 0 ] ) // first arg is error
: Promise.resolve( ...stored.slice( 1 ) ); // skip error in success handler
}
if ( undefined === stored ) {
// eslint-disable-next-line no-console
console.error(
`WPCOM Offline: Request made for uncached request to ${ params.path }\n` +
'See client/lib/wp/offline-library/README.md for priming instructions.'
);
callback( new Error( 'Network disconnected and request for path not cached.' ) );
} else {
callback( ...stored );
}
// make sure we still return an XHR
// this is the expected behavior of wpcom.js request
return new XMLHttpRequest();
}
if ( ! primingRequested ) {
return request( params, callback );
}
return request( params, ( ...args ) => {
requests.set( stringify( params ), args );
return callback( ...args );
} );
},
} );
};