From 837026c146e97a7d4e6779f72571bb427d13056d Mon Sep 17 00:00:00 2001 From: Pranav Date: Fri, 9 Jan 2026 09:32:09 -0800 Subject: [PATCH] feat: Use amplitude for Cloud Analytics (#13217) Migrates our analytics integration on Cloud from PostHog to Amplitude. This change updates the core AnalyticsHelper class to use the Amplitude SDK while maintaining the same tracking interface. Rest of all existing analytics calls throughout the codebase continue to work without modification. **Changes:** - Replace PostHog analytics with Amplitude SDK - Rename ANALYTICS_TOKEN to CLOUD_ANALYTICS_TOKEN for clarity - Fix bug in page() method signature that was causing malformed payloads --- app/controllers/dashboard_controller.rb | 2 +- .../dashboard/helper/AnalyticsHelper/index.js | 41 ++--- .../AnalyticsHelper/specs/helper.spec.js | 86 ++++++----- app/views/layouts/vueapp.html.erb | 4 +- config/installation_config.yml | 4 +- .../super_admin/app_configs_controller.rb | 4 +- package.json | 2 +- pnpm-lock.yaml | 140 +++++++++++++----- 8 files changed, 178 insertions(+), 105 deletions(-) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index abf42517c..d57ad0e53 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -16,7 +16,7 @@ class DashboardController < ActionController::Base CHATWOOT_INBOX_TOKEN API_CHANNEL_NAME API_CHANNEL_THUMBNAIL - ANALYTICS_TOKEN + CLOUD_ANALYTICS_TOKEN DIRECT_UPLOADS_ENABLED MAXIMUM_FILE_UPLOAD_SIZE HCAPTCHA_SITE_KEY diff --git a/app/javascript/dashboard/helper/AnalyticsHelper/index.js b/app/javascript/dashboard/helper/AnalyticsHelper/index.js index ba3b5c7e6..e4392f473 100644 --- a/app/javascript/dashboard/helper/AnalyticsHelper/index.js +++ b/app/javascript/dashboard/helper/AnalyticsHelper/index.js @@ -1,4 +1,4 @@ -import posthog from 'posthog-js'; +import * as amplitude from '@amplitude/analytics-browser'; /** * AnalyticsHelper class to initialize and track user analytics @@ -26,12 +26,10 @@ export class AnalyticsHelper { return; } - posthog.init(this.analyticsToken, { - api_host: 'https://app.posthog.com', - capture_pageview: false, - persistence: 'localStorage+cookie', + amplitude.init(this.analyticsToken, { + defaultTracking: false, }); - this.analytics = posthog; + this.analytics = amplitude; } /** @@ -45,20 +43,26 @@ export class AnalyticsHelper { } this.user = user; - this.analytics.identify(this.user.id.toString(), { - email: this.user.email, - name: this.user.name, - avatar: this.user.avatar_url, - }); + this.analytics.setUserId(`user-${this.user.id.toString()}`); + + const identifyEvent = new amplitude.Identify(); + identifyEvent.set('email', this.user.email); + identifyEvent.set('name', this.user.name); + identifyEvent.set('avatar', this.user.avatar_url); + this.analytics.identify(identifyEvent); const { accounts, account_id: accountId } = this.user; const [currentAccount] = accounts.filter( account => account.id === accountId ); if (currentAccount) { - this.analytics.group('company', currentAccount.id.toString(), { - name: currentAccount.name, - }); + const groupId = `account-${currentAccount.id.toString()}`; + + this.analytics.setGroup('company', groupId); + + const groupIdentify = new amplitude.Identify(); + groupIdentify.set('name', currentAccount.name); + this.analytics.groupIdentify('company', groupId, groupIdentify); } } @@ -72,20 +76,21 @@ export class AnalyticsHelper { if (!this.analytics) { return; } - this.analytics.capture(eventName, properties); + this.analytics.track(eventName, properties); } /** * Track the page views * @function - * @param {Object} params - Page view properties + * @param {string} pageName - Page name + * @param {Object} [properties={}] - Page view properties */ - page(params) { + page(pageName, properties = {}) { if (!this.analytics) { return; } - this.analytics.capture('$pageview', params); + this.analytics.track('$pageview', { pageName, ...properties }); } } diff --git a/app/javascript/dashboard/helper/AnalyticsHelper/specs/helper.spec.js b/app/javascript/dashboard/helper/AnalyticsHelper/specs/helper.spec.js index dacf7a5e0..da8553779 100644 --- a/app/javascript/dashboard/helper/AnalyticsHelper/specs/helper.spec.js +++ b/app/javascript/dashboard/helper/AnalyticsHelper/specs/helper.spec.js @@ -1,12 +1,15 @@ import helperObject, { AnalyticsHelper } from '../'; -vi.mock('posthog-js', () => ({ - default: { - init: vi.fn(), - identify: vi.fn(), - capture: vi.fn(), - group: vi.fn(), - }, +vi.mock('@amplitude/analytics-browser', () => ({ + init: vi.fn(), + setUserId: vi.fn(), + identify: vi.fn(), + setGroup: vi.fn(), + groupIdentify: vi.fn(), + track: vi.fn(), + Identify: vi.fn(() => ({ + set: vi.fn(), + })), })); describe('helperObject', () => { @@ -22,12 +25,12 @@ describe('AnalyticsHelper', () => { }); describe('init', () => { - it('should initialize posthog with the correct token', async () => { + it('should initialize amplitude with the correct token', async () => { await analyticsHelper.init(); expect(analyticsHelper.analytics).not.toBe(null); }); - it('should not initialize posthog if token is not provided', async () => { + it('should not initialize amplitude if token is not provided', async () => { analyticsHelper = new AnalyticsHelper(); await analyticsHelper.init(); expect(analyticsHelper.analytics).toBe(null); @@ -36,10 +39,15 @@ describe('AnalyticsHelper', () => { describe('identify', () => { beforeEach(() => { - analyticsHelper.analytics = { identify: vi.fn(), group: vi.fn() }; + analyticsHelper.analytics = { + setUserId: vi.fn(), + identify: vi.fn(), + setGroup: vi.fn(), + groupIdentify: vi.fn(), + }; }); - it('should call identify on posthog with correct arguments', () => { + it('should call setUserId and identify on amplitude with correct arguments', () => { analyticsHelper.identify({ id: 123, email: 'test@example.com', @@ -49,19 +57,18 @@ describe('AnalyticsHelper', () => { account_id: 1, }); - expect(analyticsHelper.analytics.identify).toHaveBeenCalledWith('123', { - email: 'test@example.com', - name: 'Test User', - avatar: 'avatar_url', - }); - expect(analyticsHelper.analytics.group).toHaveBeenCalledWith( - 'company', - '1', - { name: 'Account 1' } + expect(analyticsHelper.analytics.setUserId).toHaveBeenCalledWith( + 'user-123' ); + expect(analyticsHelper.analytics.identify).toHaveBeenCalled(); + expect(analyticsHelper.analytics.setGroup).toHaveBeenCalledWith( + 'company', + 'account-1' + ); + expect(analyticsHelper.analytics.groupIdentify).toHaveBeenCalled(); }); - it('should call identify on posthog without group', () => { + it('should call identify on amplitude without group', () => { analyticsHelper.identify({ id: 123, email: 'test@example.com', @@ -71,10 +78,10 @@ describe('AnalyticsHelper', () => { account_id: 5, }); - expect(analyticsHelper.analytics.group).not.toHaveBeenCalled(); + expect(analyticsHelper.analytics.setGroup).not.toHaveBeenCalled(); }); - it('should not call analytics.page if analytics is null', () => { + it('should not call analytics methods if analytics is null', () => { analyticsHelper.analytics = null; analyticsHelper.identify({}); expect(analyticsHelper.analytics).toBe(null); @@ -83,27 +90,27 @@ describe('AnalyticsHelper', () => { describe('track', () => { beforeEach(() => { - analyticsHelper.analytics = { capture: vi.fn() }; + analyticsHelper.analytics = { track: vi.fn() }; analyticsHelper.user = { id: 123 }; }); - it('should call capture on posthog with correct arguments', () => { + it('should call track on amplitude with correct arguments', () => { analyticsHelper.track('Test Event', { prop1: 'value1', prop2: 'value2' }); - expect(analyticsHelper.analytics.capture).toHaveBeenCalledWith( + expect(analyticsHelper.analytics.track).toHaveBeenCalledWith( 'Test Event', { prop1: 'value1', prop2: 'value2' } ); }); - it('should call capture on posthog with default properties', () => { + it('should call track on amplitude with default properties', () => { analyticsHelper.track('Test Event'); - expect(analyticsHelper.analytics.capture).toHaveBeenCalledWith( + expect(analyticsHelper.analytics.track).toHaveBeenCalledWith( 'Test Event', {} ); }); - it('should not call capture on posthog if analytics is not initialized', () => { + it('should not call track on amplitude if analytics is not initialized', () => { analyticsHelper.analytics = null; analyticsHelper.track('Test Event', { prop1: 'value1', prop2: 'value2' }); expect(analyticsHelper.analytics).toBe(null); @@ -112,24 +119,25 @@ describe('AnalyticsHelper', () => { describe('page', () => { beforeEach(() => { - analyticsHelper.analytics = { capture: vi.fn() }; + analyticsHelper.analytics = { track: vi.fn() }; }); - it('should call the capture method for pageview with the correct arguments', () => { - const params = { - name: 'Test page', - url: '/test', + it('should call the track method for pageview with the correct arguments', () => { + const pageName = 'home'; + const properties = { + path: '/test', + name: 'home', }; - analyticsHelper.page(params); - expect(analyticsHelper.analytics.capture).toHaveBeenCalledWith( + analyticsHelper.page(pageName, properties); + expect(analyticsHelper.analytics.track).toHaveBeenCalledWith( '$pageview', - params + { pageName: 'home', path: '/test', name: 'home' } ); }); - it('should not call analytics.capture if analytics is null', () => { + it('should not call analytics.track if analytics is null', () => { analyticsHelper.analytics = null; - analyticsHelper.page(); + analyticsHelper.page('home'); expect(analyticsHelper.analytics).toBe(null); }); }); diff --git a/app/views/layouts/vueapp.html.erb b/app/views/layouts/vueapp.html.erb index 6cb238c6e..d97ece981 100644 --- a/app/views/layouts/vueapp.html.erb +++ b/app/views/layouts/vueapp.html.erb @@ -63,10 +63,10 @@ } window.errorLoggingConfig = '<%= ENV.fetch('SENTRY_FRONTEND_DSN', '') || ENV.fetch('SENTRY_DSN', '') %>' - <% if @global_config['ANALYTICS_TOKEN'].present? %> + <% if @global_config['CLOUD_ANALYTICS_TOKEN'].present? %> <% end %> diff --git a/config/installation_config.yml b/config/installation_config.yml index 8581deb97..567da8a59 100644 --- a/config/installation_config.yml +++ b/config/installation_config.yml @@ -225,10 +225,10 @@ - name: DEPLOYMENT_ENV value: self-hosted description: 'The deployment environment of the installation, to differentiate between Chatwoot cloud and self-hosted' -- name: ANALYTICS_TOKEN +- name: CLOUD_ANALYTICS_TOKEN value: display_title: 'Analytics Token' - description: 'The PostHog analytics token for Chatwoot cloud' + description: 'The Amplitude analytics API key for Chatwoot cloud' type: secret - name: CLEARBIT_API_KEY value: diff --git a/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb b/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb index 0ed7ee67a..87ac8f6d6 100644 --- a/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb +++ b/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb @@ -34,9 +34,9 @@ module Enterprise::SuperAdmin::AppConfigsController end def internal_config_options - %w[CHATWOOT_INBOX_TOKEN CHATWOOT_INBOX_HMAC_KEY ANALYTICS_TOKEN CLEARBIT_API_KEY DASHBOARD_SCRIPTS INACTIVE_WHATSAPP_NUMBERS BLOCKED_EMAIL_DOMAINS + %w[CHATWOOT_INBOX_TOKEN CHATWOOT_INBOX_HMAC_KEY CLOUD_ANALYTICS_TOKEN CLEARBIT_API_KEY DASHBOARD_SCRIPTS INACTIVE_WHATSAPP_NUMBERS SKIP_INCOMING_BCC_PROCESSING CAPTAIN_CLOUD_PLAN_LIMITS ACCOUNT_SECURITY_NOTIFICATION_WEBHOOK_URL CHATWOOT_INSTANCE_ADMIN_EMAIL - OG_IMAGE_CDN_URL OG_IMAGE_CLIENT_REF CLOUDFLARE_API_KEY CLOUDFLARE_ZONE_ID + OG_IMAGE_CDN_URL OG_IMAGE_CLIENT_REF CLOUDFLARE_API_KEY CLOUDFLARE_ZONE_ID BLOCKED_EMAIL_DOMAINS OTEL_PROVIDER LANGFUSE_PUBLIC_KEY LANGFUSE_SECRET_KEY LANGFUSE_BASE_URL] end diff --git a/package.json b/package.json index 1ba064450..6d5a37b5a 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "mitt": "^3.0.1", "opus-recorder": "^8.0.5", "pinia": "^3.0.4", - "posthog-js": "^1.260.2", + "@amplitude/analytics-browser": "^2.11.10", "qrcode": "^1.5.4", "semver": "7.6.3", "snakecase-keys": "^8.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 56a7d910f..26bd3141e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,9 @@ importers: .: dependencies: + '@amplitude/analytics-browser': + specifier: ^2.11.10 + version: 2.33.1 '@breezystack/lamejs': specifier: ^1.2.7 version: 1.2.7 @@ -169,9 +172,6 @@ importers: pinia: specifier: ^3.0.4 version: 3.0.4(typescript@5.6.2)(vue@3.5.12(typescript@5.6.2)) - posthog-js: - specifier: ^1.260.2 - version: 1.260.3 qrcode: specifier: ^1.5.4 version: 1.5.4 @@ -371,6 +371,30 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@amplitude/analytics-browser@2.33.1': + resolution: {integrity: sha512-93wZjuAFJ7QdyptF82i1pezm5jKuBWITHI++XshDgpks1RstJvJ9n11Ak8MnE4L2BGQ93XDN2aVEHfmQkt0/Pw==} + + '@amplitude/analytics-connector@1.6.4': + resolution: {integrity: sha512-SpIv0IQMNIq6SH3UqFGiaZyGSc7PBZwRdq7lvP0pBxW8i4Ny+8zwI0pV+VMfMHQwWY3wdIbWw5WQphNjpdq1/Q==} + + '@amplitude/analytics-core@2.35.0': + resolution: {integrity: sha512-7RmHYELXCGu8yuO9D6lEXiqkMtiC5sePNhCWmwuP30dneDYHtH06gaYvAFH/YqOFuE6enwEEJfFYtcaPhyiqtA==} + + '@amplitude/plugin-autocapture-browser@1.18.3': + resolution: {integrity: sha512-njYque5t1QCEEe5V8Ls4yVVklTM6V7OXxBk6pqznN/hj/Pc4X8Wjy898pZ2VtbnvpagBKKzGb5B6Syl8OXiicw==} + + '@amplitude/plugin-network-capture-browser@1.7.3': + resolution: {integrity: sha512-zfWgAN7g6AigJAsgrGmlgVwydOHH6XvweBoxhU+qEvRydboiIVCDLSxuXczUsBG7kYVLWRdBK1DYoE5J7lqTGA==} + + '@amplitude/plugin-page-url-enrichment-browser@0.5.9': + resolution: {integrity: sha512-TqdELx4WrdRutCjHUFUzum/f/UjhbdTZw0UKkYFAj5gwAKDjaPEjL4waRvINOTaVLsne1A6ck4KEMfC8AKByFw==} + + '@amplitude/plugin-page-view-tracking-browser@2.6.6': + resolution: {integrity: sha512-dBcJlrdKgPzSgS3exDRRrMLqhIaOjwlIy7o8sEMn1PpMawERlbumSSdtfII6L4L67HYUPo4PY4Kp4acqSzaLvQ==} + + '@amplitude/plugin-web-vitals-browser@1.1.4': + resolution: {integrity: sha512-XQXI9OjTNSz2yi0lXw2VYMensDzzSkMCfvXNniTb1LgnHwBcQ1JWPcTqHLPFrvvNckeIdOT78vjs7yA+c1FyzA==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -1091,9 +1115,6 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - '@posthog/core@1.0.1': - resolution: {integrity: sha512-bwXUeHe+MLgENm8+/FxEbiNocOw1Vjewmm+HEUaYQe6frq8OhZnrvtnzZU3Q3DF6N0UbAmD/q+iNfNgyx8mozg==} - '@radix-ui/colors@3.0.0': resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==} @@ -1326,6 +1347,9 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@types/zen-observable@0.8.3': + resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==} + '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} @@ -2450,9 +2474,6 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - fflate@0.4.8: - resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} - file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3791,20 +3812,6 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - posthog-js@1.260.3: - resolution: {integrity: sha512-FCtksk0GQn22Rk9P7x7dsmAO7a2aBxPeYb2O2KXSraxR8xd2G6lUOOthVDK+qgtmuhpUZuur/mHrXEslMUEtjg==} - peerDependencies: - '@rrweb/types': 2.0.0-alpha.17 - rrweb-snapshot: 2.0.0-alpha.17 - peerDependenciesMeta: - '@rrweb/types': - optional: true - rrweb-snapshot: - optional: true - - preact@10.27.1: - resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==} - prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -3979,6 +3986,9 @@ packages: rust-result@1.0.0: resolution: {integrity: sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -4665,8 +4675,8 @@ packages: wavesurfer.js@7.8.6: resolution: {integrity: sha512-EDexkMwkkQBTWruhfWQRkTtvRggtKFTPuJX/oZ5wbIZEfyww9EBeLr2mtkxzA1S8TlWPx6adY5WyjOlNYNyHSg==} - web-vitals@4.2.4: - resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} + web-vitals@5.1.0: + resolution: {integrity: sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==} webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} @@ -4834,6 +4844,12 @@ packages: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} + zen-observable-ts@1.1.0: + resolution: {integrity: sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==} + + zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + snapshots: '@aashutoshrathi/word-wrap@1.2.6': {} @@ -4844,6 +4860,51 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@amplitude/analytics-browser@2.33.1': + dependencies: + '@amplitude/analytics-core': 2.35.0 + '@amplitude/plugin-autocapture-browser': 1.18.3 + '@amplitude/plugin-network-capture-browser': 1.7.3 + '@amplitude/plugin-page-url-enrichment-browser': 0.5.9 + '@amplitude/plugin-page-view-tracking-browser': 2.6.6 + '@amplitude/plugin-web-vitals-browser': 1.1.4 + tslib: 2.8.1 + + '@amplitude/analytics-connector@1.6.4': {} + + '@amplitude/analytics-core@2.35.0': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + tslib: 2.8.1 + zen-observable-ts: 1.1.0 + + '@amplitude/plugin-autocapture-browser@1.18.3': + dependencies: + '@amplitude/analytics-core': 2.35.0 + rxjs: 7.8.2 + tslib: 2.8.1 + + '@amplitude/plugin-network-capture-browser@1.7.3': + dependencies: + '@amplitude/analytics-core': 2.35.0 + tslib: 2.8.1 + + '@amplitude/plugin-page-url-enrichment-browser@0.5.9': + dependencies: + '@amplitude/analytics-core': 2.35.0 + tslib: 2.8.1 + + '@amplitude/plugin-page-view-tracking-browser@2.6.6': + dependencies: + '@amplitude/analytics-core': 2.35.0 + tslib: 2.8.1 + + '@amplitude/plugin-web-vitals-browser@1.1.4': + dependencies: + '@amplitude/analytics-core': 2.35.0 + tslib: 2.8.1 + web-vitals: 5.1.0 + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -5626,8 +5687,6 @@ snapshots: '@polka/url@1.0.0-next.28': {} - '@posthog/core@1.0.1': {} - '@radix-ui/colors@3.0.0': {} '@rails/actioncable@6.1.3': {} @@ -5810,6 +5869,8 @@ snapshots: '@types/web-bluetooth@0.0.20': {} + '@types/zen-observable@0.8.3': {} + '@ungap/structured-clone@1.2.0': {} '@videojs/http-streaming@2.13.1(video.js@7.18.1)': @@ -7202,8 +7263,6 @@ snapshots: dependencies: reusify: 1.0.4 - fflate@0.4.8: {} - file-entry-cache@6.0.1: dependencies: flat-cache: 3.1.0 @@ -8671,16 +8730,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - posthog-js@1.260.3: - dependencies: - '@posthog/core': 1.0.1 - core-js: 3.38.1 - fflate: 0.4.8 - preact: 10.27.1 - web-vitals: 4.2.4 - - preact@10.27.1: {} - prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -8895,6 +8944,10 @@ snapshots: dependencies: individual: 2.0.0 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + sade@1.8.1: dependencies: mri: 1.2.0 @@ -9667,7 +9720,7 @@ snapshots: wavesurfer.js@7.8.6: {} - web-vitals@4.2.4: {} + web-vitals@5.1.0: {} webidl-conversions@7.0.0: {} @@ -9824,3 +9877,10 @@ snapshots: yocto-queue@0.1.0: {} yocto-queue@1.1.1: {} + + zen-observable-ts@1.1.0: + dependencies: + '@types/zen-observable': 0.8.3 + zen-observable: 0.8.15 + + zen-observable@0.8.15: {}