Merge pull request #10 from Fine0830/docs-project

Docs: Improve project readme
diff --git a/README.md b/README.md
index 8ffa9eb..fb5ebb4 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,120 @@
 - Provide metrics and error collection to SkyWalking backend.
 - Lightweight
 
+# Usage
+* Install  
+the skywalking-client-js runtime library is available at npm
+```
+npm install skywalking-client-js --save
+```
+* Init SDK
+```
+import ClientMonitor from 'skywalking-client-js';
+```
+```
+ClientMonitor.register({
+  service: 'test-ui',
+  pagePath: 'http://localhost:8080/',
+  serviceVersion: 'v1.0.0',
+});
+```
+* SDK Reference
+
+|Parameter|Type|Description|Required|Default Value|
+|----|----|----|----|----|
+|service|String|project id|true|-|
+|serviceVersion|String|project verison|true|-|
+|pagePath|String|project path|true|-|
+|jsErrors|Boolean|Support js errors monitoring|false|true|
+|apiErrors|Boolean|Support API errors monitoring|false|true|
+|resourceErrors|Boolean|Support resource errors monitoring|false|true|
+|useFmp|Boolean|Collect FMP (first meaningful paint) data of the first screen|false|false|
+|enableSPA|Boolean|Monitor the page hashchange event and report PV, which is suitable for single page application scenarios|false|false|
+|autoTracePerf|Boolean|Support automatic sending of performance data|false|true|
+|vue|Boolean|Support vue errors monitoring|false|true|
+
+* API Reference
+
+**register()**  
+After the SDK is initially completed, it calls the register() interface to revise some of the configuration items. For details of the SDK configuration item, see SDK reference.  
+
+register() grammar  
+```
+ClientMonitor.register(params);
+```
+
+register() call parameters  
+|Parameter|Type|Description|Required|Default Value|
+|----|----|---------|----|----|
+|params|Object|Configuration items and values to be modified|true|-|
+
+**setPerformance()**  
+After the page onLoad, call the setPerformance() interface to report the default performance metrics.  
+
+How to use setPerformance()  
+1. Set the SDK configuration item autoTracePerf to false to turn off automatic reporting performance metrics and wait for manual triggering of escalation.  
+2. Call ClientMonitor.setPerformance(object) method to report automatically the default performance metrics.  
+
+setPerformance() examples of use  
+```
+import ClientMonitor from 'skywalking-client-js';
+
+ClientMonitor.setPerformance({
+  reportUrl: 'http://example.com',
+  service: 'skywalking-ui',
+  serviceVersion: 'v8.1.0',
+  pagePath: location.href,
+  useFmp: true
+});
+```
+* Special scene
+
+**SPA Page**  
+In spa (single page application) single page application, the page will be refreshed only once. The traditional method only reports PV once after the page loading, but cannot count the PV of each sub-page, and can't make other types of logs aggregate by sub-page.  
+The SDK provides two processing methods for spa pages:  
+1. Enable spa automatic parsing  
+This method is suitable for most single page application scenarios with URL hash as the route.  
+In the initialized configuration item, set enableSPA to true, which will turn on the page's hashchange event listening (trigger re reporting PV), and use URL hash as the page field in other data reporting.  
+2. Manual reporting  
+This method can be used in all single page application scenarios. This method can be used if the first method is invalid.    
+The SDK provides a setpage method to manually update the page name when data is reported. When this method is called, the page PV will be re reported by default. For details, see setPerformance().  
+```
+app.on('routeChange', function (next) {
+  ClientMonitor.setPerformance({
+    reportUrl: 'http://example.com',
+    service: 'skywalking-ui',
+    serviceVersion: 'v8.1.0',
+    pagePath: location.href,
+    useFmp: true
+  });
+});   
+```
+
+# Development
+* Install Modules
+```
+npm install
+```
+* Projects that use this project need to do the following  
+
+```
+npm link path/skywalking-client-js
+```
+```
+import ClientMonitor from '../node_modules/skywalking-client-js/src/index';
+ClientMonitor.register({
+  service: 'test-ui',
+  pagePath: 'http://localhost:8080/',
+  serviceVersion: 'v1.0.0'
+});
+```
+* Front end agent
+Refer to [test project](https://github.com/SkyAPMTest/skywalking-client-test)
+* Start project
+```
+npm run start
+```
+
 # Contact Us
 * Submit an [issue](https://github.com/apache/skywalking/issues)
 * Mail list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe the mail list.
@@ -16,4 +130,3 @@
 
 # License
 Apache 2.0
-
diff --git a/src/errors/ajax.ts b/src/errors/ajax.ts
index 8d6dc71..366d978 100644
--- a/src/errors/ajax.ts
+++ b/src/errors/ajax.ts
@@ -20,11 +20,8 @@
 import { GradeTypeEnum, ErrorsCategory } from '../services/constant';
 
 class AjaxErrors extends Base {
-  public handleError(options: {
-    service: string;
-    serviceVersion: string;
-    pagePath: string;
-  }) {
+  // get http error info
+  public handleError(options: { service: string; serviceVersion: string; pagePath: string }) {
     if (!window.XMLHttpRequest) {
       return;
     }
@@ -52,14 +49,19 @@
         console.log(error);
       }
     };
-    XMLHttpRequest.prototype.send = function() {
+    XMLHttpRequest.prototype.send = function () {
       if (this.addEventListener) {
         this.addEventListener('error', xhrEvent);
         this.addEventListener('load', xhrEvent);
         this.addEventListener('abort', xhrEvent);
+        this.addEventListener('loadstart', xhrEvent);
+        this.addEventListener('progress', xhrEvent);
+        this.addEventListener('timeout', xhrEvent);
+        this.addEventListener('loadend', xhrEvent);
+        this.addEventListener('readystatechange', xhrEvent);
       } else {
         const stateChange = this.onreadystatechange;
-        this.onreadystatechange = function(event: any) {
+        this.onreadystatechange = function (event: any) {
           stateChange.apply(this, arguments);
           if (this.readyState === 4) {
             xhrEvent(event);
diff --git a/src/monitor.ts b/src/monitor.ts
index 3662d49..f73bc86 100644
--- a/src/monitor.ts
+++ b/src/monitor.ts
@@ -27,7 +27,6 @@
     autoTracePerf: true, // trace performance detail
     useFmp: false, // use first meaningful paint
     enableSPA: false,
-    autoSendPerf: true,
   } as CustomOptionsType,
 
   register(configs: CustomOptionsType) {
@@ -36,7 +35,7 @@
       ...configs,
     };
     this.errors(configs);
-    if (this.customOptions.autoSendPerf) {
+    if (this.customOptions.autoTracePerf) {
       this.performance();
     }
   },
@@ -45,32 +44,40 @@
     if (document.readyState === 'complete') {
       Performance.recordPerf(this.customOptions);
     } else {
-      window.addEventListener('load', () => {
-        Performance.recordPerf(this.customOptions);
-      }, false);
+      window.addEventListener(
+        'load',
+        () => {
+          Performance.recordPerf(this.customOptions);
+        },
+        false,
+      );
     }
     if (this.customOptions.enableSPA) {
       // hash router
-      window.addEventListener('hashchange', () => {
-        Performance.recordPerf(this.customOptions);
-      }, false);
+      window.addEventListener(
+        'hashchange',
+        () => {
+          Performance.recordPerf(this.customOptions);
+        },
+        false,
+      );
     }
   },
   errors(options: CustomOptionsType) {
     const { service, pagePath, serviceVersion } = options;
 
     if (this.customOptions.jsErrors) {
-      JSErrors.handleErrors({ service, pagePath, serviceVersion});
-      PromiseErrors.handleErrors({ service, pagePath, serviceVersion});
+      JSErrors.handleErrors({ service, pagePath, serviceVersion });
+      PromiseErrors.handleErrors({ service, pagePath, serviceVersion });
       if (this.customOptions.vue) {
-        VueErrors.handleErrors({ service, pagePath, serviceVersion}, this.customOptions.vue);
+        VueErrors.handleErrors({ service, pagePath, serviceVersion }, this.customOptions.vue);
       }
     }
     if (this.customOptions.apiErrors) {
-      AjaxErrors.handleError({ service, pagePath, serviceVersion});
+      AjaxErrors.handleError({ service, pagePath, serviceVersion });
     }
     if (this.customOptions.resourceErrors) {
-      ResourceErrors.handleErrors({ service, pagePath, serviceVersion});
+      ResourceErrors.handleErrors({ service, pagePath, serviceVersion });
     }
   },
   setPerformance(configs: CustomOptionsType) {
diff --git a/src/services/report.ts b/src/services/report.ts
index 213cfed..434076f 100644
--- a/src/services/report.ts
+++ b/src/services/report.ts
@@ -29,6 +29,7 @@
   }
 
   public sendByFetch(data: any) {
+    console.log(data);
     const sendRequest = new Request(this.url, { method: 'POST', body: JSON.stringify(data) });
 
     fetch(sendRequest)
diff --git a/src/types.d.ts b/src/types.d.ts
index c501cf8..b4f3f69 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -25,6 +25,5 @@
   autoTracePerf: boolean;
   useFmp: boolean;
   enableSPA: boolean;
-  autoSendPerf: boolean;
   vue: any;
 }