rrweb.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import type {fullSnapshotEvent, serializedNodeWithId} from 'sentry/utils/replays/types';
  2. import {EventType, NodeType} from 'sentry/utils/replays/types';
  3. interface FullSnapshotEvent extends fullSnapshotEvent {
  4. timestamp: number;
  5. }
  6. const nextRRWebId = (function () {
  7. let __rrwebID = 0;
  8. return () => ++__rrwebID;
  9. })();
  10. export function RRWebInitFrameEvents({
  11. height = 600,
  12. href = 'http://localhost/',
  13. timestamp,
  14. width = 800,
  15. }: {
  16. timestamp: Date;
  17. height?: number;
  18. href?: string;
  19. width?: number;
  20. }) {
  21. return [
  22. {
  23. type: EventType.DomContentLoaded,
  24. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  25. },
  26. {
  27. type: EventType.Load,
  28. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  29. },
  30. {
  31. type: EventType.Meta,
  32. data: {href, width, height},
  33. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  34. },
  35. ];
  36. }
  37. export function RRWebFullSnapshotFrameEvent({
  38. timestamp,
  39. childNodes = [],
  40. }: {
  41. timestamp: Date;
  42. childNodes?: serializedNodeWithId[];
  43. }): FullSnapshotEvent {
  44. return {
  45. type: EventType.FullSnapshot,
  46. timestamp: timestamp.getTime(),
  47. data: {
  48. initialOffset: {top: 0, left: 0},
  49. node: {
  50. type: NodeType.Document,
  51. id: 0,
  52. childNodes: [
  53. RRWebDOMFrame({
  54. tagName: 'body',
  55. attributes: {
  56. style:
  57. 'margin:0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu;',
  58. },
  59. childNodes,
  60. }),
  61. ],
  62. },
  63. },
  64. };
  65. }
  66. export function RRWebDOMFrame({
  67. id,
  68. tagName,
  69. attributes,
  70. childNodes,
  71. textContent,
  72. }: {
  73. attributes?: Record<string, string>;
  74. childNodes?: serializedNodeWithId[];
  75. id?: number;
  76. tagName?: string;
  77. textContent?: string;
  78. }): serializedNodeWithId {
  79. id = id ?? nextRRWebId();
  80. if (tagName) {
  81. return {
  82. type: NodeType.Element,
  83. id,
  84. tagName,
  85. attributes: attributes ?? {},
  86. childNodes: childNodes ?? [],
  87. };
  88. }
  89. return {
  90. type: NodeType.Text,
  91. id,
  92. textContent: textContent ?? '',
  93. };
  94. }
  95. export function RRWebHelloWorldFrame() {
  96. return RRWebDOMFrame({
  97. tagName: 'div',
  98. childNodes: [
  99. RRWebDOMFrame({
  100. tagName: 'h1',
  101. attributes: {style: 'text-align: center;'},
  102. childNodes: [
  103. RRWebDOMFrame({
  104. textContent: 'Hello World',
  105. }),
  106. ],
  107. }),
  108. ],
  109. });
  110. }