dreaction-react-native 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,4 +32,5 @@ export interface DReactionReactNative extends DReaction, ReactNativePluginFeatur
32
32
  };
33
33
  }
34
34
  export declare const dreaction: DReactionReactNative;
35
+ export declare function watchFPS(): () => void;
35
36
  //# sourceMappingURL=dreaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dreaction.d.ts","sourceRoot":"","sources":["../src/dreaction.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,wBAAwB,EAExB,SAAS,EACT,aAAa,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAGpF,OAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAA0B,EACxB,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAmB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD,YAAY,EAAE,aAAa,EAAE,CAAC;AAM9B,eAAO,MAAM,sBAAsB,OAOO,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC;IAC5C,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC;IACvC,YAAY,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC;IAC7C,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,yBAAyB,GAAG,wBAAwB,CACvD,aAAa,EACb,OAAO,sBAAsB,CAC9B,CAAC;AAEF,MAAM,WAAW,oBACf,SAAQ,SAAS,EAEf,yBAAyB;IAC3B,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC1D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;IACzC,sBAAsB,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnE,mBAAmB,EAAE,CAAC,CAAC,GAAG,OAAO,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,OAAO,CAAC,EAAE;QACR;;WAEG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,KACE;QACH,iBAAiB,EAAE,CAAC,GAAG,SAAS,CAAC;QACjC,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;QAC1C,iBAAiB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;KAC9C,CAAC;CACH;AAkFD,eAAO,MAAM,SAAS,sBAA+C,CAAC"}
1
+ {"version":3,"file":"dreaction.d.ts","sourceRoot":"","sources":["../src/dreaction.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,wBAAwB,EAExB,SAAS,EACT,aAAa,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAGpF,OAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAA0B,EACxB,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAmB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD,YAAY,EAAE,aAAa,EAAE,CAAC;AAM9B,eAAO,MAAM,sBAAsB,OAOO,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC;IAC5C,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC;IACvC,YAAY,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC;IAC7C,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,yBAAyB,GAAG,wBAAwB,CACvD,aAAa,EACb,OAAO,sBAAsB,CAC9B,CAAC;AAEF,MAAM,WAAW,oBACf,SAAQ,SAAS,EAEf,yBAAyB;IAC3B,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC1D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC;IACzC,sBAAsB,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnE,mBAAmB,EAAE,CAAC,CAAC,GAAG,OAAO,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,OAAO,CAAC,EAAE;QACR;;WAEG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,KACE;QACH,iBAAiB,EAAE,CAAC,GAAG,SAAS,CAAC;QACjC,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;QAC1C,iBAAiB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;KAC9C,CAAC;CACH;AAkFD,eAAO,MAAM,SAAS,sBAA+C,CAAC;AAyFtE,wBAAgB,QAAQ,eAMvB"}
package/lib/dreaction.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.dreaction = exports.reactNativeCorePlugins = void 0;
7
+ exports.watchFPS = watchFPS;
7
8
  const react_native_1 = require("react-native");
8
9
  const dreaction_client_core_1 = require("dreaction-client-core");
9
10
  const getReactNativeVersion_1 = __importDefault(require("./helpers/getReactNativeVersion"));
@@ -145,3 +146,10 @@ exports.dreaction.registerDataWatcher = (name, type, options) => {
145
146
  },
146
147
  };
147
148
  };
149
+ function watchFPS() {
150
+ return (0, dreaction_client_core_1.runFPSMeter)((fps) => {
151
+ exports.dreaction.send('profiler.fps', {
152
+ fps,
153
+ });
154
+ });
155
+ }
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  // @ts-ignore
7
- const XHRInterceptor_1 = __importDefault(require("react-native/Libraries/Network/XHRInterceptor"));
4
+ const xhrInterceptor_1 = require("./xhrInterceptor");
8
5
  /**
9
6
  * Don't include the response bodies for images by default.
10
7
  */
