UNPKG

quala-node

Version:
211 lines 7.4 kB
'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