replaySpanFrameData.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {RawSpanFrame as TSpanFrame} from 'sentry/utils/replays/types';
  2. type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
  3. type TestableFrame<Op extends TSpanFrame['op']> = Overwrite<
  4. Partial<Extract<TSpanFrame, {op: Op}>>,
  5. {endTimestamp: Date; startTimestamp: Date}
  6. >;
  7. type MockFrame<Op extends TSpanFrame['op']> = Extract<TSpanFrame, {op: Op}>;
  8. function BaseFrame<T extends TSpanFrame['op']>(
  9. op: T,
  10. fields: TestableFrame<T>
  11. ): MockFrame<T> {
  12. return {
  13. op,
  14. description: fields.description ?? '',
  15. startTimestamp: fields.startTimestamp.getTime() / 1000,
  16. endTimestamp: fields.endTimestamp.getTime() / 1000,
  17. data: fields.data,
  18. } as MockFrame<T>;
  19. }
  20. export function LargestContentfulPaintFrame(
  21. fields: TestableFrame<'largest-contentful-paint'>
  22. ): MockFrame<'largest-contentful-paint'> {
  23. return BaseFrame('largest-contentful-paint', {
  24. ...fields,
  25. data: {
  26. nodeId: fields.data?.nodeId,
  27. size: fields.data?.size ?? 0,
  28. value: fields.data?.value ?? 0,
  29. },
  30. });
  31. }
  32. export function MemoryFrame(fields: TestableFrame<'memory'>): MockFrame<'memory'> {
  33. return BaseFrame('memory', {
  34. ...fields,
  35. data: {
  36. memory: {
  37. jsHeapSizeLimit: fields.data?.memory?.jsHeapSizeLimit ?? 0,
  38. totalJSHeapSize: fields.data?.memory?.totalJSHeapSize ?? 0,
  39. usedJSHeapSize: fields.data?.memory?.usedJSHeapSize ?? 0,
  40. },
  41. },
  42. });
  43. }
  44. export function NavigationFrame(
  45. fields: TestableFrame<
  46. 'navigation.navigate' | 'navigation.reload' | 'navigation.back_forward'
  47. >
  48. ): MockFrame<'navigation.navigate' | 'navigation.reload' | 'navigation.back_forward'> {
  49. return BaseFrame(fields.op ?? 'navigation.navigate', {
  50. ...fields,
  51. data: {
  52. decodedBodySize: fields.data?.decodedBodySize,
  53. domComplete: fields.data?.domComplete,
  54. domContentLoadedEventEnd: fields.data?.domContentLoadedEventEnd,
  55. domContentLoadedEventStart: fields.data?.domContentLoadedEventStart,
  56. domInteractive: fields.data?.domInteractive,
  57. duration: fields.data?.duration,
  58. encodedBodySize: fields.data?.encodedBodySize,
  59. loadEventEnd: fields.data?.loadEventEnd,
  60. loadEventStart: fields.data?.loadEventStart,
  61. redirectCount: fields.data?.redirectCount,
  62. size: fields.data?.size,
  63. },
  64. });
  65. }
  66. export function NavigationPushFrame(
  67. fields: TestableFrame<'navigation.push'>
  68. ): MockFrame<'navigation.push'> {
  69. return BaseFrame('navigation.push', {
  70. ...fields,
  71. data: {
  72. previous: fields.data?.previous ?? '/',
  73. },
  74. });
  75. }
  76. export function PaintFrame(fields: TestableFrame<'paint'>): MockFrame<'paint'> {
  77. return BaseFrame('paint', fields);
  78. }
  79. export function RequestFrame(
  80. fields: TestableFrame<'resource.fetch' | 'resource.xhr'>
  81. ): MockFrame<'resource.fetch' | 'resource.xhr'> {
  82. return BaseFrame(fields.op ?? 'resource.xhr', {
  83. ...fields,
  84. data: {
  85. method: fields.data?.method,
  86. requestBodySize: fields.data?.requestBodySize,
  87. responseBodySize: fields.data?.responseBodySize,
  88. statusCode: fields.data?.statusCode,
  89. request: fields.data?.request,
  90. response: fields.data?.response,
  91. },
  92. });
  93. }
  94. export function ResourceFrame(
  95. fields: TestableFrame<
  96. | 'resource.css'
  97. | 'resource.iframe'
  98. | 'resource.img'
  99. | 'resource.link'
  100. | 'resource.other'
  101. | 'resource.script'
  102. >
  103. ): MockFrame<
  104. | 'resource.css'
  105. | 'resource.iframe'
  106. | 'resource.img'
  107. | 'resource.link'
  108. | 'resource.other'
  109. | 'resource.script'
  110. > {
  111. return BaseFrame(fields.op ?? 'resource.other', {
  112. ...fields,
  113. data: {
  114. decodedBodySize: fields.data?.decodedBodySize ?? 0,
  115. encodedBodySize: fields.data?.encodedBodySize ?? 0,
  116. size: fields.data?.size ?? 0,
  117. statusCode: fields.data?.statusCode,
  118. },
  119. });
  120. }