@@ -132,9 +129,9 @@ const networking = (pluginConfig = {}) => (dreaction) => {
132
129
  return {
133
130
  onConnect: () => {
134
131
  // register our monkey-patch
135
- XHRInterceptor_1.default.setSendCallback(onSend);
136
- XHRInterceptor_1.default.setResponseCallback(onResponse);
137
- XHRInterceptor_1.default.enableInterception();
132
+ xhrInterceptor_1.XHRInterceptor.setSendCallback(onSend);
133
+ xhrInterceptor_1.XHRInterceptor.setResponseCallback(onResponse);
134
+ xhrInterceptor_1.XHRInterceptor.enableInterception();
138
135
  },
139
136
  };
140
137
  };
@@ -0,0 +1,39 @@
1
+ type XHRInterceptorOpenCallback = (method: string, url: string, request: XMLHttpRequest) => void;
2
+ type XHRInterceptorSendCallback = (data: string, request: XMLHttpRequest) => void;
3
+ type XHRInterceptorRequestHeaderCallback = (header: string, value: string, request: XMLHttpRequest) => void;
4
+ type XHRInterceptorHeaderReceivedCallback = (responseContentType: string | undefined, responseSize: number | undefined, allHeaders: string, request: XMLHttpRequest) => void;
5
+ type XHRInterceptorResponseCallback = (status: number, timeout: number, response: string, responseURL: string, responseType: string, request: XMLHttpRequest) => void;
6
+ /**
7
+ * A network interceptor which monkey-patches XMLHttpRequest methods
8
+ * to gather all network requests/responses, in order to show their
9
+ * information in the React Native inspector development tool.
10
+ * This supports interception with XMLHttpRequest API, including Fetch API
11
+ * and any other third party libraries that depend on XMLHttpRequest.
12
+ */
13
+ export declare const XHRInterceptor: {
14
+ /**
15
+ * Invoked before XMLHttpRequest.open(...) is called.
16
+ */
17
+ setOpenCallback(callback: XHRInterceptorOpenCallback): void;
18
+ /**
19
+ * Invoked before XMLHttpRequest.send(...) is called.
20
+ */
21
+ setSendCallback(callback: XHRInterceptorSendCallback): void;
22
+ /**
23
+ * Invoked after xhr's readyState becomes xhr.HEADERS_RECEIVED.
24
+ */
25
+ setHeaderReceivedCallback(callback: XHRInterceptorHeaderReceivedCallback): void;
26
+ /**
27
+ * Invoked after xhr's readyState becomes xhr.DONE.
28
+ */
29
+ setResponseCallback(callback: XHRInterceptorResponseCallback): void;
30
+ /**
31
+ * Invoked before XMLHttpRequest.setRequestHeader(...) is called.
32
+ */
33
+ setRequestHeaderCallback(callback: XHRInterceptorRequestHeaderCallback): void;
34
+ isInterceptorEnabled(): boolean;
35
+ enableInterception(): void;
36
+ disableInterception(): void;
37
+ };
38
+ export {};
39
+ //# sourceMappingURL=xhrInterceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xhrInterceptor.d.ts","sourceRoot":"","sources":["../../src/plugins/xhrInterceptor.ts"],"names":[],"mappings":"AAgBA,KAAK,0BAA0B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;AAEhG,KAAK,0BAA0B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;AAEjF,KAAK,mCAAmC,GAAG,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,KACpB,IAAI,CAAA;AAET,KAAK,oCAAoC,GAAG,CAC1C,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,KACpB,IAAI,CAAA;AAET,KAAK,8BAA8B,GAAG,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,KACpB,IAAI,CAAA;AAUT;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;8BACuB,0BAA0B;IAIpD;;OAEG;8BACuB,0BAA0B;IAIpD;;OAEG;wCACiC,oCAAoC;IAIxE;;OAEG;kCAC2B,8BAA8B;IAI5D;;OAEG;uCACgC,mCAAmC;4BAI9C,OAAO;;;CAwGhC,CAAA"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ /* eslint-disable prefer-rest-params */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.XHRInterceptor = void 0;
5
+ /**
6
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
7
+ *
8
+ * This source code is licensed under the MIT license found in the
9
+ * LICENSE file in the root directory of this source tree.
10
+ *
11
+ * Vendored from: https://github.com/callstackincubator/rozenite/blob/402e3579878f72cbae7f8123f9ca80459dc1fe7f/packages/network-activity-plugin/src/react-native/http/xhr-interceptor.ts
12
+ * Original source: https://github.com/facebook/react-native/blob/2c683c5787dd03ac15d2aad45dcc53650529ee7f/packages/react-native/src/private/devsupport/devmenu/elementinspector/XHRInterceptor.js
13
+ */
14
+ const originalXHROpen = XMLHttpRequest.prototype.open;
15
+ const originalXHRSend = XMLHttpRequest.prototype.send;
16
+ const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
17
+ let openCallback;
18
+ let sendCallback;
19
+ let requestHeaderCallback;
20
+ let headerReceivedCallback;
21
+ let responseCallback;
22
+ let isInterceptorEnabled = false;
23
+ /**
24
+ * A network interceptor which monkey-patches XMLHttpRequest methods
25
+ * to gather all network requests/responses, in order to show their
26
+ * information in the React Native inspector development tool.
27
+ * This supports interception with XMLHttpRequest API, including Fetch API
28
+ * and any other third party libraries that depend on XMLHttpRequest.
29
+ */
30
+ exports.XHRInterceptor = {
31
+ /**
32
+ * Invoked before XMLHttpRequest.open(...) is called.
33
+ */
34
+ setOpenCallback(callback) {
35
+ openCallback = callback;
36
+ },
37
+ /**
38
+ * Invoked before XMLHttpRequest.send(...) is called.
39
+ */
40
+ setSendCallback(callback) {
41
+ sendCallback = callback;
42
+ },
43
+ /**
44
+ * Invoked after xhr's readyState becomes xhr.HEADERS_RECEIVED.
45
+ */
46
+ setHeaderReceivedCallback(callback) {
47
+ headerReceivedCallback = callback;
48
+ },
49
+ /**
50
+ * Invoked after xhr's readyState becomes xhr.DONE.
51
+ */
52
+ setResponseCallback(callback) {
53
+ responseCallback = callback;
54
+ },
55
+ /**
56
+ * Invoked before XMLHttpRequest.setRequestHeader(...) is called.
57
+ */
58
+ setRequestHeaderCallback(callback) {
59
+ requestHeaderCallback = callback;
60
+ },
61
+ isInterceptorEnabled() {
62
+ return isInterceptorEnabled;
63
+ },
64
+ enableInterception() {
65
+ if (isInterceptorEnabled) {
66
+ return;
67
+ }
68
+ // Override `open` method for all XHR requests to intercept the request
69
+ // method and url, then pass them through the `openCallback`.
70
+ // $FlowFixMe[cannot-write]
71
+ // $FlowFixMe[missing-this-annot]
72
+ XMLHttpRequest.prototype.open = function (method, url) {
73
+ if (openCallback) {
74
+ openCallback(method, url, this);
75
+ }
76
+ originalXHROpen.apply(this, arguments);
77
+ };
78
+ // Override `setRequestHeader` method for all XHR requests to intercept
79
+ // the request headers, then pass them through the `requestHeaderCallback`.
80
+ // $FlowFixMe[cannot-write]
81
+ // $FlowFixMe[missing-this-annot]
82
+ XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
83
+ if (requestHeaderCallback) {
84
+ requestHeaderCallback(header, value, this);
85
+ }
86
+ originalXHRSetRequestHeader.apply(this, arguments);
87
+ };
88
+ // Override `send` method of all XHR requests to intercept the data sent,
89
+ // register listeners to intercept the response, and invoke the callbacks.
90
+ // $FlowFixMe[cannot-write]
91
+ // $FlowFixMe[missing-this-annot]
92
+ XMLHttpRequest.prototype.send = function (data) {
93
+ if (sendCallback) {
94
+ sendCallback(data, this);
95
+ }
96
+ if (this.addEventListener) {
97
+ this.addEventListener("readystatechange", () => {
98
+ if (!isInterceptorEnabled) {
99
+ return;
100
+ }
101
+ if (this.readyState === this.HEADERS_RECEIVED) {
102
+ const contentTypeString = this.getResponseHeader("Content-Type");
103
+ const contentLengthString = this.getResponseHeader("Content-Length");
104
+ let responseContentType, responseSize;
105
+ if (contentTypeString) {
106
+ responseContentType = contentTypeString.split(";")[0];
107
+ }
108
+ if (contentLengthString) {
109
+ responseSize = parseInt(contentLengthString, 10);
110
+ }
111
+ if (headerReceivedCallback) {
112
+ headerReceivedCallback(responseContentType, responseSize, this.getAllResponseHeaders(), this);
113
+ }
114
+ }
115
+ if (this.readyState === this.DONE) {
116
+ if (responseCallback) {
117
+ responseCallback(this.status, this.timeout, this.response, this.responseURL, this.responseType, this);
118
+ }
119
+ }
120
+ }, false);
121
+ }
122
+ originalXHRSend.apply(this, arguments);
123
+ };
124
+ isInterceptorEnabled = true;
125
+ },
126
+ // Unpatch XMLHttpRequest methods and remove the callbacks.
127
+ disableInterception() {
128
+ if (!isInterceptorEnabled) {
129
+ return;
130
+ }
131
+ isInterceptorEnabled = false;
132
+ // $FlowFixMe[cannot-write]
133
+ XMLHttpRequest.prototype.send = originalXHRSend;
134
+ // $FlowFixMe[cannot-write]
135
+ XMLHttpRequest.prototype.open = originalXHROpen;
136
+ // $FlowFixMe[cannot-write]
137
+ XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;
138
+ responseCallback = null;
139
+ openCallback = null;
140
+ sendCallback = null;
141
+ headerReceivedCallback = null;
142
+ requestHeaderCallback = null;
143
+ },
144
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dreaction-react-native",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "main": "lib/index.js",
@@ -15,8 +15,8 @@
15
15
  "author": "moonrailgun <moonrailgun@gmail.com>",
