From 5a2d379a1df441c19f760e4a8f4699f48681da83 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Mon, 3 Feb 2025 13:29:26 +0000 Subject: [PATCH] feat: switch playback to our own rrweb (#28148) Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- cypress.e2e.config.ts | 6 + cypress/support/e2e.ts | 4 +- ee/frontend/mobile-replay/index.ts | 2 +- ee/frontend/mobile-replay/mobile.types.ts | 2 +- .../schema/web/rr-web-schema.json | 234 +++++++++++++++++- ee/frontend/mobile-replay/transform.test.ts | 2 +- .../mobile-replay/transformer/transformers.ts | 2 +- frontend/@posthog/ee/types.ts | 2 +- .../__mocks__/recording_snapshots.ts | 2 +- .../apm/performance-event-utils.ts | 2 +- .../session-recordings/file-playback/types.ts | 2 +- .../session-recordings/player/PlayerFrame.tsx | 2 +- .../session-recordings/player/eventIndex.ts | 2 +- .../player/inspector/playerInspectorLogic.ts | 2 +- .../player/playerMetaLogic.tsx | 2 +- .../player/rrweb/canvas/canvas-plugin.ts | 6 +- .../rrweb/canvas/deserialize-canvas-args.ts | 4 +- .../session-recordings/player/rrweb/index.ts | 4 +- .../player/sessionRecordingDataLogic.ts | 14 +- .../player/sessionRecordingPlayerLogic.ts | 5 +- .../sidebar/PlayerSidebarDebuggerTab.tsx | 2 +- .../player/utils/segmenter.ts | 2 +- frontend/src/types.ts | 4 +- jest.config.ts | 2 +- package.json | 11 +- pnpm-lock.yaml | 130 ++++++---- 26 files changed, 355 insertions(+), 97 deletions(-) diff --git a/cypress.e2e.config.ts b/cypress.e2e.config.ts index d8023fa4de922..8b907f8fb2c90 100644 --- a/cypress.e2e.config.ts +++ b/cypress.e2e.config.ts @@ -45,6 +45,12 @@ export default defineConfig({ webpackOptions: createEntry('cypress'), watchOptions: {}, } + options.webpackOptions.module.rules.push({ + test: /\.m?js$/, + resolve: { + fullySpecified: false, + }, +} as any) // @ts-expect-error -- ignore errors in options type on('file:preprocessor', webpackPreprocessor(options)) diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index f05a549c9bf30..90af4e0604fb4 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -18,9 +18,7 @@ const E2E_TESTING = Cypress.env('E2E_TESTING') // From: https://github.com/cypress-io/cypress/issues/300#issuecomment-688915086 Cypress.on('window:before:load', (win) => { cy.spy(win.console, 'error') - cy.spy(win.console, 'warn') - - win._cypress_posthog_captures = [] + cy.spy(win.console, 'warn')(win as any)._cypress_posthog_captures = [] }) Cypress.on('window:load', (win) => { diff --git a/ee/frontend/mobile-replay/index.ts b/ee/frontend/mobile-replay/index.ts index 56a7d2ee45b98..a9e8a008b05bb 100644 --- a/ee/frontend/mobile-replay/index.ts +++ b/ee/frontend/mobile-replay/index.ts @@ -1,4 +1,4 @@ -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' import { captureException, captureMessage } from '@sentry/react' import Ajv, { ErrorObject } from 'ajv' diff --git a/ee/frontend/mobile-replay/mobile.types.ts b/ee/frontend/mobile-replay/mobile.types.ts index 7e18622fa8f47..3e8a19c48211c 100644 --- a/ee/frontend/mobile-replay/mobile.types.ts +++ b/ee/frontend/mobile-replay/mobile.types.ts @@ -1,5 +1,5 @@ // copied from rrweb-snapshot, not included in rrweb types -import { customEvent, EventType, IncrementalSource, removedNodeMutation } from '@rrweb/types' +import { customEvent, EventType, IncrementalSource, removedNodeMutation } from '@posthog/rrweb-types' export enum NodeType { Document = 0, diff --git a/ee/frontend/mobile-replay/schema/web/rr-web-schema.json b/ee/frontend/mobile-replay/schema/web/rr-web-schema.json index 79102a23ef9d9..fe8720f0f1591 100644 --- a/ee/frontend/mobile-replay/schema/web/rr-web-schema.json +++ b/ee/frontend/mobile-replay/schema/web/rr-web-schema.json @@ -54,7 +54,9 @@ "required": ["top", "left"], "type": "object" }, - "node": {} + "node": { + "$ref": "#/definitions/serializedNodeWithId" + } }, "required": ["node", "initialOffset"], "type": "object" @@ -310,6 +312,30 @@ "enum": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "type": "number" }, + "NodeType.CDATA": { + "const": 4, + "type": "number" + }, + "NodeType.Comment": { + "const": 5, + "type": "number" + }, + "NodeType.Document": { + "const": 0, + "type": "number" + }, + "NodeType.DocumentType": { + "const": 1, + "type": "number" + }, + "NodeType.Element": { + "const": 2, + "type": "number" + }, + "NodeType.Text": { + "const": 3, + "type": "number" + }, "PointerTypes": { "enum": [0, 1, 2], "type": "number" @@ -339,7 +365,9 @@ "nextId": { "type": ["number", "null"] }, - "node": {}, + "node": { + "$ref": "#/definitions/serializedNodeWithId" + }, "parentId": { "type": "number" }, @@ -414,6 +442,17 @@ "required": ["id", "attributes"], "type": "object" }, + "attributes": { + "additionalProperties": { + "type": ["string", "number", "boolean", "null"] + }, + "properties": { + "_cssText": { + "type": "string" + } + }, + "type": "object" + }, "canvasMutationCommand": { "additionalProperties": false, "properties": { @@ -785,6 +824,197 @@ "required": ["ranges", "source"], "type": "object" }, + "serializedNodeWithId": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "childNodes": { + "items": { + "$ref": "#/definitions/serializedNodeWithId" + }, + "type": "array" + }, + "compatMode": { + "type": "string" + }, + "id": { + "type": "number" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "rootId": { + "type": "number" + }, + "type": { + "$ref": "#/definitions/NodeType.Document" + } + }, + "required": ["childNodes", "id", "type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "publicId": { + "type": "string" + }, + "rootId": { + "type": "number" + }, + "systemId": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/NodeType.DocumentType" + } + }, + "required": ["id", "name", "publicId", "systemId", "type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "attributes": { + "$ref": "#/definitions/attributes" + }, + "childNodes": { + "items": { + "$ref": "#/definitions/serializedNodeWithId" + }, + "type": "array" + }, + "id": { + "type": "number" + }, + "isCustom": { + "const": true, + "type": "boolean" + }, + "isSVG": { + "const": true, + "type": "boolean" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "needBlock": { + "type": "boolean" + }, + "rootId": { + "type": "number" + }, + "tagName": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/NodeType.Element" + } + }, + "required": ["attributes", "childNodes", "id", "tagName", "type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "isStyle": { + "const": true, + "type": "boolean" + }, + "rootId": { + "type": "number" + }, + "textContent": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/NodeType.Text" + } + }, + "required": ["id", "textContent", "type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "rootId": { + "type": "number" + }, + "textContent": { + "const": "", + "type": "string" + }, + "type": { + "$ref": "#/definitions/NodeType.CDATA" + } + }, + "required": ["id", "textContent", "type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "number" + }, + "isShadow": { + "type": "boolean" + }, + "isShadowHost": { + "type": "boolean" + }, + "rootId": { + "type": "number" + }, + "textContent": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/NodeType.Comment" + } + }, + "required": ["id", "textContent", "type"], + "type": "object" + } + ] + }, "styleDeclarationData": { "additionalProperties": false, "properties": { diff --git a/ee/frontend/mobile-replay/transform.test.ts b/ee/frontend/mobile-replay/transform.test.ts index 77c5316d5a24b..f786eb0de5345 100644 --- a/ee/frontend/mobile-replay/transform.test.ts +++ b/ee/frontend/mobile-replay/transform.test.ts @@ -1,5 +1,5 @@ import posthogEE from '@posthog/ee/exports' -import { EventType } from '@rrweb/types' +import { EventType } from '@posthog/rrweb-types' import { ifEeDescribe } from 'lib/ee.test' import { PostHogEE } from '../../../frontend/@posthog/ee/types' diff --git a/ee/frontend/mobile-replay/transformer/transformers.ts b/ee/frontend/mobile-replay/transformer/transformers.ts index c209a6f58cea3..f786d0fd00128 100644 --- a/ee/frontend/mobile-replay/transformer/transformers.ts +++ b/ee/frontend/mobile-replay/transformer/transformers.ts @@ -8,7 +8,7 @@ import { metaEvent, mutationData, removedNodeMutation, -} from '@rrweb/types' +} from '@posthog/rrweb-types' import { captureMessage } from '@sentry/react' import { isObject } from 'lib/utils' import { PLACEHOLDER_SVG_DATA_IMAGE_URL } from 'scenes/session-recordings/player/rrweb' diff --git a/frontend/@posthog/ee/types.ts b/frontend/@posthog/ee/types.ts index 445a811018113..b36bf40e48d09 100644 --- a/frontend/@posthog/ee/types.ts +++ b/frontend/@posthog/ee/types.ts @@ -1,6 +1,6 @@ // NOTE: All exported items from the EE module _must_ be optionally defined to ensure we work well with FOSS -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' export type PostHogEE = { enabled: boolean diff --git a/frontend/src/scenes/session-recordings/__mocks__/recording_snapshots.ts b/frontend/src/scenes/session-recordings/__mocks__/recording_snapshots.ts index 5853cc41479b7..f60eaf7a5c498 100644 --- a/frontend/src/scenes/session-recordings/__mocks__/recording_snapshots.ts +++ b/frontend/src/scenes/session-recordings/__mocks__/recording_snapshots.ts @@ -1,4 +1,4 @@ -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' import { deduplicateSnapshots } from 'scenes/session-recordings/player/sessionRecordingDataLogic' import { RecordingSnapshot } from '~/types' diff --git a/frontend/src/scenes/session-recordings/apm/performance-event-utils.ts b/frontend/src/scenes/session-recordings/apm/performance-event-utils.ts index 9f450ab316cbb..a4f429d3b3dfc 100644 --- a/frontend/src/scenes/session-recordings/apm/performance-event-utils.ts +++ b/frontend/src/scenes/session-recordings/apm/performance-event-utils.ts @@ -1,4 +1,4 @@ -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' import { getSeriesBackgroundColor, getSeriesColor } from 'lib/colors' import { humanizeBytes } from 'lib/utils' import { CapturedNetworkRequest } from 'posthog-js' diff --git a/frontend/src/scenes/session-recordings/file-playback/types.ts b/frontend/src/scenes/session-recordings/file-playback/types.ts index 61f609f904d4e..e5d95425b0e31 100644 --- a/frontend/src/scenes/session-recordings/file-playback/types.ts +++ b/frontend/src/scenes/session-recordings/file-playback/types.ts @@ -1,4 +1,4 @@ -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' import { PersonType, RecordingSnapshot, SessionRecordingType } from '~/types' diff --git a/frontend/src/scenes/session-recordings/player/PlayerFrame.tsx b/frontend/src/scenes/session-recordings/player/PlayerFrame.tsx index 9dadd50b48360..f5e4df79c1924 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerFrame.tsx +++ b/frontend/src/scenes/session-recordings/player/PlayerFrame.tsx @@ -1,7 +1,7 @@ import './PlayerFrame.scss' +import { Handler, viewportResizeDimension } from '@posthog/rrweb-types' import useSize from '@react-hook/size' -import { Handler, viewportResizeDimension } from '@rrweb/types' import { useActions, useValues } from 'kea' import { useEffect, useRef } from 'react' import { sessionRecordingPlayerLogic } from 'scenes/session-recordings/player/sessionRecordingPlayerLogic' diff --git a/frontend/src/scenes/session-recordings/player/eventIndex.ts b/frontend/src/scenes/session-recordings/player/eventIndex.ts index 50bcc937f53b1..ae58f52988f37 100644 --- a/frontend/src/scenes/session-recordings/player/eventIndex.ts +++ b/frontend/src/scenes/session-recordings/player/eventIndex.ts @@ -1,4 +1,4 @@ -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' interface Metadata { playerTime: number diff --git a/frontend/src/scenes/session-recordings/player/inspector/playerInspectorLogic.ts b/frontend/src/scenes/session-recordings/player/inspector/playerInspectorLogic.ts index 765a284fd0f8d..09cdb719805e3 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/playerInspectorLogic.ts +++ b/frontend/src/scenes/session-recordings/player/inspector/playerInspectorLogic.ts @@ -1,4 +1,4 @@ -import { customEvent, EventType, eventWithTime, fullSnapshotEvent, pluginEvent } from '@rrweb/types' +import { customEvent, EventType, eventWithTime, fullSnapshotEvent, pluginEvent } from '@posthog/rrweb-types' import FuseClass from 'fuse.js' import { actions, connect, events, kea, key, listeners, path, props, propsChanged, reducers, selectors } from 'kea' import { loaders } from 'kea-loaders' diff --git a/frontend/src/scenes/session-recordings/player/playerMetaLogic.tsx b/frontend/src/scenes/session-recordings/player/playerMetaLogic.tsx index 0e1cc456cc157..6e3ce84c78f52 100644 --- a/frontend/src/scenes/session-recordings/player/playerMetaLogic.tsx +++ b/frontend/src/scenes/session-recordings/player/playerMetaLogic.tsx @@ -1,5 +1,5 @@ import { IconCursorClick, IconKeyboard, IconWarning } from '@posthog/icons' -import { eventWithTime } from '@rrweb/types' +import { eventWithTime } from '@posthog/rrweb-types' import { actions, connect, kea, key, listeners, path, props, reducers, selectors } from 'kea' import { loaders } from 'kea-loaders' import api from 'lib/api' diff --git a/frontend/src/scenes/session-recordings/player/rrweb/canvas/canvas-plugin.ts b/frontend/src/scenes/session-recordings/player/rrweb/canvas/canvas-plugin.ts index 4de5d6325989d..ac6fc5e1bf304 100644 --- a/frontend/src/scenes/session-recordings/player/rrweb/canvas/canvas-plugin.ts +++ b/frontend/src/scenes/session-recordings/player/rrweb/canvas/canvas-plugin.ts @@ -1,3 +1,5 @@ +import { canvasMutation, Replayer } from '@posthog/rrweb' +import { ReplayPlugin } from '@posthog/rrweb' import { CanvasArg, canvasMutationData, @@ -5,11 +7,9 @@ import { EventType, eventWithTime, IncrementalSource, -} from '@rrweb/types' +} from '@posthog/rrweb-types' import { captureException } from '@sentry/react' import { debounce } from 'lib/utils' -import { canvasMutation, Replayer } from 'rrweb' -import { ReplayPlugin } from 'rrweb/typings/types' import { deserializeCanvasArg } from './deserialize-canvas-args' diff --git a/frontend/src/scenes/session-recordings/player/rrweb/canvas/deserialize-canvas-args.ts b/frontend/src/scenes/session-recordings/player/rrweb/canvas/deserialize-canvas-args.ts index 19370d07807f7..3a93e9a94e8b4 100644 --- a/frontend/src/scenes/session-recordings/player/rrweb/canvas/deserialize-canvas-args.ts +++ b/frontend/src/scenes/session-recordings/player/rrweb/canvas/deserialize-canvas-args.ts @@ -1,6 +1,6 @@ -import { CanvasArg } from '@rrweb/types' +import { Replayer } from '@posthog/rrweb' +import { CanvasArg } from '@posthog/rrweb-types' import { base64ArrayBuffer } from 'lib/utils' -import { Replayer } from 'rrweb' type GLVarMap = Map type CanvasContexts = CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext diff --git a/frontend/src/scenes/session-recordings/player/rrweb/index.ts b/frontend/src/scenes/session-recordings/player/rrweb/index.ts index 71a0935351595..079ad85a99b12 100644 --- a/frontend/src/scenes/session-recordings/player/rrweb/index.ts +++ b/frontend/src/scenes/session-recordings/player/rrweb/index.ts @@ -1,6 +1,6 @@ -import { EventType, eventWithTime, IncrementalSource } from '@rrweb/types' +import { playerConfig, ReplayPlugin } from '@posthog/rrweb' +import { EventType, eventWithTime, IncrementalSource } from '@posthog/rrweb-types' import Hls from 'hls.js' -import { playerConfig, ReplayPlugin } from 'rrweb/typings/types' export const PLACEHOLDER_SVG_DATA_IMAGE_URL = 'url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNOCAwSDE2TDAgMTZWOEw4IDBaIiBmaWxsPSIjMkQyRDJEIi8+CjxwYXRoIGQ9Ik0xNiA4VjE2SDhMMTYgOFoiIGZpbGw9IiMyRDJEMkQiLz4KPC9zdmc+Cg==");' diff --git a/frontend/src/scenes/session-recordings/player/sessionRecordingDataLogic.ts b/frontend/src/scenes/session-recordings/player/sessionRecordingDataLogic.ts index 767a600b5f8c0..2d4512bde258b 100644 --- a/frontend/src/scenes/session-recordings/player/sessionRecordingDataLogic.ts +++ b/frontend/src/scenes/session-recordings/player/sessionRecordingDataLogic.ts @@ -1,5 +1,5 @@ import posthogEE from '@posthog/ee/exports' -import { customEvent, EventType, eventWithTime, fullSnapshotEvent, IncrementalSource } from '@rrweb/types' +import { customEvent, EventType, eventWithTime, fullSnapshotEvent, IncrementalSource } from '@posthog/rrweb-types' import { captureException } from '@sentry/react' import { gunzipSync, strFromU8, strToU8 } from 'fflate' import { @@ -133,17 +133,23 @@ function unzip(compressedStr: string): any { * you can't return a union of `KnownType | unknown` * so even though this returns `eventWithTime | unknown` * it has to be typed as only unknown + * + * KLUDGE: we shouldn't need so many type assertions on ev.data but TS is not smart enough to figure it out */ function decompressEvent(ev: unknown): unknown { try { if (isCompressedEvent(ev)) { if (ev.cv === '2024-10') { - if (ev.type === EventType.FullSnapshot) { + if (ev.type === EventType.FullSnapshot && typeof ev.data === 'string') { return { ...ev, data: unzip(ev.data), } - } else if (ev.type === EventType.IncrementalSnapshot) { + } else if ( + ev.type === EventType.IncrementalSnapshot && + typeof ev.data === 'object' && + 'source' in ev.data + ) { if (ev.data.source === IncrementalSource.StyleSheetRule) { return { ...ev, @@ -154,7 +160,7 @@ function decompressEvent(ev: unknown): unknown { removes: unzip(ev.data.removes), }, } - } else if (ev.data.source === IncrementalSource.Mutation) { + } else if (ev.data.source === IncrementalSource.Mutation && 'texts' in ev.data) { return { ...ev, data: { diff --git a/frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts b/frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts index df8bd1914f0c6..6a42c1f74228a 100644 --- a/frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts +++ b/frontend/src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts @@ -1,5 +1,6 @@ import { lemonToast } from '@posthog/lemon-ui' -import { EventType, eventWithTime, IncrementalSource } from '@rrweb/types' +import { playerConfig, Replayer, ReplayPlugin } from '@posthog/rrweb' +import { EventType, eventWithTime, IncrementalSource } from '@posthog/rrweb-types' import { captureException } from '@sentry/react' import { actions, @@ -25,8 +26,6 @@ import { eventUsageLogic } from 'lib/utils/eventUsageLogic' import { wrapConsole } from 'lib/utils/wrapConsole' import posthog from 'posthog-js' import { RefObject } from 'react' -import { Replayer } from 'rrweb' -import { playerConfig, ReplayPlugin } from 'rrweb/typings/types' import { openBillingPopupModal } from 'scenes/billing/BillingPopup' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { diff --git a/frontend/src/scenes/session-recordings/player/sidebar/PlayerSidebarDebuggerTab.tsx b/frontend/src/scenes/session-recordings/player/sidebar/PlayerSidebarDebuggerTab.tsx index e372c42bb1bb7..5067ba5a7202d 100644 --- a/frontend/src/scenes/session-recordings/player/sidebar/PlayerSidebarDebuggerTab.tsx +++ b/frontend/src/scenes/session-recordings/player/sidebar/PlayerSidebarDebuggerTab.tsx @@ -1,5 +1,5 @@ import { LemonButton, LemonCollapse, LemonInputSelect } from '@posthog/lemon-ui' -import { EventType, eventWithTime, IncrementalSource } from '@rrweb/types' +import { EventType, eventWithTime, IncrementalSource } from '@posthog/rrweb-types' import { useActions, useValues } from 'kea' import { JSONViewer } from 'lib/components/JSONViewer' import { IconChevronLeft, IconChevronRight } from 'lib/lemon-ui/icons' diff --git a/frontend/src/scenes/session-recordings/player/utils/segmenter.ts b/frontend/src/scenes/session-recordings/player/utils/segmenter.ts index 1df94c89f63ca..8b8666e8000e0 100644 --- a/frontend/src/scenes/session-recordings/player/utils/segmenter.ts +++ b/frontend/src/scenes/session-recordings/player/utils/segmenter.ts @@ -1,4 +1,4 @@ -import { EventType, eventWithTime, IncrementalSource } from '@rrweb/types' +import { EventType, eventWithTime, IncrementalSource } from '@posthog/rrweb-types' import { Dayjs } from 'lib/dayjs' import { RecordingSegment, RecordingSnapshot } from '~/types' diff --git a/frontend/src/types.ts b/frontend/src/types.ts index e49d5a618c310..9e1a79b4560e5 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -1,7 +1,7 @@ import { LemonInputProps, LemonTableColumns } from '@posthog/lemon-ui' import { PluginConfigSchema } from '@posthog/plugin-scaffold' -import { LogLevel } from '@rrweb/rrweb-plugin-console-record' -import { eventWithTime } from '@rrweb/types' +import { LogLevel } from '@posthog/rrweb-plugin-console-record' +import { eventWithTime } from '@posthog/rrweb-types' import { ChartDataset, ChartType, InteractionItem } from 'chart.js' import { LogicWrapper } from 'kea' import { DashboardCompatibleScenes } from 'lib/components/SceneDashboardChoice/sceneDashboardChoiceModalLogic' diff --git a/jest.config.ts b/jest.config.ts index 462a8dfefc38a..6e71fa649d540 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -102,7 +102,7 @@ const config: Config = { 'monaco-editor': '/node_modules/monaco-editor/esm/vs/editor/editor.api.d.ts', '^scenes/(.*)$': '/frontend/src/scenes/$1', '^react-virtualized/dist/es/(.*)$': 'react-virtualized/dist/commonjs/$1', - '^rrweb/es/rrweb': 'rrweb/dist/rrweb.min.js', + '^@posthog/rrweb/es/rrweb': '@posthog/rrweb/dist/rrweb.min.js', d3: '/node_modules/d3/dist/d3.min.js', '^d3-(.*)$': `d3-$1/dist/d3-$1`, }, diff --git a/package.json b/package.json index f92984668b284..460dcc2f3e848 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "dev:migrate:postgres": "export DEBUG=1 && source env/bin/activate && python manage.py migrate", "dev:migrate:clickhouse": "export DEBUG=1 && source env/bin/activate && python manage.py migrate_clickhouse", "prepare": "husky install", - "mobile-replay:web:schema:build:json": "ts-json-schema-generator -f tsconfig.json --path 'node_modules/@rrweb/types/dist/index.d.ts' --type 'eventWithTime' --expose all --no-top-ref --out ee/frontend/mobile-replay/schema/web/rr-web-schema.json && prettier --write ee/frontend/mobile-replay/schema/web/rr-web-schema.json", + "mobile-replay:web:schema:build:json": "ts-json-schema-generator -f tsconfig.json --path 'node_modules/@posthog/rrweb-types/dist/index.d.ts' --type 'eventWithTime' --expose all --no-top-ref --out ee/frontend/mobile-replay/schema/web/rr-web-schema.json && prettier --write ee/frontend/mobile-replay/schema/web/rr-web-schema.json", "mobile-replay:mobile:schema:build:json": "ts-json-schema-generator -f tsconfig.json --path 'ee/frontend/mobile-replay/mobile.types.ts' --type 'mobileEventWithTime' --expose all --no-top-ref --out ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json && prettier --write ee/frontend/mobile-replay/schema/mobile/rr-mobile-schema.json", "mobile-replay:schema:build:json": "pnpm mobile-replay:web:schema:build:json && pnpm mobile-replay:mobile:schema:build:json", "visualize-toolbar-bundle": "pnpm exec esbuild-visualizer --metadata ./toolbar-esbuild-meta.json --filename=toolbar-esbuild-bundle-visualization.html", @@ -81,8 +81,8 @@ "@posthog/plugin-scaffold": "^1.4.4", "@radix-ui/react-accordion": "^1.2.2", "@react-hook/size": "^2.1.2", - "@rrweb/rrweb-plugin-console-record": "2.0.0-alpha.18", - "@rrweb/types": "2.0.0-alpha.13", + "@posthog/rrweb-plugin-console-record": "0.0.6", + "@posthog/rrweb-types": "0.0.6", "@sentry/react": "7.112.1", "@stripe/react-stripe-js": "^2.8.0", "@stripe/stripe-js": "^4.5.0", @@ -190,7 +190,7 @@ "react-transition-group": "^4.4.5", "react-virtualized": "^9.22.5", "resize-observer-polyfill": "^1.5.1", - "rrweb": "2.0.0-alpha.13", + "@posthog/rrweb": "0.0.6", "sass": "^1.26.2", "tailwind-merge": "^2.2.2", "tailwindcss": "3.4.1", @@ -210,7 +210,7 @@ "@babel/preset-env": "^7.22.10", "@babel/preset-react": "^7.22.5", "@babel/preset-typescript": "^7.22.5", - "@cypress/webpack-preprocessor": "^5.17.1", + "@cypress/webpack-preprocessor": "^6.0.2", "@playwright/test": "1.45.0", "@sentry/types": "7.112.1", "@storybook/addon-a11y": "^7.6.4", @@ -339,7 +339,6 @@ "typescript": "~4.9.5" }, "patchedDependencies": { - "rrweb@2.0.0-alpha.13": "patches/rrweb@2.0.0-alpha.13.patch", "heatmap.js@2.0.5": "patches/heatmap.js@2.0.5.patch", "dayjs@1.11.11": "patches/dayjs@1.11.11.patch" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b3f2eb319ee1..98dc0edbc5c97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,9 +15,6 @@ patchedDependencies: heatmap.js@2.0.5: hash: gydrxrztd4ruyhouu6tu7zh43e path: patches/heatmap.js@2.0.5.patch - rrweb@2.0.0-alpha.13: - hash: e2gmypqces37eklplr5o3rvywa - path: patches/rrweb@2.0.0-alpha.13.patch dependencies: '@babel/runtime': @@ -62,18 +59,21 @@ dependencies: '@posthog/plugin-scaffold': specifier: ^1.4.4 version: 1.4.4 + '@posthog/rrweb': + specifier: 0.0.6 + version: 0.0.6 + '@posthog/rrweb-plugin-console-record': + specifier: 0.0.6 + version: 0.0.6(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.6) + '@posthog/rrweb-types': + specifier: 0.0.6 + version: 0.0.6 '@radix-ui/react-accordion': specifier: ^1.2.2 version: 1.2.2(@types/react-dom@18.2.14)(@types/react@17.0.52)(react-dom@18.2.0)(react@18.2.0) '@react-hook/size': specifier: ^2.1.2 version: 2.1.2(react@18.2.0) - '@rrweb/rrweb-plugin-console-record': - specifier: 2.0.0-alpha.18 - version: 2.0.0-alpha.18(rrweb@2.0.0-alpha.13) - '@rrweb/types': - specifier: 2.0.0-alpha.13 - version: 2.0.0-alpha.13 '@sentry/react': specifier: 7.112.1 version: 7.112.1(react@18.2.0) @@ -395,9 +395,6 @@ dependencies: resize-observer-polyfill: specifier: ^1.5.1 version: 1.5.1 - rrweb: - specifier: 2.0.0-alpha.13 - version: 2.0.0-alpha.13(patch_hash=e2gmypqces37eklplr5o3rvywa) sass: specifier: ^1.26.2 version: 1.56.0 @@ -457,8 +454,8 @@ devDependencies: specifier: ^7.22.5 version: 7.22.5(@babel/core@7.22.10) '@cypress/webpack-preprocessor': - specifier: ^5.17.1 - version: 5.17.1(@babel/core@7.22.10)(@babel/preset-env@7.22.10)(babel-loader@8.3.0)(webpack@5.88.2) + specifier: ^6.0.2 + version: 6.0.2(@babel/core@7.22.10)(@babel/preset-env@7.22.10)(babel-loader@8.3.0)(webpack@5.88.2) '@playwright/test': specifier: 1.45.0 version: 1.45.0 @@ -4169,12 +4166,12 @@ packages: uuid: 8.3.2 dev: true - /@cypress/webpack-preprocessor@5.17.1(@babel/core@7.22.10)(@babel/preset-env@7.22.10)(babel-loader@8.3.0)(webpack@5.88.2): - resolution: {integrity: sha512-FE/e8ikPc8z4EVopJCaior3RGy0jd2q9Xcp5NtiwNG4XnLfEnUFTZlAGwXe75sEh4fNMPrBJW1KIz77PX5vGAw==} + /@cypress/webpack-preprocessor@6.0.2(@babel/core@7.22.10)(@babel/preset-env@7.22.10)(babel-loader@8.3.0)(webpack@5.88.2): + resolution: {integrity: sha512-0+1+4iy4W9PE6R5ywBNKAZoFp8Sf//w3UJ+CKTqkcAjA29b+dtsD0iFT70DsYE0BMqUM1PO7HXFGbXllQ+bRAA==} peerDependencies: '@babel/core': ^7.0.1 '@babel/preset-env': ^7.0.0 - babel-loader: ^8.0.2 || ^9 + babel-loader: ^8.3 || ^9 webpack: ^4 || ^5 dependencies: '@babel/core': 7.22.10 @@ -5445,6 +5442,49 @@ packages: '@maxmind/geoip2-node': 3.5.0 dev: false + /@posthog/rrdom@0.0.4: + resolution: {integrity: sha512-hUZOgnIxzB6ZWgKBbuf79oHko+7x1+sQMVtovY0k6fO67e5SwhKkLq3Y/Tn2ayIyUqEKqL8971wP1cmIeIVO+A==} + dependencies: + '@posthog/rrweb-snapshot': 0.0.4 + dev: false + + /@posthog/rrweb-plugin-console-record@0.0.6(@posthog/rrweb-utils@0.0.4)(@posthog/rrweb@0.0.6): + resolution: {integrity: sha512-aFbFNjbx6qk6HJZ4scFJcF3QS9IUjSmAxg5KMvSTlixwYUUJuKGJUmzau2sb6kqC4V8OICfkzAfq0q+k5xMpDQ==} + peerDependencies: + '@posthog/rrweb': '*' + '@posthog/rrweb-utils': '*' + dependencies: + '@posthog/rrweb': 0.0.6 + '@posthog/rrweb-utils': 0.0.4 + dev: false + + /@posthog/rrweb-snapshot@0.0.4: + resolution: {integrity: sha512-ifZH6T0FYjHtiCcqQOdrLn8YH9I7OOIWu2GSZMCzFd8F8oX1gtX4Tk/yX0sA6qAIWtfwDC0dKXgHWS2/EqGjgg==} + dependencies: + postcss: 8.5.1 + dev: false + + /@posthog/rrweb-types@0.0.6: + resolution: {integrity: sha512-WXjddVEY2oZzuCOuobDAz9D2x8tl7SYv8/YGXcY1BApJ1Y17b+w8g5r2+0A1ZFC0aq89LVO3AIwEPd0vipkFqA==} + dev: false + + /@posthog/rrweb-utils@0.0.4: + resolution: {integrity: sha512-ndkpquzqXV/i0u4paOPiESWE/wdOEPdM+Q+sFQfcn6KnvjxtkzsnNNSlOcNHSwuRh0bCk3Cgs2ixDVTSZ+Zdtg==} + dev: false + + /@posthog/rrweb@0.0.6: + resolution: {integrity: sha512-Ui/za+yF5LmNYxY3b5wszgVFtA5FdHNcqYotKa7DY08w1sE/CPtFe7cdGYHhegjzexC1KDVU54a1FDLktWDuTg==} + dependencies: + '@posthog/rrdom': 0.0.4 + '@posthog/rrweb-snapshot': 0.0.4 + '@posthog/rrweb-types': 0.0.6 + '@posthog/rrweb-utils': 0.0.4 + '@types/css-font-loading-module': 0.0.7 + '@xstate/fsm': 1.6.5 + base64-arraybuffer: 1.0.2 + mitt: 3.0.0 + dev: false + /@radix-ui/number@1.0.1: resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: @@ -6353,20 +6393,6 @@ packages: type-fest: 2.19.0 dev: false - /@rrweb/rrweb-plugin-console-record@2.0.0-alpha.18(rrweb@2.0.0-alpha.13): - resolution: {integrity: sha512-R/ys7jrOXjCwcVOf3EkXtT3/XZQ+OMqy+3VhUmgrwngpvppThZlbK4a13OCECwkB8OCJ81S9oYleNbszja2IYA==} - peerDependencies: - rrweb: ^2.0.0-alpha.18 - dependencies: - rrweb: 2.0.0-alpha.13(patch_hash=e2gmypqces37eklplr5o3rvywa) - dev: false - - /@rrweb/types@2.0.0-alpha.13: - resolution: {integrity: sha512-ytq+MeVm/vP2ybw+gTAN3Xvt7HN2yS+wlbfnwHpQMftxrwzq0kEZHdw+Jp5WUvvpONWzXriNAUU9dW0qLGkzNg==} - dependencies: - rrweb-snapshot: 2.0.0-alpha.13 - dev: false - /@sentry-internal/feedback@7.112.1: resolution: {integrity: sha512-ejE4eRXLqv5emxVWudBkRQCv5Q7s21thei7gqSxGLBXe8AUrCjTiD0qA1ToJAKcleIyRRf/TQvGb/T7U6vwAAw==} engines: {node: '>=12'} @@ -17489,6 +17515,10 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + dev: false + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -18412,6 +18442,15 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.5.1: + resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + dev: false + /posthog-js-lite@3.0.0: resolution: {integrity: sha512-dyajjnfzZD1tht4N7p7iwf7nBnR1MjVaVu+MKr+7gBgA39bn28wizCIJZztZPtHy4PY0YwtSGgwfBCuG/hnHgA==} dev: false @@ -19731,30 +19770,6 @@ packages: resolution: {integrity: sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q==} dev: false - /rrdom@2.0.0-alpha.13: - resolution: {integrity: sha512-GJD3L2MPbIg3+VgCwwfujB4HRXyMfDdg8o3djPjSB9rMX2b52Hx2tBUmwmdnWfgWKtYGDJ2wVX9Dng3tZEBHVA==} - dependencies: - rrweb-snapshot: 2.0.0-alpha.13 - dev: false - - /rrweb-snapshot@2.0.0-alpha.13: - resolution: {integrity: sha512-slbhNBCYjxLGCeH95a67ECCy5a22nloXp1F5wF7DCzUNw80FN7tF9Lef1sRGLNo32g3mNqTc2sWLATlKejMxYw==} - dev: false - - /rrweb@2.0.0-alpha.13(patch_hash=e2gmypqces37eklplr5o3rvywa): - resolution: {integrity: sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==} - dependencies: - '@rrweb/types': 2.0.0-alpha.13 - '@types/css-font-loading-module': 0.0.7 - '@xstate/fsm': 1.6.5 - base64-arraybuffer: 1.0.2 - fflate: 0.4.8 - mitt: 3.0.0 - rrdom: 2.0.0-alpha.13 - rrweb-snapshot: 2.0.0-alpha.13 - dev: false - patched: true - /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -20366,6 +20381,11 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + dev: false + /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: