UNPKG

@segment/analytics-next

Version:

Analytics Next (aka Analytics 2.0) is the latest version of Segment’s JavaScript SDK - enabling you to send your data to any tool without having to learn, test, or use a new API every time.

370 lines 19.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ajsDestinations = exports.LegacyDestination = void 0; var tslib_1 = require("tslib"); var facade_1 = require("@segment/facade"); var connection_1 = require("../../core/connection"); var context_1 = require("../../core/context"); var environment_1 = require("../../core/environment"); var analytics_core_1 = require("@segment/analytics-core"); var is_plan_event_enabled_1 = require("../../lib/is-plan-event-enabled"); var merged_options_1 = require("../../lib/merged-options"); var p_while_1 = require("../../lib/p-while"); var priority_queue_1 = require("../../lib/priority-queue"); var persisted_1 = require("../../lib/priority-queue/persisted"); var middleware_1 = require("../middleware"); var loader_1 = require("./loader"); var analytics_core_2 = require("@segment/analytics-core"); var utils_1 = require("./utils"); var metric_helpers_1 = require("../../core/stats/metric-helpers"); var analytics_generic_utils_1 = require("@segment/analytics-generic-utils"); function flushQueue(xt, queue) { return tslib_1.__awaiter(this, void 0, void 0, function () { var failedQueue; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: failedQueue = []; if ((0, connection_1.isOffline)()) { return [2 /*return*/, queue]; } return [4 /*yield*/, (0, p_while_1.pWhile)(function () { return queue.length > 0 && (0, connection_1.isOnline)(); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var ctx, result, success; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: ctx = queue.pop(); if (!ctx) { return [2 /*return*/]; } return [4 /*yield*/, (0, analytics_core_1.attempt)(ctx, xt)]; case 1: result = _a.sent(); success = result instanceof context_1.Context; if (!success) { failedQueue.push(ctx); } return [2 /*return*/]; } }); }); }) // re-add failed tasks ]; case 1: _a.sent(); // re-add failed tasks failedQueue.map(function (failed) { return queue.pushWithBackoff(failed); }); return [2 /*return*/, queue]; } }); }); } var LegacyDestination = /** @class */ (function () { function LegacyDestination(name, version, writeKey, settings, options, integrationSource) { if (settings === void 0) { settings = {}; } var _this = this; this.options = {}; this.type = 'destination'; this.middleware = []; this.initializePromise = (0, analytics_generic_utils_1.createDeferred)(); this.flushing = false; this.name = name; this.version = version; this.settings = tslib_1.__assign({}, settings); this.disableAutoISOConversion = options.disableAutoISOConversion || false; this.integrationSource = integrationSource; // AJS-Renderer sets an extraneous `type` setting that clobbers // existing type defaults. We need to remove it if it's present if (this.settings['type'] && this.settings['type'] === 'browser') { delete this.settings['type']; } this.initializePromise.promise.then(function (isInitialized) { return (_this._initialized = isInitialized); }, function () { }); this.options = options; this.buffer = options.disableClientPersistence ? new priority_queue_1.PriorityQueue(4, []) : new persisted_1.PersistedPriorityQueue(4, "".concat(writeKey, ":dest-").concat(name)); this.scheduleFlush(); } LegacyDestination.prototype.isLoaded = function () { return !!this._ready; }; LegacyDestination.prototype.ready = function () { var _this = this; return this.initializePromise.promise.then(function () { var _a; return (_a = _this.onReady) !== null && _a !== void 0 ? _a : Promise.resolve(); }); }; LegacyDestination.prototype.load = function (ctx, analyticsInstance) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function () { var integrationSource, _b, error_1; var _this = this; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: if (this._ready || this.onReady !== undefined) { return [2 /*return*/]; } _c.label = 1; case 1: _c.trys.push([1, 5, , 6]); if (!((_a = this.integrationSource) !== null && _a !== void 0)) return [3 /*break*/, 2]; _b = _a; return [3 /*break*/, 4]; case 2: return [4 /*yield*/, (0, loader_1.loadIntegration)(ctx, this.name, this.version, this.options.obfuscate)]; case 3: _b = (_c.sent()); _c.label = 4; case 4: integrationSource = _b; this.integration = (0, loader_1.buildIntegration)(integrationSource, this.settings, analyticsInstance); return [3 /*break*/, 6]; case 5: error_1 = _c.sent(); (0, metric_helpers_1.recordIntegrationMetric)(ctx, { integrationName: this.name, methodName: 'load', type: 'classic', didError: true, }); throw error_1; case 6: this.onReady = new Promise(function (resolve) { var onReadyFn = function () { _this._ready = true; resolve(true); }; _this.integration.once('ready', onReadyFn); }); this.integration.on('initialize', function () { _this.initializePromise.resolve(true); }); try { (0, metric_helpers_1.recordIntegrationMetric)(ctx, { integrationName: this.name, methodName: 'initialize', type: 'classic', }); this.integration.initialize(); } catch (error) { (0, metric_helpers_1.recordIntegrationMetric)(ctx, { integrationName: this.name, methodName: 'initialize', type: 'classic', didError: true, }); this.initializePromise.resolve(false); throw error; } return [2 /*return*/]; } }); }); }; LegacyDestination.prototype.unload = function (_ctx, _analyticsInstance) { return (0, loader_1.unloadIntegration)(this.name, this.version, this.options.obfuscate); }; LegacyDestination.prototype.addMiddleware = function () { var _a; var fn = []; for (var _i = 0; _i < arguments.length; _i++) { fn[_i] = arguments[_i]; } this.middleware = (_a = this.middleware).concat.apply(_a, fn); }; LegacyDestination.prototype.shouldBuffer = function (ctx) { return ( // page events can't be buffered because of destinations that automatically add page views ctx.event.type !== 'page' && ((0, connection_1.isOffline)() || this._ready !== true || this._initialized !== true)); }; LegacyDestination.prototype.send = function (ctx, clz, eventType) { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function () { var plan, ev, planEvent, afterMiddleware, event, err_1; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: if (this.shouldBuffer(ctx)) { this.buffer.push(ctx); this.scheduleFlush(); return [2 /*return*/, ctx]; } plan = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.plan) === null || _b === void 0 ? void 0 : _b.track; ev = ctx.event.event; if (plan && ev && this.name !== 'Segment.io') { planEvent = plan[ev]; if (!(0, is_plan_event_enabled_1.isPlanEventEnabled)(plan, planEvent)) { ctx.updateEvent('integrations', tslib_1.__assign(tslib_1.__assign({}, ctx.event.integrations), { All: false, 'Segment.io': true })); ctx.cancel(new context_1.ContextCancelation({ retry: false, reason: "Event ".concat(ev, " disabled for integration ").concat(this.name, " in tracking plan"), type: 'Dropped by plan', })); } else { ctx.updateEvent('integrations', tslib_1.__assign(tslib_1.__assign({}, ctx.event.integrations), planEvent === null || planEvent === void 0 ? void 0 : planEvent.integrations)); } if ((planEvent === null || planEvent === void 0 ? void 0 : planEvent.enabled) && (planEvent === null || planEvent === void 0 ? void 0 : planEvent.integrations[this.name]) === false) { ctx.cancel(new context_1.ContextCancelation({ retry: false, reason: "Event ".concat(ev, " disabled for integration ").concat(this.name, " in tracking plan"), type: 'Dropped by plan', })); } } return [4 /*yield*/, (0, middleware_1.applyDestinationMiddleware)(this.name, ctx.event, this.middleware)]; case 1: afterMiddleware = _c.sent(); if (afterMiddleware === null) { return [2 /*return*/, ctx]; } event = new clz(afterMiddleware, { traverse: !this.disableAutoISOConversion, }); (0, metric_helpers_1.recordIntegrationMetric)(ctx, { integrationName: this.name, methodName: eventType, type: 'classic', }); _c.label = 2; case 2: _c.trys.push([2, 5, , 6]); if (!this.integration) return [3 /*break*/, 4]; return [4 /*yield*/, this.integration.invoke.call(this.integration, eventType, event)]; case 3: _c.sent(); _c.label = 4; case 4: return [3 /*break*/, 6]; case 5: err_1 = _c.sent(); (0, metric_helpers_1.recordIntegrationMetric)(ctx, { integrationName: this.name, methodName: eventType, type: 'classic', didError: true, }); throw err_1; case 6: return [2 /*return*/, ctx]; } }); }); }; LegacyDestination.prototype.track = function (ctx) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, this.send(ctx, facade_1.Track, 'track')]; }); }); }; LegacyDestination.prototype.page = function (ctx) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: if (((_a = this.integration) === null || _a === void 0 ? void 0 : _a._assumesPageview) && !this._initialized) { this.integration.initialize(); } return [4 /*yield*/, this.initializePromise.promise]; case 1: _b.sent(); return [2 /*return*/, this.send(ctx, facade_1.Page, 'page')]; } }); }); }; LegacyDestination.prototype.identify = function (ctx) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, this.send(ctx, facade_1.Identify, 'identify')]; }); }); }; LegacyDestination.prototype.alias = function (ctx) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, this.send(ctx, facade_1.Alias, 'alias')]; }); }); }; LegacyDestination.prototype.group = function (ctx) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, this.send(ctx, facade_1.Group, 'group')]; }); }); }; LegacyDestination.prototype.scheduleFlush = function () { var _this = this; if (this.flushing) { return; } // eslint-disable-next-line @typescript-eslint/no-misused-promises setTimeout(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: if ((0, connection_1.isOffline)() || this._ready !== true || this._initialized !== true) { this.scheduleFlush(); return [2 /*return*/]; } this.flushing = true; _a = this; return [4 /*yield*/, flushQueue(this, this.buffer)]; case 1: _a.buffer = _b.sent(); this.flushing = false; if (this.buffer.todo > 0) { this.scheduleFlush(); } return [2 /*return*/]; } }); }); }, Math.random() * 5000); }; return LegacyDestination; }()); exports.LegacyDestination = LegacyDestination; function ajsDestinations(writeKey, settings, integrations, options, routingMiddleware, legacyIntegrationSources) { var _a, _b; if (integrations === void 0) { integrations = {}; } if (options === void 0) { options = {}; } if ((0, environment_1.isServer)()) { return []; } if (settings.plan) { options = options !== null && options !== void 0 ? options : {}; options.plan = settings.plan; } var routingRules = (_b = (_a = settings.middlewareSettings) === null || _a === void 0 ? void 0 : _a.routingRules) !== null && _b !== void 0 ? _b : []; var remoteIntegrationsConfig = settings.integrations; var localIntegrationsConfig = options.integrations; // merged remote CDN settings with user provided options var integrationOptions = (0, merged_options_1.mergedOptions)(settings, options !== null && options !== void 0 ? options : {}); var adhocIntegrationSources = legacyIntegrationSources === null || legacyIntegrationSources === void 0 ? void 0 : legacyIntegrationSources.reduce(function (acc, integrationSource) { var _a; return (tslib_1.__assign(tslib_1.__assign({}, acc), (_a = {}, _a[(0, loader_1.resolveIntegrationNameFromSource)(integrationSource)] = integrationSource, _a))); }, {}); var installableIntegrations = new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], Object.keys(remoteIntegrationsConfig).filter(function (name) { return (0, utils_1.isInstallableIntegration)(name, remoteIntegrationsConfig[name]); }), true), Object.keys(adhocIntegrationSources || {}).filter(function (name) { return (0, analytics_core_2.isPlainObject)(remoteIntegrationsConfig[name]) || (0, analytics_core_2.isPlainObject)(localIntegrationsConfig === null || localIntegrationsConfig === void 0 ? void 0 : localIntegrationsConfig[name]); }), true)); return Array.from(installableIntegrations) .filter(function (name) { return !(0, utils_1.isDisabledIntegration)(name, integrations); }) .map(function (name) { var integrationSettings = remoteIntegrationsConfig[name]; var version = (0, loader_1.resolveVersion)(integrationSettings); var destination = new LegacyDestination(name, version, writeKey, integrationOptions[name], options, adhocIntegrationSources === null || adhocIntegrationSources === void 0 ? void 0 : adhocIntegrationSources[name]); var routing = routingRules.filter(function (rule) { return rule.destinationName === name; }); if (routing.length > 0 && routingMiddleware) { destination.addMiddleware(routingMiddleware); } return destination; }); } exports.ajsDestinations = ajsDestinations; //# sourceMappingURL=index.js.map