16
16
  "license": "MIT",
17
17
  "dependencies": {
18
- "dreaction-client-core": "1.1.11",
19
- "dreaction-protocol": "1.0.7"
18
+ "dreaction-protocol": "1.0.8",
19
+ "dreaction-client-core": "1.2.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@react-native-async-storage/async-storage": "^2.1.0",
package/src/dreaction.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Platform } from 'react-native';
2
- import { createClient } from 'dreaction-client-core';
2
+ import { createClient, runFPSMeter } from 'dreaction-client-core';
3
3
  import type {
4
4
  ClientOptions,
5
5
  InferFeaturesFromPlugins,
@@ -244,3 +244,11 @@ dreaction.registerDataWatcher = <T = unknown>(
244
244
  },
245
245
  };
246
246
  };
247
+
248
+ export function watchFPS() {
249
+ return runFPSMeter((fps) => {
250
+ dreaction.send('profiler.fps', {
251
+ fps,
252
+ });
253
+ });
254
+ }
@@ -1,5 +1,5 @@
1
1
  // @ts-ignore
2
- import XHRInterceptor from 'react-native/Libraries/Network/XHRInterceptor';
2
+ import { XHRInterceptor } from './xhrInterceptor';
3
3
  import type { DReactionCore, Plugin } from 'dreaction-client-core';
