From 6b95723f1ce6a3f4420ae069a917c4e86a99fdbf Mon Sep 17 00:00:00 2001 From: CodingOnStar Date: Mon, 17 Nov 2025 14:06:50 +0800 Subject: [PATCH] feat: integrate Amplitude analytics for event tracking - Added AmplitudeProvider component to initialize Amplitude analytics. - Updated layout components to include AmplitudeProvider for tracking. - Introduced utility functions for tracking events, setting user ID, and managing user properties. - Updated package.json and pnpm-lock.yaml to include @amplitude/analytics-browser dependency. --- web/app/(commonLayout)/layout.tsx | 2 + web/app/account/(commonLayout)/layout.tsx | 2 + .../amplitude/AmplitudeProvider.tsx | 42 +++ web/app/components/amplitude/index.ts | 2 + web/app/components/amplitude/utils.ts | 37 ++ web/package.json | 2 + web/pnpm-lock.yaml | 327 ++++++++++++++++++ 7 files changed, 414 insertions(+) create mode 100644 web/app/components/amplitude/AmplitudeProvider.tsx create mode 100644 web/app/components/amplitude/index.ts create mode 100644 web/app/components/amplitude/utils.ts diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx index 7f6bbb1f52..d0587e23f8 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -3,6 +3,7 @@ import type { ReactNode } from 'react' import SwrInitializer from '@/app/components/swr-initializer' import { AppContextProvider } from '@/context/app-context' import GA, { GaType } from '@/app/components/base/ga' +import AmplitudeProvider from '@/app/components/amplitude' import HeaderWrapper from '@/app/components/header/header-wrapper' import Header from '@/app/components/header' import { EventEmitterContextProvider } from '@/context/event-emitter' @@ -17,6 +18,7 @@ const Layout = ({ children }: { children: ReactNode }) => { return ( <> + diff --git a/web/app/account/(commonLayout)/layout.tsx b/web/app/account/(commonLayout)/layout.tsx index b3225b5341..3dc29f56c3 100644 --- a/web/app/account/(commonLayout)/layout.tsx +++ b/web/app/account/(commonLayout)/layout.tsx @@ -4,6 +4,7 @@ import Header from './header' import SwrInitor from '@/app/components/swr-initializer' import { AppContextProvider } from '@/context/app-context' import GA, { GaType } from '@/app/components/base/ga' +import AmplitudeProvider from '@/app/components/amplitude' import HeaderWrapper from '@/app/components/header/header-wrapper' import { EventEmitterContextProvider } from '@/context/event-emitter' import { ProviderContextProvider } from '@/context/provider-context' @@ -13,6 +14,7 @@ const Layout = ({ children }: { children: ReactNode }) => { return ( <> + diff --git a/web/app/components/amplitude/AmplitudeProvider.tsx b/web/app/components/amplitude/AmplitudeProvider.tsx new file mode 100644 index 0000000000..f32ff3c3e8 --- /dev/null +++ b/web/app/components/amplitude/AmplitudeProvider.tsx @@ -0,0 +1,42 @@ +'use client' + +import type { FC } from 'react' +import React, { useEffect } from 'react' +import * as amplitude from '@amplitude/analytics-browser' +import { sessionReplayPlugin } from '@amplitude/plugin-session-replay-browser' + +export type IAmplitudeProps = { + apiKey?: string +} + +const AmplitudeProvider: FC = ({ + apiKey = '702e89332ab88a7f14e665f417244e9d', +}) => { + useEffect(() => { + // // Only enable in non-CE edition + // if (IS_CE_EDITION) { + // console.warn('[Amplitude] Amplitude is disabled in CE edition') + // return + // } + + const sessionReplay = sessionReplayPlugin({ + sampleRate: 0.1, + }) + + amplitude.add(sessionReplay) + + amplitude.init(apiKey, { + defaultTracking: { + sessions: true, + pageViews: true, + formInteractions: true, + fileDownloads: true, + }, + logLevel: amplitude.Types.LogLevel.Warn, + }) + }, [apiKey]) + + return null +} + +export default React.memo(AmplitudeProvider) diff --git a/web/app/components/amplitude/index.ts b/web/app/components/amplitude/index.ts new file mode 100644 index 0000000000..e447a0c5e3 --- /dev/null +++ b/web/app/components/amplitude/index.ts @@ -0,0 +1,2 @@ +export { default } from './AmplitudeProvider' +export { resetUser, setUserId, setUserProperties, trackEvent } from './utils' diff --git a/web/app/components/amplitude/utils.ts b/web/app/components/amplitude/utils.ts new file mode 100644 index 0000000000..8423c43bb2 --- /dev/null +++ b/web/app/components/amplitude/utils.ts @@ -0,0 +1,37 @@ +import * as amplitude from '@amplitude/analytics-browser' + +/** + * Track custom event + * @param eventName Event name + * @param eventProperties Event properties (optional) + */ +export const trackEvent = (eventName: string, eventProperties?: Record) => { + amplitude.track(eventName, eventProperties) +} + +/** + * Set user ID + * @param userId User ID + */ +export const setUserId = (userId: string) => { + amplitude.setUserId(userId) +} + +/** + * Set user properties + * @param properties User properties + */ +export const setUserProperties = (properties: Record) => { + const identifyEvent = new amplitude.Identify() + Object.entries(properties).forEach(([key, value]) => { + identifyEvent.set(key, value) + }) + amplitude.identify(identifyEvent) +} + +/** + * Reset user (e.g., when user logs out) + */ +export const resetUser = () => { + amplitude.reset() +} diff --git a/web/package.json b/web/package.json index d10359f25d..438c5d0f1a 100644 --- a/web/package.json +++ b/web/package.json @@ -44,6 +44,8 @@ "knip": "knip" }, "dependencies": { + "@amplitude/analytics-browser": "^2.30.1", + "@amplitude/plugin-session-replay-browser": "^1.23.2", "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.26.28", "@formatjs/intl-localematcher": "^0.5.10", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 8e638ed2df..0711a6bdac 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -60,6 +60,12 @@ importers: .: dependencies: + '@amplitude/analytics-browser': + specifier: ^2.30.1 + version: 2.30.1 + '@amplitude/plugin-session-replay-browser': + specifier: ^1.23.2 + version: 1.23.2(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2) '@emoji-mart/data': specifier: ^1.2.1 version: 1.2.1 @@ -536,6 +542,83 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@amplitude/analytics-browser@2.30.1': + resolution: {integrity: sha512-uNCYjOdwBKXKPXlH1t2HayMRpzQ64hF8cIq78Y42/cAq+3Zhz4Hxy4IKmu9Sx+cC7p3QpToXjnhozQdnnjEeYg==} + + '@amplitude/analytics-client-common@2.4.12': + resolution: {integrity: sha512-mK7vph3cSMKfy59gkSwo/M5OMvHjP62qK0CIfJPJF4U0n7EyWaKgzfE4aBV98IjKQkglkfmhd7hn1es8MsLVMw==} + + '@amplitude/analytics-connector@1.6.4': + resolution: {integrity: sha512-SpIv0IQMNIq6SH3UqFGiaZyGSc7PBZwRdq7lvP0pBxW8i4Ny+8zwI0pV+VMfMHQwWY3wdIbWw5WQphNjpdq1/Q==} + + '@amplitude/analytics-core@2.31.1': + resolution: {integrity: sha512-ynk7l24be7L/E6m/XDq0gZdwAKmmS3fE+5BLFF+usljFlWvUY59qFjAZbv6DkaMQA6IGDm9ocgg4VnlNxdX6bA==} + + '@amplitude/analytics-core@2.32.0-zen-observable-migration.0': + resolution: {integrity: sha512-L1nF+2TWHXDVDK6F+t6DbIPxlIgCwtP/y7DtP3npTwep+HMrQZUp7P8Tc4/EO3VRBdiqXeeo5s/AT/+JRawqnw==} + + '@amplitude/analytics-types@2.11.0': + resolution: {integrity: sha512-L1niBXYSWmbyHUE/GNuf6YBljbafaxWI3X5jjEIZDFCjQvdWO3DKalY1VPFUbhgYQgWw7+bC6I/AlUaporyfig==} + + '@amplitude/experiment-core@0.7.2': + resolution: {integrity: sha512-Wc2NWvgQ+bLJLeF0A9wBSPIaw0XuqqgkPKsoNFQrmS7r5Djd56um75In05tqmVntPJZRvGKU46pAp8o5tdf4mA==} + + '@amplitude/plugin-autocapture-browser@1.17.1': + resolution: {integrity: sha512-KuWQbyo+DUH1Z066ubhLzH3r8R/r0e0SU8ecPF0oPhvD19VH0uYQ/nt+S+0lMvkivy5GLPyjkBAzCHhjbM0TFQ==} + + '@amplitude/plugin-network-capture-browser@1.6.13': + resolution: {integrity: sha512-tf8/UQnEeT1Y7SCXLTQAeX+8/taV7gXW7Z4f5Dk1m9FKq34mn2hh9k3es+3SVmd7FS2D+nixnlaEvUX2TSLr3A==} + + '@amplitude/plugin-page-url-enrichment-browser@0.5.2': + resolution: {integrity: sha512-jofoyuZ2Ye7KjQQCnjL6L1u+QcvGB2GJMhDoNS6Nkb1jg7JdSxpD+8qvjSIFo727UXmbqEGFuZ68i6PnzIzsHQ==} + + '@amplitude/plugin-page-view-tracking-browser@2.5.7': + resolution: {integrity: sha512-CW9gtVBH6n74vqSXa4gTmAL8NuNDYoLHXLY2j+qn1noP7QUBk1BD1TTCuSWqB6CMkTzBLF1zSjnE0MgPoTe8yA==} + + '@amplitude/plugin-session-replay-browser@1.23.2': + resolution: {integrity: sha512-wBceE9KqOhkYMiyrK9iDChXAOFvBNswy2wPOyguzWB3Iq+i3185Dz2/SPtoGJ+BOJFiT8totlj/luPjJKA74VQ==} + + '@amplitude/plugin-web-vitals-browser@0.1.0-zen-observable-migration.0': + resolution: {integrity: sha512-R0kdIK/PCXake5TqWp/Fv6/qut/9a6cz1jJrsqe0G/AoE6BhEiFgaBjDZo+6y3ejIXw1gTK0AVl5VprO3IrcfA==} + + '@amplitude/rrdom@2.0.0-alpha.33': + resolution: {integrity: sha512-uu+1w1RGEJ7QcGPwCC898YBR47DpNYOZTnQMY9/IgMzTXQ0+Hh1/JLsQfMnBBtAePhvCS0BlHd/qGD5w0taIcg==} + + '@amplitude/rrweb-packer@2.0.0-alpha.32': + resolution: {integrity: sha512-vYT0JFzle/FV9jIpEbuumCLh516az6ltAo7mrd06dlGo1tgos7bJbl3kcnvEXmDG7WWsKwip/Qprap7cZ4CmJw==} + + '@amplitude/rrweb-plugin-console-record@2.0.0-alpha.32': + resolution: {integrity: sha512-oJuBSNuBnqnrRCneW3b/pMirSz0Ubr2Ebz/t+zJhkGBgrTPNMviv8sSyyGuSn0kL4RAh/9QAG1H1hiYf9cuzgA==} + peerDependencies: + '@amplitude/rrweb': ^2.0.0-alpha.32 + + '@amplitude/rrweb-record@2.0.0-alpha.32': + resolution: {integrity: sha512-bs5ItsPfedVNiZyIzYgtey6S6qaU90XcP4/313dcvedzBk9o+eVjBG5DDbStJnwYnSj+lB+oAWw5uc9H9ghKjQ==} + + '@amplitude/rrweb-snapshot@2.0.0-alpha.33': + resolution: {integrity: sha512-06CgbRFS+cYDo1tUa+Fe8eo4QA9qmYv9Azio3UYlYxqJf4BtAYSL0eXuzVBuqt3ZXnQwzBlsUj/8QWKKySkO7A==} + + '@amplitude/rrweb-types@2.0.0-alpha.32': + resolution: {integrity: sha512-tDs8uizkG+UwE2GKjXh+gH8WhUz0C3y7WfTwrtWi1TnsVc00sXaKSUo5G2h4YF4PGK6dpnLgJBqTwrqCZ211AQ==} + + '@amplitude/rrweb-types@2.0.0-alpha.33': + resolution: {integrity: sha512-OTUqndbcuXDZczf99NUq2PqQWTZ4JHK7oF8YT7aOXh1pJVEWhfe6S+J0idHd3YFCy1TD9gtOcdnz5nDJN68Wnw==} + + '@amplitude/rrweb-utils@2.0.0-alpha.32': + resolution: {integrity: sha512-DCCQjuNACkIMkdY5/KBaEgL4znRHU694ClW3RIjqFXJ6j6pqGyjEhCqtlCes+XwdgwOQKnJGMNka3J9rmrSqHg==} + + '@amplitude/rrweb-utils@2.0.0-alpha.33': + resolution: {integrity: sha512-brK6csN0Tj1W5gYERFhamWEPeFLbz9nYokdaUtd8PL/Y0owWXNX11KGP4pMWvl/f1bElDU0vcu3uYAzM4YGLQw==} + + '@amplitude/rrweb@2.0.0-alpha.33': + resolution: {integrity: sha512-vMuk/3HzDWaUzBLFxKd7IpA8TEWjyPZBuLiLexMd/mOfTt/+JkVLsfXiJOyltJfR98LpmMTp1q51dtq357Dnfg==} + + '@amplitude/session-replay-browser@1.29.4': + resolution: {integrity: sha512-GZ3DWKPbWAltPnjE9PVRLsfXYdCDlnt4+4rpKcdzJ7XVBJZ4oNbh4lhLSa2w1CLgKPE9OVrqEY8jqiSpYXPaOw==} + + '@amplitude/targeting@0.2.0': + resolution: {integrity: sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==} + '@antfu/eslint-config@5.4.1': resolution: {integrity: sha512-x7BiNkxJRlXXs8tIvg0CgMuNo5IZVWkGLMJotCtCtzWUHW78Pmm8PvtXhvLBbTc8683GGBK616MMztWLh4RNjA==} hasBin: true @@ -2789,12 +2872,30 @@ packages: peerDependencies: rollup: ^1.20.0 || ^2.0.0 + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/pluginutils@3.1.0': resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0 + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@sentry-internal/browser-utils@8.55.0': resolution: {integrity: sha512-ROgqtQfpH/82AQIpESPqPQe0UyWywKJsmVIqi3c5Fh+zkds5LUxnssTj3yNd1x+kxaPDVB023jAP+3ibNgeNDw==} engines: {node: '>=14.18'} @@ -3087,6 +3188,9 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/css-font-loading-module@0.0.7': + resolution: {integrity: sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==} + '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} @@ -3342,6 +3446,9 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@types/zen-observable@0.8.3': + resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==} + '@typescript-eslint/eslint-plugin@8.46.2': resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3500,6 +3607,9 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + '@xstate/fsm@1.6.5': + resolution: {integrity: sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==} + '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -3752,6 +3862,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-arraybuffer@1.0.2: + resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} + engines: {node: '>= 0.6.0'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5108,6 +5222,9 @@ packages: picomatch: optional: true + fflate@0.4.8: + resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -5477,9 +5594,15 @@ packages: peerDependencies: postcss: ^8.1.0 + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + idb@7.1.1: resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + idb@8.0.0: + resolution: {integrity: sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -5853,6 +5976,9 @@ packages: js-audio-recorder@1.0.7: resolution: {integrity: sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==} + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-cookie@3.0.5: resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} engines: {node: '>=14'} @@ -7393,6 +7519,9 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -8196,6 +8325,9 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-vitals@5.1.0: + resolution: {integrity: sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==} + webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} @@ -8404,6 +8536,12 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} 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==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8442,6 +8580,151 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@amplitude/analytics-browser@2.30.1': + dependencies: + '@amplitude/analytics-core': 2.31.1 + '@amplitude/plugin-autocapture-browser': 1.17.1 + '@amplitude/plugin-network-capture-browser': 1.6.13 + '@amplitude/plugin-page-url-enrichment-browser': 0.5.2 + '@amplitude/plugin-page-view-tracking-browser': 2.5.7 + '@amplitude/plugin-web-vitals-browser': 0.1.0-zen-observable-migration.0 + tslib: 2.8.1 + + '@amplitude/analytics-client-common@2.4.12': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + '@amplitude/analytics-core': 2.31.1 + '@amplitude/analytics-types': 2.11.0 + tslib: 2.8.1 + + '@amplitude/analytics-connector@1.6.4': {} + + '@amplitude/analytics-core@2.31.1': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + tslib: 2.8.1 + + '@amplitude/analytics-core@2.32.0-zen-observable-migration.0': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + tslib: 2.8.1 + zen-observable-ts: 1.1.0 + + '@amplitude/analytics-types@2.11.0': {} + + '@amplitude/experiment-core@0.7.2': + dependencies: + js-base64: 3.7.8 + + '@amplitude/plugin-autocapture-browser@1.17.1': + dependencies: + '@amplitude/analytics-core': 2.31.1 + rxjs: 7.8.2 + tslib: 2.8.1 + + '@amplitude/plugin-network-capture-browser@1.6.13': + dependencies: + '@amplitude/analytics-core': 2.31.1 + rxjs: 7.8.2 + tslib: 2.8.1 + + '@amplitude/plugin-page-url-enrichment-browser@0.5.2': + dependencies: + '@amplitude/analytics-core': 2.31.1 + tslib: 2.8.1 + + '@amplitude/plugin-page-view-tracking-browser@2.5.7': + dependencies: + '@amplitude/analytics-core': 2.31.1 + tslib: 2.8.1 + + '@amplitude/plugin-session-replay-browser@1.23.2(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)': + dependencies: + '@amplitude/analytics-client-common': 2.4.12 + '@amplitude/analytics-core': 2.31.1 + '@amplitude/analytics-types': 2.11.0 + '@amplitude/session-replay-browser': 1.29.4(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2) + idb-keyval: 6.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@amplitude/rrweb' + - rollup + + '@amplitude/plugin-web-vitals-browser@0.1.0-zen-observable-migration.0': + dependencies: + '@amplitude/analytics-core': 2.32.0-zen-observable-migration.0 + rxjs: 7.8.2 + tslib: 2.8.1 + web-vitals: 5.1.0 + + '@amplitude/rrdom@2.0.0-alpha.33': + dependencies: + '@amplitude/rrweb-snapshot': 2.0.0-alpha.33 + + '@amplitude/rrweb-packer@2.0.0-alpha.32': + dependencies: + '@amplitude/rrweb-types': 2.0.0-alpha.32 + fflate: 0.4.8 + + '@amplitude/rrweb-plugin-console-record@2.0.0-alpha.32(@amplitude/rrweb@2.0.0-alpha.33)': + dependencies: + '@amplitude/rrweb': 2.0.0-alpha.33 + + '@amplitude/rrweb-record@2.0.0-alpha.32': + dependencies: + '@amplitude/rrweb': 2.0.0-alpha.33 + '@amplitude/rrweb-types': 2.0.0-alpha.32 + + '@amplitude/rrweb-snapshot@2.0.0-alpha.33': + dependencies: + postcss: 8.5.6 + + '@amplitude/rrweb-types@2.0.0-alpha.32': {} + + '@amplitude/rrweb-types@2.0.0-alpha.33': {} + + '@amplitude/rrweb-utils@2.0.0-alpha.32': {} + + '@amplitude/rrweb-utils@2.0.0-alpha.33': {} + + '@amplitude/rrweb@2.0.0-alpha.33': + dependencies: + '@amplitude/rrdom': 2.0.0-alpha.33 + '@amplitude/rrweb-snapshot': 2.0.0-alpha.33 + '@amplitude/rrweb-types': 2.0.0-alpha.33 + '@amplitude/rrweb-utils': 2.0.0-alpha.33 + '@types/css-font-loading-module': 0.0.7 + '@xstate/fsm': 1.6.5 + base64-arraybuffer: 1.0.2 + mitt: 3.0.1 + + '@amplitude/session-replay-browser@1.29.4(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)': + dependencies: + '@amplitude/analytics-client-common': 2.4.12 + '@amplitude/analytics-core': 2.31.1 + '@amplitude/analytics-types': 2.11.0 + '@amplitude/rrweb-packer': 2.0.0-alpha.32 + '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.32(@amplitude/rrweb@2.0.0-alpha.33) + '@amplitude/rrweb-record': 2.0.0-alpha.32 + '@amplitude/rrweb-types': 2.0.0-alpha.32 + '@amplitude/rrweb-utils': 2.0.0-alpha.32 + '@amplitude/targeting': 0.2.0 + '@rollup/plugin-replace': 6.0.3(rollup@2.79.2) + idb: 8.0.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@amplitude/rrweb' + - rollup + + '@amplitude/targeting@0.2.0': + dependencies: + '@amplitude/analytics-client-common': 2.4.12 + '@amplitude/analytics-core': 2.31.1 + '@amplitude/analytics-types': 2.11.0 + '@amplitude/experiment-core': 0.7.2 + idb: 8.0.0 + tslib: 2.8.1 + '@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.22)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@antfu/install-pkg': 1.1.0 @@ -11041,6 +11324,13 @@ snapshots: magic-string: 0.25.9 rollup: 2.79.2 + '@rollup/plugin-replace@6.0.3(rollup@2.79.2)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@2.79.2) + magic-string: 0.30.21 + optionalDependencies: + rollup: 2.79.2 + '@rollup/pluginutils@3.1.0(rollup@2.79.2)': dependencies: '@types/estree': 0.0.39 @@ -11048,6 +11338,14 @@ snapshots: picomatch: 2.3.1 rollup: 2.79.2 + '@rollup/pluginutils@5.3.0(rollup@2.79.2)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 2.79.2 + '@sentry-internal/browser-utils@8.55.0': dependencies: '@sentry/core': 8.55.0 @@ -11449,6 +11747,8 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/css-font-loading-module@0.0.7': {} + '@types/d3-array@3.2.2': {} '@types/d3-axis@3.0.6': @@ -11726,6 +12026,8 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@types/zen-observable@0.8.3': {} + '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -11967,6 +12269,8 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 + '@xstate/fsm@1.6.5': {} + '@xtuc/ieee754@1.2.0': {} '@xtuc/long@4.2.2': {} @@ -12234,6 +12538,8 @@ snapshots: balanced-match@1.0.2: {} + base64-arraybuffer@1.0.2: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.8.18: {} @@ -13807,6 +14113,8 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fflate@0.4.8: {} + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -14285,8 +14593,12 @@ snapshots: dependencies: postcss: 8.5.6 + idb-keyval@6.2.2: {} + idb@7.1.1: {} + idb@8.0.0: {} + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -14809,6 +15121,8 @@ snapshots: js-audio-recorder@1.0.7: {} + js-base64@3.7.8: {} + js-cookie@3.0.5: {} js-tokens@4.0.0: {} @@ -16797,6 +17111,10 @@ snapshots: rw@1.3.3: {} + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-buffer@5.2.1: {} sass-loader@16.0.5(sass@1.93.2)(webpack@5.102.1(esbuild@0.25.0)(uglify-js@3.19.3)): @@ -17624,6 +17942,8 @@ snapshots: web-namespaces@2.0.1: {} + web-vitals@5.1.0: {} + webidl-conversions@4.0.2: {} webpack-bundle-analyzer@4.10.1: @@ -17909,6 +18229,13 @@ snapshots: yocto-queue@1.2.1: {} + zen-observable-ts@1.1.0: + dependencies: + '@types/zen-observable': 0.8.3 + zen-observable: 0.8.15 + + zen-observable@0.8.15: {} + zod@3.25.76: {} zod@4.1.12: {}