Skip to content

Commit 3c895e1

Browse files
committed
✨ stream plugin
1 parent 8682acf commit 3c895e1

File tree

5 files changed

+124
-50
lines changed

5 files changed

+124
-50
lines changed

packages/rum-core/src/domain/assembly.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from '@datadog/browser-core'
1313
import type { RumEventDomainContext } from '../domainContext.types'
1414
import { RumEventType } from '../rawRumEvent.types'
15-
import type { RumEvent } from '../rumEvent.types'
15+
import type { RumEvent, RumViewEvent, RumVitalEvent } from '../rumEvent.types'
1616
import type { LifeCycle } from './lifeCycle'
1717
import { LifeCycleEventType } from './lifeCycle'
1818
import type { RumConfiguration } from './configuration'
@@ -133,11 +133,28 @@ export function startRumAssembly(
133133
}
134134

135135
if (rawRumEvent.type === 'stream') {
136-
// @ts-expect-error TBF
137-
serverRumEvent.type = 'view'
138-
}
136+
const streamEvent = {
137+
...(serverRumEvent as RumViewEvent),
138+
view: {
139+
...serverRumEvent.view,
140+
id: serverRumEvent.stream?.id,
141+
action: {
142+
count: 0,
143+
},
144+
error: {
145+
count: 0,
146+
},
147+
resource: {
148+
count: 0,
149+
},
150+
},
151+
type: 'view',
152+
}
139153

140-
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, serverRumEvent)
154+
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, streamEvent as RumEvent & Context)
155+
} else {
156+
lifeCycle.notify(LifeCycleEventType.RUM_EVENT_COLLECTED, serverRumEvent)
157+
}
141158
}
142159
}
143160
)

packages/rum-core/src/domain/stream/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export function createStreamPlugin(): { plugin: RumPlugin; createStream: () => R
1313

1414
const api: API = {
1515
get addEvent() {
16-
console.log('>>>', 'getter addEvent', addEvent)
1716
return addEvent ?? store
1817
},
1918
}
Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
1-
// eslint-disable-next-line no-restricted-syntax
2-
abstract class Metric {
3-
constructor(private name: string) {}
1+
export function createWeightAverageMetric() {
2+
let lastUpdate = 0
3+
let weight = 0
4+
let value: number | undefined
45

5-
update(value: number, weight?: number): void {
6-
// This method is a placeholder for metric updates.
6+
return {
7+
get value() {
8+
console.log('>>>', value)
9+
return value
10+
},
11+
update(newLastUpdate: number, newValue: number) {
12+
if (newLastUpdate <= lastUpdate) {
13+
return
14+
}
15+
16+
const newWeight = newLastUpdate - lastUpdate
17+
value = ((value ?? 0) * weight + newValue * newWeight) / (weight + newWeight)
18+
weight += newWeight
19+
lastUpdate = newLastUpdate
20+
},
721
}
822
}
923

10-
// eslint-disable-next-line no-restricted-syntax
11-
export class WeightAverageMetric extends Metric {
12-
private average: number = 0
13-
private weight: number = 0
24+
export function createLastMetric() {
25+
let lastUpdate = 0
26+
let value: number | undefined
27+
28+
return {
29+
get value() {
30+
return value
31+
},
32+
update(newLastUpdate: number, newValue: number) {
33+
if (newLastUpdate <= lastUpdate) {
34+
return
35+
}
1436

15-
update(value: number, weight: number): void {
16-
this.average = (this.average * this.weight + value * weight) / (this.weight + weight)
17-
this.weight += weight
37+
value = newValue
38+
lastUpdate = newLastUpdate
39+
},
1840
}
1941
}
Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,70 @@
11
import { clocksNow, generateUUID } from '@datadog/browser-core'
22
import type { StartRumResult } from '../..'
3-
import type { WeightAverageMetric } from './metric'
3+
import { createLastMetric, createWeightAverageMetric } from './metric'
44
import { createTimer } from './timer'
55

66
export interface API {
77
addEvent: AddEvent
88
}
99

10-
export type AddEvent = StartRumResult['addEvent']
11-
1210
interface Meta {
1311
duration?: number
1412
format?: string
1513
resolution?: string
1614
}
1715

18-
interface Metrics {
19-
bitrate: WeightAverageMetric
20-
fps: WeightAverageMetric
21-
timestamp: number
22-
watchTime: number
23-
}
16+
export type AddEvent = StartRumResult['addEvent']
2417

2518
type Transition = 'end' | 'error' | 'pause' | 'play' | 'preload' | 'quit' | 'rebuff' | 'seek' | 'start'
2619

2720
export function createStream(api: API) {
2821
const id = generateUUID()
2922
const origin = clocksNow()
3023
const timer = createTimer()
24+
const meta: Meta = {}
25+
const metrics = {
26+
bitrate: createWeightAverageMetric(),
27+
fps: createWeightAverageMetric(),
28+
timestamp: createLastMetric(),
29+
watchTime: createLastMetric(),
30+
}
31+
32+
function sendStreamEvent() {
33+
const now = clocksNow()
34+
35+
api.addEvent(
36+
now.relative,
37+
{
38+
date: now.timeStamp,
39+
type: 'stream',
40+
stream: {
41+
id,
42+
bitrate: metrics.bitrate.value,
43+
duration: meta.duration,
44+
format: meta.format,
45+
fps: metrics.fps.value,
46+
resolution: meta.resolution,
47+
timestamp: metrics.timestamp.value,
48+
watch_time: metrics.watchTime.value,
49+
},
50+
},
51+
{}
52+
)
53+
}
3154

3255
return {
33-
interaction(id: string): void {},
56+
interaction(id: string): void {
57+
console.log('>>>', 'interaction', id)
58+
},
59+
set<K extends keyof Meta>(key: K, value: Meta[K]): void {
60+
if (meta[key] !== undefined) {
61+
return
62+
}
63+
64+
meta[key] = value
65+
66+
sendStreamEvent()
67+
},
3468
transition(state: Transition, context: any): void {
3569
if (state === 'play') {
3670
timer.start()
@@ -53,20 +87,10 @@ export function createStream(api: API) {
5387
context
5488
)
5589
},
56-
update(key: string, value: any): void {
57-
const now = clocksNow()
90+
update(key: keyof typeof metrics, value: number): void {
91+
metrics[key].update(timer.value, value)
5892

59-
api.addEvent(
60-
now.relative,
61-
{
62-
date: now.timeStamp,
63-
type: 'stream',
64-
stream: {
65-
id: generateUUID(),
66-
},
67-
},
68-
{}
69-
)
93+
sendStreamEvent()
7094
},
7195
}
7296
}

packages/rum-core/src/domain/stream/timer.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,33 @@ import type { RelativeTime } from '@datadog/browser-core'
22
import { relativeNow } from '@datadog/browser-core'
33

44
export function createTimer() {
5-
let start: RelativeTime
6-
let count = 0
5+
let counter = 0
6+
let start: RelativeTime = 0 as RelativeTime
7+
let stopped = true
78

89
return {
9-
start(): number {
10-
start = relativeNow()
10+
get value() {
11+
if (stopped) {
12+
return counter
13+
}
1114

12-
return count
15+
return relativeNow() - start
1316
},
14-
stop(): number {
15-
const duration = relativeNow() - start
17+
start(): void {
18+
if (!stopped) {
19+
return
20+
}
1621

17-
count += duration
22+
start = relativeNow()
23+
stopped = false
24+
},
25+
stop(): void {
26+
if (stopped) {
27+
return
28+
}
1829

19-
return count
30+
counter = relativeNow() - start
31+
stopped = true
2032
},
2133
}
2234
}

0 commit comments

Comments
 (0)