quala-node
Version:
client library for quala
211 lines • 7.4 kB
JavaScript
'use strict';
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const axios_1 = require("axios");
const axiosRetry = require('axios-retry');
const axios_retry_1 = require("axios-retry");
const ms_1 = require("ms");
const removeSlash_1 = require("./removeSlash");
const class_validator_1 = require("class-validator");
const version = require('../package.json').version;
const setImmediate = global.setImmediate || process.nextTick.bind(process);
const noop = () => { };
var MessageType;
(function (MessageType) {
MessageType["IDENTIFY"] = "IDENTIFY";
MessageType["IDENTIFY_COMPANY"] = "IDENTIFY_COMPANY";
MessageType["TRACK"] = "TRACK";
})(MessageType = exports.MessageType || (exports.MessageType = {}));
class Message {
}
__decorate([
class_validator_1.IsNotEmpty(),
__metadata("design:type", String)
], Message.prototype, "userId", void 0);
exports.Message = Message;
class BatchMessage extends Message {
}
__decorate([
class_validator_1.IsNotEmpty(),
__metadata("design:type", String)
], BatchMessage.prototype, "type", void 0);
exports.BatchMessage = BatchMessage;
class CompanyTraits {
}
exports.CompanyTraits = CompanyTraits;
class UserTraits {
}
exports.UserTraits = UserTraits;
class IndentifyMessage extends Message {
}
__decorate([
class_validator_1.IsNotEmpty(),
__metadata("design:type", String)
], IndentifyMessage.prototype, "companyId", void 0);
__decorate([
class_validator_1.IsOptional(),
__metadata("design:type", Object)
], IndentifyMessage.prototype, "traits", void 0);
__decorate([
class_validator_1.IsOptional(),
__metadata("design:type", Object)
], IndentifyMessage.prototype, "companyTraits", void 0);
exports.IndentifyMessage = IndentifyMessage;
class IndentifyCompanyMessage extends Message {
}
__decorate([
class_validator_1.IsNotEmpty(),
__metadata("design:type", String)
], IndentifyCompanyMessage.prototype, "companyId", void 0);
__decorate([
class_validator_1.IsOptional(),
__metadata("design:type", Object)
], IndentifyCompanyMessage.prototype, "companyTraits", void 0);
class Properties {
}
class TrackMessage extends Message {
}
__decorate([
class_validator_1.IsNotEmpty(),
__metadata("design:type", String)
], TrackMessage.prototype, "signal", void 0);
__decorate([
class_validator_1.IsOptional(),
__metadata("design:type", Object)
], TrackMessage.prototype, "properties", void 0);
exports.TrackMessage = TrackMessage;
class Beacon {
constructor(writeKey, options = {}) {
this.timer = null;
assert(writeKey, 'You must pass your Quala project\'s writeKey.');
this.queue = [];
this.writeKey = writeKey;
this.host = removeSlash_1.default(options.host || 'https://beacon.quala.io');
this.timeout = options.timeout || false;
this.flushAt = Math.max(options.flushAt, 1) || 20;
this.flushInterval = options.flushInterval || 10000;
this.flushed = false;
this.enable = options.enable || true;
axiosRetry(axios_1.default, {
retries: options.retryCount || 3,
retryCondition: this._isErrorRetryable,
retryDelay: axios_retry_1.exponentialDelay
});
}
static _validate(object) {
class_validator_1.validateSync(object);
}
identify(message, callback = undefined) {
Beacon._validate(message);
this.enqueue(MessageType.IDENTIFY, message, callback);
return this;
}
identifyCompany(message, callback = undefined) {
Beacon._validate(message);
this.enqueue(MessageType.IDENTIFY_COMPANY, message, callback);
return this;
}
track(message, callback = undefined) {
Beacon._validate(message);
this.enqueue(MessageType.TRACK, message, callback);
return this;
}
enqueue(type, message, callback) {
callback = callback || noop;
if (!this.enable) {
return setImmediate(callback);
}
let batchMessage = Object.assign(new BatchMessage(), message);
batchMessage.type = type;
if (!batchMessage.timestamp) {
batchMessage.timestamp = new Date();
}
this.queue.push({ message: batchMessage, callback });
if (!this.flushed) {
this.flushed = true;
this.flush();
return;
}
if (this.queue.length >= this.flushAt) {
this.flush();
}
if (this.flushInterval && !this.timer) {
this.timer = setTimeout(this.flush.bind(this), this.flushInterval);
}
}
flush(callback = undefined) {
callback = callback || noop;
if (!this.enable) {
return setImmediate(callback);
}
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
if (!this.queue.length) {
return setImmediate(callback);
}
const items = this.queue.splice(0, this.flushAt);
const callbacks = items.map(item => item.callback);
const messages = items.map(item => item.message);
const data = {
batch: messages,
timestamp: new Date(),
sentAt: new Date()
};
const done = (err = undefined) => {
callbacks.forEach(callback => callback(err));
callback(err, data);
};
const headers = {
'authorization': `writeKey: ${this.writeKey}`
};
if (typeof window === 'undefined') {
headers['user-agent'] = `beacon-node/${version}`;
}
const req = {
method: 'POST',
url: `${this.host}/v1/batch`,
data,
headers
};
if (this.timeout) {
req.timeout = typeof this.timeout === 'string' ? ms_1.default(this.timeout) : this.timeout;
}
axios_1.default(req)
.then(() => done())
.catch(err => {
if (err.response) {
const error = new Error(err.response.statusText);
return done(error);
}
done(err);
});
}
_isErrorRetryable(error) {
if (axios_retry_1.isNetworkError(error)) {
return true;
}
if (!error.response) {
return false;
}
if (error.response.status >= 500 && error.response.status <= 599) {
return true;
}
if (error.response.status === 429) {
return true;
}
return false;
}
}
exports.default = Beacon;
//# sourceMappingURL=index.js.map