Socket
Socket
Sign inDemoInstall

@kano/kbc-telemetry

Package Overview
Dependencies
Maintainers
12
Versions
165
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kano/kbc-telemetry - npm Package Compare versions

Comparing version 4.3.0-alpha.0 to 4.4.0-alpha.0

lib/utils/local-storage.d.ts

13

lib/kbc-telemetry.js

@@ -18,2 +18,3 @@ "use strict";

const react_tracking_1 = require("react-tracking");
const react_detect_offline_1 = require("react-detect-offline");
const telemetry_1 = require("./utils/telemetry");

@@ -23,8 +24,14 @@ let Tracking = class Tracking extends React.Component {

super(props);
this.telemetryClient = new telemetry_1.TelemetryClient(this.props.config);
}
componentDidMount() {
telemetry_1.initialiseTracking(this.props.config);
updateStatus(online) {
this.telemetryClient.updateOnline(online);
}
render() {
return (React.createElement(React.Fragment, null, this.props.children));
return (React.createElement(React.Fragment, null,
React.createElement(react_detect_offline_1.Detector, { render: ({ online }) => {
this.updateStatus(online);
return (React.createElement(React.Fragment, null));
} }),
this.props.children));
}

@@ -31,0 +38,0 @@ };

@@ -1,5 +0,22 @@

export declare const initialiseTracking: (config: {
interface IConfig {
url: string;
env: string;
interval: number;
}) => void;
}
export declare class TelemetryClient {
config: IConfig;
sendingInProgress: boolean;
storeName: string;
acceptedEnv: boolean;
online: boolean;
constructor(config: any);
updateOnline(online: boolean): Promise<void>;
updateLocalStorage(data: any): void;
initialiseTracking(): Promise<void>;
triggerDataSend(data: any, interval?: any): Promise<void>;
sendData(url: string, batch: {
data: any;
collection: string;
}): Promise<any>;
}
export default TelemetryClient;