4
4
 
5
5
  /**
@@ -0,0 +1,198 @@
1
+ /* eslint-disable prefer-rest-params */
2
+
3
+ /**
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * Vendored from: https://github.com/callstackincubator/rozenite/blob/402e3579878f72cbae7f8123f9ca80459dc1fe7f/packages/network-activity-plugin/src/react-native/http/xhr-interceptor.ts
10
+ * Original source: https://github.com/facebook/react-native/blob/2c683c5787dd03ac15d2aad45dcc53650529ee7f/packages/react-native/src/private/devsupport/devmenu/elementinspector/XHRInterceptor.js
11
+ */
12
+
13
+ const originalXHROpen = XMLHttpRequest.prototype.open
14
+ const originalXHRSend = XMLHttpRequest.prototype.send
15
+ const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader
16
+
17
+ type XHRInterceptorOpenCallback = (method: string, url: string, request: XMLHttpRequest) => void
18
+
19
+ type XHRInterceptorSendCallback = (data: string, request: XMLHttpRequest) => void
20
+
21
+ type XHRInterceptorRequestHeaderCallback = (
22
+ header: string,
23
+ value: string,
24
+ request: XMLHttpRequest
25
+ ) => void
26
+
27
+ type XHRInterceptorHeaderReceivedCallback = (
28
+ responseContentType: string | undefined,
29
+ responseSize: number | undefined,
30
+ allHeaders: string,
31
+ request: XMLHttpRequest
32
+ ) => void
33
+
34
+ type XHRInterceptorResponseCallback = (
35
+ status: number,
36
+ timeout: number,
37
+ response: string,
38
+ responseURL: string,
39
+ responseType: string,
40
+ request: XMLHttpRequest
41
+ ) => void
42
+
43
+ let openCallback: XHRInterceptorOpenCallback | null
44
+ let sendCallback: XHRInterceptorSendCallback | null
45
+ let requestHeaderCallback: XHRInterceptorRequestHeaderCallback | null
46
+ let headerReceivedCallback: XHRInterceptorHeaderReceivedCallback | null
47
+ let responseCallback: XHRInterceptorResponseCallback | null
48
+
49
+ let isInterceptorEnabled = false
50
+
51
+ /**
52
+ * A network interceptor which monkey-patches XMLHttpRequest methods
53
+ * to gather all network requests/responses, in order to show their
54
+ * information in the React Native inspector development tool.
55
+ * This supports interception with XMLHttpRequest API, including Fetch API
56
+ * and any other third party libraries that depend on XMLHttpRequest.
57
+ */
58
+ export const XHRInterceptor = {
59
+ /**
60
+ * Invoked before XMLHttpRequest.open(...) is called.
61
+ */
62
+ setOpenCallback(callback: XHRInterceptorOpenCallback) {
63
+ openCallback = callback
64
+ },
65
+
66
+ /**
67
+ * Invoked before XMLHttpRequest.send(...) is called.
68
+ */
69
+ setSendCallback(callback: XHRInterceptorSendCallback) {
70
+ sendCallback = callback
71
+ },
72
+
73
+ /**
74
+ * Invoked after xhr's readyState becomes xhr.HEADERS_RECEIVED.
75
+ */
76
+ setHeaderReceivedCallback(callback: XHRInterceptorHeaderReceivedCallback) {
77
+ headerReceivedCallback = callback
78
+ },
79
+
80
+ /**
81
+ * Invoked after xhr's readyState becomes xhr.DONE.
82
+ */
83
+ setResponseCallback(callback: XHRInterceptorResponseCallback) {
84
+ responseCallback = callback
85
+ },
86
+
87
+ /**
88
+ * Invoked before XMLHttpRequest.setRequestHeader(...) is called.
89
+ */
90
+ setRequestHeaderCallback(callback: XHRInterceptorRequestHeaderCallback) {
91
+ requestHeaderCallback = callback
92
+ },
93
+
94
+ isInterceptorEnabled(): boolean {
95
+ return isInterceptorEnabled
96
+ },
97
+
98
+ enableInterception() {
99
+ if (isInterceptorEnabled) {
100
+ return
101
+ }
102
+ // Override `open` method for all XHR requests to intercept the request
103
+ // method and url, then pass them through the `openCallback`.
104
+ // $FlowFixMe[cannot-write]
105
+ // $FlowFixMe[missing-this-annot]
106
+ XMLHttpRequest.prototype.open = function (method: string, url: string) {
107
+ if (openCallback) {
108
+ openCallback(method, url, this)
109
+ }
110
+ originalXHROpen.apply(this, arguments as any)
111
+ }
112
+
113
+ // Override `setRequestHeader` method for all XHR requests to intercept
114
+ // the request headers, then pass them through the `requestHeaderCallback`.
115
+ // $FlowFixMe[cannot-write]
116
+ // $FlowFixMe[missing-this-annot]
117
+ XMLHttpRequest.prototype.setRequestHeader = function (header: string, value: string) {
118
+ if (requestHeaderCallback) {
119
+ requestHeaderCallback(header, value, this)
120
+ }
121
+ originalXHRSetRequestHeader.apply(this, arguments as any)
122
+ }
123
+
124
+ // Override `send` method of all XHR requests to intercept the data sent,
125
+ // register listeners to intercept the response, and invoke the callbacks.
126
+ // $FlowFixMe[cannot-write]
127
+ // $FlowFixMe[missing-this-annot]
128
+ XMLHttpRequest.prototype.send = function (data: string) {
129
+ if (sendCallback) {
130
+ sendCallback(data, this)
131
+ }
132
+ if (this.addEventListener) {
133
+ this.addEventListener(
134
+ "readystatechange",
135
+ () => {
136
+ if (!isInterceptorEnabled) {
137
+ return
138
+ }
139
+ if (this.readyState === this.HEADERS_RECEIVED) {
140
+ const contentTypeString = this.getResponseHeader("Content-Type")
141
+ const contentLengthString = this.getResponseHeader("Content-Length")
142
+ let responseContentType, responseSize
143
+ if (contentTypeString) {
144
+ responseContentType = contentTypeString.split(";")[0]
145
+ }
146
+ if (contentLengthString) {
147
+ responseSize = parseInt(contentLengthString, 10)
148
+ }
149
+ if (headerReceivedCallback) {
150
+ headerReceivedCallback(
151
+ responseContentType,
152
+ responseSize,
153
+ this.getAllResponseHeaders(),
154
+ this
155
+ )
156
+ }
157
+ }
158
+ if (this.readyState === this.DONE) {
159
+ if (responseCallback) {
160
+ responseCallback(
161
+ this.status,
162
+ this.timeout,
163
+ this.response,
164
+ this.responseURL,
165
+ this.responseType,
166
+ this
167
+ )
168
+ }
169
+ }
170
+ },
171
+ false
172
+ )
173
+ }
174
+
175
+ originalXHRSend.apply(this, arguments as any)
176
+ }
177
+ isInterceptorEnabled = true
178
+ },
179
+
180
+ // Unpatch XMLHttpRequest methods and remove the callbacks.
181
+ disableInterception() {
182
+ if (!isInterceptorEnabled) {
183
+ return
184
+ }
185
+ isInterceptorEnabled = false
186
+ // $FlowFixMe[cannot-write]
187
+ XMLHttpRequest.prototype.send = originalXHRSend
188
+ // $FlowFixMe[cannot-write]
189
+ XMLHttpRequest.prototype.open = originalXHROpen
190
+ // $FlowFixMe[cannot-write]
191
+ XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader
192
+ responseCallback = null
193
+ openCallback = null
194
+ sendCallback = null
195
+ headerReceivedCallback = null
196
+ requestHeaderCallback = null
197
+ },
198
+ }