posthog-js
Version:
Posthog-js allows you to automatically capture usage and send events to PostHog.
173 lines • 7.7 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupSegmentIntegration = setupSegmentIntegration;
var logger_1 = require("@posthog/browser-common/utils/logger");
var constants_1 = require("../constants");
var core_1 = require("@posthog/core");
var uuidv7_1 = require("@posthog/browser-common/utils/uuidv7");
var logger = (0, logger_1.createLogger)('[SegmentIntegration]');
var isSegmentAnalytics = function (segment) {
return (0, core_1.isFunction)(segment.register);
};
var normalizeSegmentIntegrationConfig = function (segment) {
return isSegmentAnalytics(segment) ? { analytics: segment } : segment;
};
var runSegmentPropertyFilters = function (filters, properties) {
var e_1, _a;
var fns = (0, core_1.isArray)(filters) ? filters : [filters];
var result = __assign({}, properties);
try {
for (var fns_1 = __values(fns), fns_1_1 = fns_1.next(); !fns_1_1.done; fns_1_1 = fns_1.next()) {
var fn = fns_1_1.value;
try {
result = fn(result);
if ((0, core_1.isNullish)(result)) {
return null;
}
}
catch (error) {
logger.error('Error in Segment filterProperties:', error);
return null;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (fns_1_1 && !fns_1_1.done && (_a = fns_1.return)) _a.call(fns_1);
}
finally { if (e_1) throw e_1.error; }
}
return result;
};
var createSegmentIntegration = function (posthog, runtimeAnonymousId, _a) {
var _b = _a === void 0 ? {} : _a, filterProperties = _b.filterProperties;
if (typeof Promise === 'undefined' || !Promise.resolve) {
logger.warn('This browser does not have Promise support, and can not use the segment integration');
}
var enrichEvent = function (ctx, eventName) {
var e_2, _a;
if (!eventName) {
return ctx;
}
var preserveRuntimeAnonymousIdentity = !!runtimeAnonymousId && ctx.event.anonymousId === runtimeAnonymousId && !ctx.event.userId;
if (!preserveRuntimeAnonymousIdentity &&
!ctx.event.userId &&
ctx.event.anonymousId !== posthog.get_distinct_id()) {
// This is our only way of detecting that segment's analytics.reset() has been called so we also call it
logger.info('No userId set, resetting PostHog');
posthog.reset();
}
if (!preserveRuntimeAnonymousIdentity) {
runtimeAnonymousId = undefined;
}
if (ctx.event.userId && ctx.event.userId !== posthog.get_distinct_id()) {
logger.info('UserId set, identifying with PostHog');
posthog.identify(ctx.event.userId);
}
var additionalProperties = posthog.calculateEventProperties(eventName, ctx.event.properties);
if (!(0, core_1.isNullish)(filterProperties)) {
var originalProperties = ctx.event.properties || {};
var enrichmentProperties = {};
try {
for (var _b = __values(Object.keys(additionalProperties)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
if (!core_1.hasOwnProperty.call(originalProperties, key)) {
enrichmentProperties[key] = additionalProperties[key];
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
var filteredProperties = runSegmentPropertyFilters(filterProperties, enrichmentProperties);
if ((0, core_1.isNullish)(filteredProperties)) {
return ctx;
}
additionalProperties = filteredProperties;
}
ctx.event.properties = Object.assign({}, additionalProperties, ctx.event.properties);
return ctx;
};
return {
name: 'PostHog JS',
type: 'enrichment',
version: '1.0.0',
isLoaded: function () { return true; },
// check and early return above
// oxlint-disable-next-line compat/compat
load: function () { return Promise.resolve(); },
track: function (ctx) { return enrichEvent(ctx, ctx.event.event); },
page: function (ctx) { return enrichEvent(ctx, constants_1.EVENT_PAGEVIEW); },
identify: function (ctx) { return enrichEvent(ctx, constants_1.EVENT_IDENTIFY); },
screen: function (ctx) { return enrichEvent(ctx, '$screen'); },
};
};
function setupPostHogFromSegment(posthog, segment, done, bootstrapIdentifiedUser) {
var bootstrapUser = function (user) {
// Use segments anonymousId instead
var getSegmentAnonymousId = function () { return user.anonymousId() || (0, uuidv7_1.uuidv7)(); };
posthog.config.get_device_id = getSegmentAnonymousId;
// During init, adopt an existing Segment user before PostHog starts loading events.
// When Segment is configured later, the enrichment plugin handles the identity transition
// so identify() can merge events captured before Segment was available.
if (bootstrapIdentifiedUser && user.id()) {
posthog.register({
distinct_id: user.id(),
$device_id: getSegmentAnonymousId(),
});
posthog.persistence.set_property(constants_1.USER_STATE, constants_1.USER_STATE_IDENTIFIED);
}
done(bootstrapIdentifiedUser ? undefined : user.anonymousId() || undefined);
};
var segmentUser = segment.user();
if ('then' in segmentUser && (0, core_1.isFunction)(segmentUser.then)) {
segmentUser.then(bootstrapUser);
}
else {
bootstrapUser(segmentUser);
}
}
function setupSegmentIntegration(posthog, done, bootstrapIdentifiedUser) {
if (bootstrapIdentifiedUser === void 0) { bootstrapIdentifiedUser = true; }
var segmentConfig = posthog.config.segment;
if (!segmentConfig) {
return done();
}
var _a = normalizeSegmentIntegrationConfig(segmentConfig), analytics = _a.analytics, filterProperties = _a.filterProperties;
setupPostHogFromSegment(posthog, analytics, function (runtimeAnonymousId) {
analytics.register(createSegmentIntegration(posthog, runtimeAnonymousId, { filterProperties: filterProperties })).then(function () {
done();
}, function (error) {
logger.error('Failed to register the Segment integration', error);
done();
});
}, bootstrapIdentifiedUser);
}
//# sourceMappingURL=segment-integration.js.map