@@ -10,67 +10,120 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initialiseTracking = (config) => {
const { url, env, interval } = config;
let trackingSending = false;
if (url && (env === 'staging' || env === 'production')) {
const trackingFunc = setInterval(() => __awaiter(this, void 0, void 0, function* () {
if (window.dataLayer && window.dataLayer.length > 0 && !trackingSending) {
trackingSending = true;
const data = [...window.dataLayer];
window.dataLayer = [];
try {
yield sendData(url, { data, collection: env });
trackingSending = false;
const local_storage_1 = __importDefault(require("./local-storage"));
class TelemetryClient {
constructor(config) {
this.config = config;
this.sendingInProgress = false;
this.storeName = `kano-telemetry-${config.env}`;
this.acceptedEnv = config.env === 'staging' || config.env === 'production';
this.initialiseTracking();
}
updateOnline(online) {
return __awaiter(this, void 0, void 0, function* () {
if (this.online && !online) {
this.online = online;
}
else if (!this.online && online) {
this.online = online;
if (this.acceptedEnv) {
const store = JSON.parse(local_storage_1.default.read(this.storeName));
if (store) {
yield this.triggerDataSend(store);
local_storage_1.default.remove(this.storeName);
}
}
catch (error) {
console.error(error);
clearInterval(trackingFunc);
trackingSending = false;
}
}
}), interval);
});
}
};
const sendData = (url = '', batch) => __awaiter(this, void 0, void 0, function* () {
const events = batch.data.map((e) => {
if (e.error) {
e.event = 'error';
e.data = e.error;
}
return JSON.stringify({
page_path: e.page || window.location.pathname,
name: e.event,
properties: e.data,
action: e.action,
module: e.module,
time: Math.round(e.date.getTime()),
timezone_offset: e.date.getTimezoneOffset(),
session_id: e.sessionId,
user_id: e.userId,
version: e.appVersion,
updateLocalStorage(data) {
const current = local_storage_1.default.read(this.storeName);
const store = current ? [...JSON.parse(current), ...data] : [...data];
local_storage_1.default.write(this.storeName, JSON.stringify(store));
}
initialiseTracking() {
return __awaiter(this, void 0, void 0, function* () {
const { url, interval } = this.config;
if (url && this.acceptedEnv) {
const trackingInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
if (window.dataLayer && window.dataLayer.length > 0 && !this.sendingInProgress) {
const data = [...window.dataLayer];
window.dataLayer = [];
if (!this.online) {
return this.updateLocalStorage(data);
}
yield this.triggerDataSend(data, trackingInterval);
}
}), interval);
}
});
});
const packet = {
n: batch.data[0].app,
d: events,
c: batch.collection,
v: batch.data[0].appVersion,
};
const proxyurl = 'https://cors-anywhere.herokuapp.com/';
const response = yield fetch(proxyurl + url, {
method: 'PUT',
body: JSON.stringify(packet),
headers: new Headers({
'Content-Type': 'application/json',
}),
}).then((res) => {
if (res.status === 200) {
return res.json();
}
return res.text().then((text) => {
throw new Error(text);
}
triggerDataSend(data, interval) {
return __awaiter(this, void 0, void 0, function* () {
const { url, env } = this.config;
this.sendingInProgress = true;
try {
yield this.sendData(url, { data, collection: env });
this.sendingInProgress = false;
}
catch (error) {
console.error(error);
if (interval)
clearInterval(interval);
this.sendingInProgress = false;
}
});
});
return response;
});
}
sendData(url = '', batch) {
return __awaiter(this, void 0, void 0, function* () {
const events = batch.data.map((e) => {
if (e.error) {
e.event = 'error';
e.data = e.error;
}
e.date = new Date(e.date);
return JSON.stringify({
page_path: e.page || window.location.pathname,
name: e.event,
properties: e.data,
action: e.action,
module: e.module,
time: Math.round(e.date.getTime()),
timezone_offset: e.date.getTimezoneOffset(),
session_id: e.sessionId,
user_id: e.userId,
version: e.appVersion,
});
});
const packet = {
n: batch.data[0].app,
d: events,
c: batch.collection,
v: batch.data[0].appVersion,
};
const proxyurl = 'https://cors-anywhere.herokuapp.com/';
const response = yield fetch(proxyurl + url, {
method: 'PUT',
body: JSON.stringify(packet),
headers: new Headers({
'Content-Type': 'application/json',
}),
}).then((res) => {
if (res.status === 200) {
return res.json();
}
return res.text().then((text) => {
throw new Error(text);
});
}).catch((err) => {
console.log(err);
});
return response;
});
}
}
exports.TelemetryClient = TelemetryClient;
exports.default = TelemetryClient;
//# sourceMappingURL=telemetry.js.map
{
"name": "@kano/kbc-telemetry",
"version": "4.3.0-alpha.0",
"version": "4.4.0-alpha.0",
"description": "Telemetry module for boilerplate apps, using react-tracking",

@@ -25,2 +25,3 @@ "author": "Kano Computing",

"dependencies": {
"react-detect-offline": "^2.4.0",
"react-tracking": "^7.3.0"

@@ -35,3 +36,3 @@ },

},
"gitHead": "617c06be6752af2dd3fe027a87ba4bbb10927c83"
"gitHead": "73448be5976f9c674878d483d7d51ed8e33bae30"
}

@@ -1,7 +0,11 @@

# `kbc-telemetry`
# kbc-telemetry
Telemetry module for boilerplate apps, using react-tracking
Telemetry module for boilerplate apps, using `react-tracking`. For more information, see [NYTimes React Tracking](https://github.com/nytimes/react-tracking).
## Usage
### Setup
Import and use TelemetryProvider component as a wrapper for your app:
```

@@ -11,5 +15,7 @@ import * as Telemetry from '@kano/kbc-telemetry';

const Tracking = Telemetry.TelemetryProvider;
```
// Wrap your app in <Tracking> and pass config info
Wrap your app in `<Tracking>` and pass config information.
```
const config = {

@@ -33,60 +39,77 @@ app: app.name,

Tracking data can be sent as decorators in container/component files:
See https://github.com/nytimes/react-tracking README
### Within components
Tracking data can be sent in multiple ways:
#### Decorators
Either on component level or at method level.
```
import React, { Component } from 'react';
import * as Telemetry from '@kano/kbc-telemetry';
@Telemetry.track({ event: 'name-of-your-event' })
@Telemetry.track({ event: 'name_of_your_event' })
class MyComponent extends Component {
@Telemetry.track({ event: 'I-did-something', action: 'click' })
@Telemetry.track({ event: 'I_did_something', action: 'click' })
handleSomething() {
//I run something
// I run something
}
}
```
render() {
return <div></div>;
}
Above shows the initial parameter as an object. But it can also be sent as a function, which accesses 3 parameters component `props`, component `state`, function arguments as an array, for example:
```
@Telemetry.track((props, state, args) => ({ event: props.event, data: { something: state.something, args: args[0] } })
handleSomething(iAmArgsZero) {
// I run something
}
```
OR from props as `this.props.tracking.trackEvent({})`, as below:
For decorators, there are explict fields that can be set as follows:
| Decorator | Field Options |
| --------------------------- | ---------------- |
| `@Telemetry.track()` | `event?: String` <br/> `data?: Any` <br/> `action?: String` <br/> `module?: String` <br/> `userId?: String` <br/> `page?: String` |
| `@Telemetry.trackError()` | `error: ` <br/> `{ name: String, stack: String, message: String }` |
#### Props
You can also use as props: `this.props.tracking.trackEvent({})`. This currently doesn't enforce the field options above.
To use tracking in props, the component **must** be either exported by wrapping it in `track()`, as follows:
```
@Telemetry.track({}) // This only needs to be included here if tracking is not being passed from a higher level component.
class MyComponent extends Component {
const FooPage = (props) => {
return <div onClick={() => props.tracking.trackEvent({ action: 'click' })} />;
}
handleSomething() {
this.props.tracking.trackEvent({ event: 'i-handle-something' })
}
export default track({
page: 'FooPage',
})(FooPage);
render() {
return <div></div>;
}
}
```
### Errors
##### OR
Currently `trackError` can only be used as a decorator. Like so in 2 ways:
Wrapped in a decorator:
```
@Telemetry.track({ page: 'MyComponent' })
class MyComponent extends Component {
handleSomething() {
this.props.tracking.trackEvent({ event: 'i_handle_something' })
}
}
```
@Telemetry.trackError({ error: { name: 'handle-error', stack: 'stack', message: 'message' } })
handleError() {
this.props.tracking.trackEvent({ event: 'i-handle-something' })
}
### Tracking Errors
// If you want to send error stacks/messages, these can be accessed by the third arguement
@Telemetry.trackError((props, state, args) => { error: { name: 'handle-error', stack: args[0].stack, message: args[0].message } })
handleDifferentError(err) {
this.props.tracking.trackEvent({ event: 'i-handle-something' })
}
Currently `trackError` can only be used as a decorator. See below and see field options in the table above.
render() {
return <div></div>;
}
```
@Telemetry.trackError({ error: { name: 'handle_error', stack: 'stack', message: 'message' } })
handleError() {
// I handle an error
}

@@ -98,12 +121,5 @@ ```

```
class MyComponent extends Component {
handleSomething() {
this.props.tracking.trackEvent({ error: { name: 'handle-error', stack: 'stack', message: 'message' } })
}
render() {
return <div></div>;
}
handleSomething() {
this.props.tracking.trackEvent({ error: { name: 'handle_error', stack: 'stack', message: 'message' } })
}
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc