diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go
index a5307ee44..8dab53ff0 100644
--- a/backend/pkg/messages/messages.go
+++ b/backend/pkg/messages/messages.go
@@ -77,6 +77,7 @@ const (
MsgBatchMetadata = 81
MsgPartitionedMessage = 82
MsgNetworkRequest = 83
+ MsgWSChannel = 84
MsgInputChange = 112
MsgSelectionChange = 113
MsgMouseThrashing = 114
@@ -109,7 +110,6 @@ const (
MsgIOSIssueEvent = 111
)
-
type Timestamp struct {
message
Timestamp uint64
@@ -133,22 +133,22 @@ func (msg *Timestamp) TypeID() int {
type SessionStart struct {
message
- Timestamp uint64
- ProjectID uint64
- TrackerVersion string
- RevID string
- UserUUID string
- UserAgent string
- UserOS string
- UserOSVersion string
- UserBrowser string
- UserBrowserVersion string
- UserDevice string
- UserDeviceType string
+ Timestamp uint64
+ ProjectID uint64
+ TrackerVersion string
+ RevID string
+ UserUUID string
+ UserAgent string
+ UserOS string
+ UserOSVersion string
+ UserBrowser string
+ UserBrowserVersion string
+ UserDevice string
+ UserDeviceType string
UserDeviceMemorySize uint64
- UserDeviceHeapSize uint64
- UserCountry string
- UserID string
+ UserDeviceHeapSize uint64
+ UserCountry string
+ UserID string
}
func (msg *SessionStart) Encode() []byte {
@@ -205,8 +205,8 @@ func (msg *SessionEndDeprecated) TypeID() int {
type SetPageLocation struct {
message
- URL string
- Referrer string
+ URL string
+ Referrer string
NavigationStart uint64
}
@@ -230,7 +230,7 @@ func (msg *SetPageLocation) TypeID() int {
type SetViewportSize struct {
message
- Width uint64
+ Width uint64
Height uint64
}
@@ -276,7 +276,6 @@ func (msg *SetViewportScroll) TypeID() int {
type CreateDocument struct {
message
-
}
func (msg *CreateDocument) Encode() []byte {
@@ -297,11 +296,11 @@ func (msg *CreateDocument) TypeID() int {
type CreateElementNode struct {
message
- ID uint64
+ ID uint64
ParentID uint64
- index uint64
- Tag string
- SVG bool
+ index uint64
+ Tag string
+ SVG bool
}
func (msg *CreateElementNode) Encode() []byte {
@@ -326,9 +325,9 @@ func (msg *CreateElementNode) TypeID() int {
type CreateTextNode struct {
message
- ID uint64
+ ID uint64
ParentID uint64
- Index uint64
+ Index uint64
}
func (msg *CreateTextNode) Encode() []byte {
@@ -351,9 +350,9 @@ func (msg *CreateTextNode) TypeID() int {
type MoveNode struct {
message
- ID uint64
+ ID uint64
ParentID uint64
- Index uint64
+ Index uint64
}
func (msg *MoveNode) Encode() []byte {
@@ -397,8 +396,8 @@ func (msg *RemoveNode) TypeID() int {
type SetNodeAttribute struct {
message
- ID uint64
- Name string
+ ID uint64
+ Name string
Value string
}
@@ -422,7 +421,7 @@ func (msg *SetNodeAttribute) TypeID() int {
type RemoveNodeAttribute struct {
message
- ID uint64
+ ID uint64
Name string
}
@@ -445,7 +444,7 @@ func (msg *RemoveNodeAttribute) TypeID() int {
type SetNodeData struct {
message
- ID uint64
+ ID uint64
Data string
}
@@ -468,7 +467,7 @@ func (msg *SetNodeData) TypeID() int {
type SetCSSData struct {
message
- ID uint64
+ ID uint64
Data string
}
@@ -492,8 +491,8 @@ func (msg *SetCSSData) TypeID() int {
type SetNodeScroll struct {
message
ID uint64
- X int64
- Y int64
+ X int64
+ Y int64
}
func (msg *SetNodeScroll) Encode() []byte {
@@ -516,7 +515,7 @@ func (msg *SetNodeScroll) TypeID() int {
type SetInputTarget struct {
message
- ID uint64
+ ID uint64
Label string
}
@@ -539,9 +538,9 @@ func (msg *SetInputTarget) TypeID() int {
type SetInputValue struct {
message
- ID uint64
+ ID uint64
Value string
- Mask int64
+ Mask int64
}
func (msg *SetInputValue) Encode() []byte {
@@ -564,7 +563,7 @@ func (msg *SetInputValue) TypeID() int {
type SetInputChecked struct {
message
- ID uint64
+ ID uint64
Checked bool
}
@@ -610,14 +609,14 @@ func (msg *MouseMove) TypeID() int {
type NetworkRequestDeprecated struct {
message
- Type string
- Method string
- URL string
- Request string
- Response string
- Status uint64
+ Type string
+ Method string
+ URL string
+ Request string
+ Response string
+ Status uint64
Timestamp uint64
- Duration uint64
+ Duration uint64
}
func (msg *NetworkRequestDeprecated) Encode() []byte {
@@ -668,15 +667,15 @@ func (msg *ConsoleLog) TypeID() int {
type PageLoadTiming struct {
message
- RequestStart uint64
- ResponseStart uint64
- ResponseEnd uint64
+ RequestStart uint64
+ ResponseStart uint64
+ ResponseEnd uint64
DomContentLoadedEventStart uint64
- DomContentLoadedEventEnd uint64
- LoadEventStart uint64
- LoadEventEnd uint64
- FirstPaint uint64
- FirstContentfulPaint uint64
+ DomContentLoadedEventEnd uint64
+ LoadEventStart uint64
+ LoadEventEnd uint64
+ FirstPaint uint64
+ FirstContentfulPaint uint64
}
func (msg *PageLoadTiming) Encode() []byte {
@@ -705,8 +704,8 @@ func (msg *PageLoadTiming) TypeID() int {
type PageRenderTiming struct {
message
- SpeedIndex uint64
- VisuallyComplete uint64
+ SpeedIndex uint64
+ VisuallyComplete uint64
TimeToInteractive uint64
}
@@ -730,7 +729,7 @@ func (msg *PageRenderTiming) TypeID() int {
type JSExceptionDeprecated struct {
message
- Name string
+ Name string
Message string
Payload string
}
@@ -756,10 +755,10 @@ func (msg *JSExceptionDeprecated) TypeID() int {
type IntegrationEvent struct {
message
Timestamp uint64
- Source string
- Name string
- Message string
- Payload string
+ Source string
+ Name string
+ Message string
+ Payload string
}
func (msg *IntegrationEvent) Encode() []byte {
@@ -784,7 +783,7 @@ func (msg *IntegrationEvent) TypeID() int {
type CustomEvent struct {
message
- Name string
+ Name string
Payload string
}
@@ -849,7 +848,7 @@ func (msg *UserAnonymousID) TypeID() int {
type Metadata struct {
message
- Key string
+ Key string
Value string
}
@@ -872,23 +871,23 @@ func (msg *Metadata) TypeID() int {
type PageEvent struct {
message
- MessageID uint64
- Timestamp uint64
- URL string
- Referrer string
- Loaded bool
- RequestStart uint64
- ResponseStart uint64
- ResponseEnd uint64
+ MessageID uint64
+ Timestamp uint64
+ URL string
+ Referrer string
+ Loaded bool
+ RequestStart uint64
+ ResponseStart uint64
+ ResponseEnd uint64
DomContentLoadedEventStart uint64
- DomContentLoadedEventEnd uint64
- LoadEventStart uint64
- LoadEventEnd uint64
- FirstPaint uint64
- FirstContentfulPaint uint64
- SpeedIndex uint64
- VisuallyComplete uint64
- TimeToInteractive uint64
+ DomContentLoadedEventEnd uint64
+ LoadEventStart uint64
+ LoadEventEnd uint64
+ FirstPaint uint64
+ FirstContentfulPaint uint64
+ SpeedIndex uint64
+ VisuallyComplete uint64
+ TimeToInteractive uint64
}
func (msg *PageEvent) Encode() []byte {
@@ -925,11 +924,11 @@ func (msg *PageEvent) TypeID() int {
type InputEvent struct {
message
- MessageID uint64
- Timestamp uint64
- Value string
+ MessageID uint64
+ Timestamp uint64
+ Value string
ValueMasked bool
- Label string
+ Label string
}
func (msg *InputEvent) Encode() []byte {
@@ -954,8 +953,8 @@ func (msg *InputEvent) TypeID() int {
type CSSInsertRule struct {
message
- ID uint64
- Rule string
+ ID uint64
+ Rule string
Index uint64
}
@@ -979,7 +978,7 @@ func (msg *CSSInsertRule) TypeID() int {
type CSSDeleteRule struct {
message
- ID uint64
+ ID uint64
Index uint64
}
@@ -1002,13 +1001,13 @@ func (msg *CSSDeleteRule) TypeID() int {
type Fetch struct {
message
- Method string
- URL string
- Request string
- Response string
- Status uint64
+ Method string
+ URL string
+ Request string
+ Response string
+ Status uint64
Timestamp uint64
- Duration uint64
+ Duration uint64
}
func (msg *Fetch) Encode() []byte {
@@ -1035,10 +1034,10 @@ func (msg *Fetch) TypeID() int {
type Profiler struct {
message
- Name string
+ Name string
Duration uint64
- Args string
- Result string
+ Args string
+ Result string
}
func (msg *Profiler) Encode() []byte {
@@ -1062,7 +1061,7 @@ func (msg *Profiler) TypeID() int {
type OTable struct {
message
- Key string
+ Key string
Value string
}
@@ -1106,8 +1105,8 @@ func (msg *StateAction) TypeID() int {
type Redux struct {
message
- Action string
- State string
+ Action string
+ State string
Duration uint64
}
@@ -1132,7 +1131,7 @@ func (msg *Redux) TypeID() int {
type Vuex struct {
message
Mutation string
- State string
+ State string
}
func (msg *Vuex) Encode() []byte {
@@ -1154,7 +1153,7 @@ func (msg *Vuex) TypeID() int {
type MobX struct {
message
- Type string
+ Type string
Payload string
}
@@ -1177,8 +1176,8 @@ func (msg *MobX) TypeID() int {
type NgRx struct {
message
- Action string
- State string
+ Action string
+ State string
Duration uint64
}
@@ -1204,8 +1203,8 @@ type GraphQL struct {
message
OperationKind string
OperationName string
- Variables string
- Response string
+ Variables string
+ Response string
}
func (msg *GraphQL) Encode() []byte {
@@ -1229,10 +1228,10 @@ func (msg *GraphQL) TypeID() int {
type PerformanceTrack struct {
message
- Frames int64
- Ticks int64
+ Frames int64
+ Ticks int64
TotalJSHeapSize uint64
- UsedJSHeapSize uint64
+ UsedJSHeapSize uint64
}
func (msg *PerformanceTrack) Encode() []byte {
@@ -1256,7 +1255,7 @@ func (msg *PerformanceTrack) TypeID() int {
type StringDict struct {
message
- Key uint64
+ Key uint64
Value string
}
@@ -1279,8 +1278,8 @@ func (msg *StringDict) TypeID() int {
type SetNodeAttributeDict struct {
message
- ID uint64
- NameKey uint64
+ ID uint64
+ NameKey uint64
ValueKey uint64
}
@@ -1304,14 +1303,14 @@ func (msg *SetNodeAttributeDict) TypeID() int {
type ResourceTimingDeprecated struct {
message
- Timestamp uint64
- Duration uint64
- TTFB uint64
- HeaderSize uint64
+ Timestamp uint64
+ Duration uint64
+ TTFB uint64
+ HeaderSize uint64
EncodedBodySize uint64
DecodedBodySize uint64
- URL string
- Initiator string
+ URL string
+ Initiator string
}
func (msg *ResourceTimingDeprecated) Encode() []byte {
@@ -1340,7 +1339,7 @@ func (msg *ResourceTimingDeprecated) TypeID() int {
type ConnectionInformation struct {
message
Downlink uint64
- Type string
+ Type string
}
func (msg *ConnectionInformation) Encode() []byte {
@@ -1383,20 +1382,20 @@ func (msg *SetPageVisibility) TypeID() int {
type PerformanceTrackAggr struct {
message
- TimestampStart uint64
- TimestampEnd uint64
- MinFPS uint64
- AvgFPS uint64
- MaxFPS uint64
- MinCPU uint64
- AvgCPU uint64
- MaxCPU uint64
+ TimestampStart uint64
+ TimestampEnd uint64
+ MinFPS uint64
+ AvgFPS uint64
+ MaxFPS uint64
+ MinCPU uint64
+ AvgCPU uint64
+ MaxCPU uint64
MinTotalJSHeapSize uint64
AvgTotalJSHeapSize uint64
MaxTotalJSHeapSize uint64
- MinUsedJSHeapSize uint64
- AvgUsedJSHeapSize uint64
- MaxUsedJSHeapSize uint64
+ MinUsedJSHeapSize uint64
+ AvgUsedJSHeapSize uint64
+ MaxUsedJSHeapSize uint64
}
func (msg *PerformanceTrackAggr) Encode() []byte {
@@ -1430,9 +1429,9 @@ func (msg *PerformanceTrackAggr) TypeID() int {
type LoadFontFace struct {
message
- ParentID uint64
- Family string
- Source string
+ ParentID uint64
+ Family string
+ Source string
Descriptors string
}
@@ -1478,12 +1477,12 @@ func (msg *SetNodeFocus) TypeID() int {
type LongTask struct {
message
- Timestamp uint64
- Duration uint64
- Context uint64
+ Timestamp uint64
+ Duration uint64
+ Context uint64
ContainerType uint64
- ContainerSrc string
- ContainerId string
+ ContainerSrc string
+ ContainerId string
ContainerName string
}
@@ -1511,9 +1510,9 @@ func (msg *LongTask) TypeID() int {
type SetNodeAttributeURLBased struct {
message
- ID uint64
- Name string
- Value string
+ ID uint64
+ Name string
+ Value string
BaseURL string
}
@@ -1538,8 +1537,8 @@ func (msg *SetNodeAttributeURLBased) TypeID() int {
type SetCSSDataURLBased struct {
message
- ID uint64
- Data string
+ ID uint64
+ Data string
BaseURL string
}
@@ -1563,12 +1562,12 @@ func (msg *SetCSSDataURLBased) TypeID() int {
type IssueEventDeprecated struct {
message
- MessageID uint64
- Timestamp uint64
- Type string
+ MessageID uint64
+ Timestamp uint64
+ Type string
ContextString string
- Context string
- Payload string
+ Context string
+ Payload string
}
func (msg *IssueEventDeprecated) Encode() []byte {
@@ -1594,7 +1593,7 @@ func (msg *IssueEventDeprecated) TypeID() int {
type TechnicalInfo struct {
message
- Type string
+ Type string
Value string
}
@@ -1617,7 +1616,7 @@ func (msg *TechnicalInfo) TypeID() int {
type CustomIssue struct {
message
- Name string
+ Name string
Payload string
}
@@ -1661,9 +1660,9 @@ func (msg *AssetCache) TypeID() int {
type CSSInsertRuleURLBased struct {
message
- ID uint64
- Rule string
- Index uint64
+ ID uint64
+ Rule string
+ Index uint64
BaseURL string
}
@@ -1688,10 +1687,10 @@ func (msg *CSSInsertRuleURLBased) TypeID() int {
type MouseClick struct {
message
- ID uint64
+ ID uint64
HesitationTime uint64
- Label string
- Selector string
+ Label string
+ Selector string
}
func (msg *MouseClick) Encode() []byte {
@@ -1716,7 +1715,7 @@ func (msg *MouseClick) TypeID() int {
type CreateIFrameDocument struct {
message
FrameID uint64
- ID uint64
+ ID uint64
}
func (msg *CreateIFrameDocument) Encode() []byte {
@@ -1739,7 +1738,7 @@ func (msg *CreateIFrameDocument) TypeID() int {
type AdoptedSSReplaceURLBased struct {
message
SheetID uint64
- Text string
+ Text string
BaseURL string
}
@@ -1764,7 +1763,7 @@ func (msg *AdoptedSSReplaceURLBased) TypeID() int {
type AdoptedSSReplace struct {
message
SheetID uint64
- Text string
+ Text string
}
func (msg *AdoptedSSReplace) Encode() []byte {
@@ -1787,8 +1786,8 @@ func (msg *AdoptedSSReplace) TypeID() int {
type AdoptedSSInsertRuleURLBased struct {
message
SheetID uint64
- Rule string
- Index uint64
+ Rule string
+ Index uint64
BaseURL string
}
@@ -1814,8 +1813,8 @@ func (msg *AdoptedSSInsertRuleURLBased) TypeID() int {
type AdoptedSSInsertRule struct {
message
SheetID uint64
- Rule string
- Index uint64
+ Rule string
+ Index uint64
}
func (msg *AdoptedSSInsertRule) Encode() []byte {
@@ -1839,7 +1838,7 @@ func (msg *AdoptedSSInsertRule) TypeID() int {
type AdoptedSSDeleteRule struct {
message
SheetID uint64
- Index uint64
+ Index uint64
}
func (msg *AdoptedSSDeleteRule) Encode() []byte {
@@ -1862,7 +1861,7 @@ func (msg *AdoptedSSDeleteRule) TypeID() int {
type AdoptedSSAddOwner struct {
message
SheetID uint64
- ID uint64
+ ID uint64
}
func (msg *AdoptedSSAddOwner) Encode() []byte {
@@ -1885,7 +1884,7 @@ func (msg *AdoptedSSAddOwner) TypeID() int {
type AdoptedSSRemoveOwner struct {
message
SheetID uint64
- ID uint64
+ ID uint64
}
func (msg *AdoptedSSRemoveOwner) Encode() []byte {
@@ -1907,9 +1906,9 @@ func (msg *AdoptedSSRemoveOwner) TypeID() int {
type JSException struct {
message
- Name string
- Message string
- Payload string
+ Name string
+ Message string
+ Payload string
Metadata string
}
@@ -1935,7 +1934,7 @@ func (msg *JSException) TypeID() int {
type Zustand struct {
message
Mutation string
- State string
+ State string
}
func (msg *Zustand) Encode() []byte {
@@ -1957,9 +1956,9 @@ func (msg *Zustand) TypeID() int {
type BatchMeta struct {
message
- PageNo uint64
+ PageNo uint64
FirstIndex uint64
- Timestamp int64
+ Timestamp int64
}
func (msg *BatchMeta) Encode() []byte {
@@ -1982,11 +1981,11 @@ func (msg *BatchMeta) TypeID() int {
type BatchMetadata struct {
message
- Version uint64
- PageNo uint64
+ Version uint64
+ PageNo uint64
FirstIndex uint64
- Timestamp int64
- Location string
+ Timestamp int64
+ Location string
}
func (msg *BatchMetadata) Encode() []byte {
@@ -2011,7 +2010,7 @@ func (msg *BatchMetadata) TypeID() int {
type PartitionedMessage struct {
message
- PartNo uint64
+ PartNo uint64
PartTotal uint64
}
@@ -2034,14 +2033,14 @@ func (msg *PartitionedMessage) TypeID() int {
type NetworkRequest struct {
message
- Type string
- Method string
- URL string
- Request string
- Response string
- Status uint64
- Timestamp uint64
- Duration uint64
+ Type string
+ Method string
+ URL string
+ Request string
+ Response string
+ Status uint64
+ Timestamp uint64
+ Duration uint64
TransferredBodySize uint64
}
@@ -2069,14 +2068,45 @@ func (msg *NetworkRequest) TypeID() int {
return 83
}
+type WSChannel struct {
+ message
+ ChType string
+ ChannelName string
+ Data string
+ Timestamp uint64
+ Dir string
+ MessageType string
+}
+
+func (msg *WSChannel) Encode() []byte {
+ buf := make([]byte, 61+len(msg.ChType)+len(msg.ChannelName)+len(msg.Data)+len(msg.Dir)+len(msg.MessageType))
+ buf[0] = 84
+ p := 1
+ p = WriteString(msg.ChType, buf, p)
+ p = WriteString(msg.ChannelName, buf, p)
+ p = WriteString(msg.Data, buf, p)
+ p = WriteUint(msg.Timestamp, buf, p)
+ p = WriteString(msg.Dir, buf, p)
+ p = WriteString(msg.MessageType, buf, p)
+ return buf[:p]
+}
+
+func (msg *WSChannel) Decode() Message {
+ return msg
+}
+
+func (msg *WSChannel) TypeID() int {
+ return 84
+}
+
type InputChange struct {
message
- ID uint64
- Value string
- ValueMasked bool
- Label string
+ ID uint64
+ Value string
+ ValueMasked bool
+ Label string
HesitationTime int64
- InputDuration int64
+ InputDuration int64
}
func (msg *InputChange) Encode() []byte {
@@ -2103,8 +2133,8 @@ func (msg *InputChange) TypeID() int {
type SelectionChange struct {
message
SelectionStart uint64
- SelectionEnd uint64
- Selection string
+ SelectionEnd uint64
+ Selection string
}
func (msg *SelectionChange) Encode() []byte {
@@ -2169,16 +2199,16 @@ func (msg *UnbindNodes) TypeID() int {
type ResourceTiming struct {
message
- Timestamp uint64
- Duration uint64
- TTFB uint64
- HeaderSize uint64
+ Timestamp uint64
+ Duration uint64
+ TTFB uint64
+ HeaderSize uint64
EncodedBodySize uint64
DecodedBodySize uint64
- URL string
- Initiator string
+ URL string
+ Initiator string
TransferredSize uint64
- Cached bool
+ Cached bool
}
func (msg *ResourceTiming) Encode() []byte {
@@ -2273,13 +2303,13 @@ func (msg *CanvasNode) TypeID() int {
type IssueEvent struct {
message
- MessageID uint64
- Timestamp uint64
- Type string
+ MessageID uint64
+ Timestamp uint64
+ Type string
ContextString string
- Context string
- Payload string
- URL string
+ Context string
+ Payload string
+ URL string
}
func (msg *IssueEvent) Encode() []byte {
@@ -2306,7 +2336,7 @@ func (msg *IssueEvent) TypeID() int {
type SessionEnd struct {
message
- Timestamp uint64
+ Timestamp uint64
EncryptionKey string
}
@@ -2352,16 +2382,16 @@ func (msg *SessionSearch) TypeID() int {
type IOSSessionStart struct {
message
- Timestamp uint64
- ProjectID uint64
+ Timestamp uint64
+ ProjectID uint64
TrackerVersion string
- RevID string
- UserUUID string
- UserOS string
- UserOSVersion string
- UserDevice string
+ RevID string
+ UserUUID string
+ UserOS string
+ UserOSVersion string
+ UserDevice string
UserDeviceType string
- UserCountry string
+ UserCountry string
}
func (msg *IOSSessionStart) Encode() []byte {
@@ -2413,9 +2443,9 @@ func (msg *IOSSessionEnd) TypeID() int {
type IOSMetadata struct {
message
Timestamp uint64
- Length uint64
- Key string
- Value string
+ Length uint64
+ Key string
+ Value string
}
func (msg *IOSMetadata) Encode() []byte {
@@ -2440,9 +2470,9 @@ func (msg *IOSMetadata) TypeID() int {
type IOSEvent struct {
message
Timestamp uint64
- Length uint64
- Name string
- Payload string
+ Length uint64
+ Name string
+ Payload string
}
func (msg *IOSEvent) Encode() []byte {
@@ -2467,8 +2497,8 @@ func (msg *IOSEvent) TypeID() int {
type IOSUserID struct {
message
Timestamp uint64
- Length uint64
- ID string
+ Length uint64
+ ID string
}
func (msg *IOSUserID) Encode() []byte {
@@ -2492,8 +2522,8 @@ func (msg *IOSUserID) TypeID() int {
type IOSUserAnonymousID struct {
message
Timestamp uint64
- Length uint64
- ID string
+ Length uint64
+ ID string
}
func (msg *IOSUserAnonymousID) Encode() []byte {
@@ -2517,11 +2547,11 @@ func (msg *IOSUserAnonymousID) TypeID() int {
type IOSScreenChanges struct {
message
Timestamp uint64
- Length uint64
- X uint64
- Y uint64
- Width uint64
- Height uint64
+ Length uint64
+ X uint64
+ Y uint64
+ Width uint64
+ Height uint64
}
func (msg *IOSScreenChanges) Encode() []byte {
@@ -2547,10 +2577,10 @@ func (msg *IOSScreenChanges) TypeID() int {
type IOSCrash struct {
message
- Timestamp uint64
- Length uint64
- Name string
- Reason string
+ Timestamp uint64
+ Length uint64
+ Name string
+ Reason string
Stacktrace string
}
@@ -2576,11 +2606,11 @@ func (msg *IOSCrash) TypeID() int {
type IOSViewComponentEvent struct {
message
- Timestamp uint64
- Length uint64
+ Timestamp uint64
+ Length uint64
ScreenName string
- ViewName string
- Visible bool
+ ViewName string
+ Visible bool
}
func (msg *IOSViewComponentEvent) Encode() []byte {
@@ -2606,10 +2636,10 @@ func (msg *IOSViewComponentEvent) TypeID() int {
type IOSClickEvent struct {
message
Timestamp uint64
- Length uint64
- Label string
- X uint64
- Y uint64
+ Length uint64
+ Label string
+ X uint64
+ Y uint64
}
func (msg *IOSClickEvent) Encode() []byte {
@@ -2634,11 +2664,11 @@ func (msg *IOSClickEvent) TypeID() int {
type IOSInputEvent struct {
message
- Timestamp uint64
- Length uint64
- Value string
+ Timestamp uint64
+ Length uint64
+ Value string
ValueMasked bool
- Label string
+ Label string
}
func (msg *IOSInputEvent) Encode() []byte {
@@ -2664,9 +2694,9 @@ func (msg *IOSInputEvent) TypeID() int {
type IOSPerformanceEvent struct {
message
Timestamp uint64
- Length uint64
- Name string
- Value uint64
+ Length uint64
+ Name string
+ Value uint64
}
func (msg *IOSPerformanceEvent) Encode() []byte {
@@ -2691,9 +2721,9 @@ func (msg *IOSPerformanceEvent) TypeID() int {
type IOSLog struct {
message
Timestamp uint64
- Length uint64
- Severity string
- Content string
+ Length uint64
+ Severity string
+ Content string
}
func (msg *IOSLog) Encode() []byte {
@@ -2718,8 +2748,8 @@ func (msg *IOSLog) TypeID() int {
type IOSInternalError struct {
message
Timestamp uint64
- Length uint64
- Content string
+ Length uint64
+ Content string
}
func (msg *IOSInternalError) Encode() []byte {
@@ -2743,14 +2773,14 @@ func (msg *IOSInternalError) TypeID() int {
type IOSNetworkCall struct {
message
Timestamp uint64
- Length uint64
- Type string
- Method string
- URL string
- Request string
- Response string
- Status uint64
- Duration uint64
+ Length uint64
+ Type string
+ Method string
+ URL string
+ Request string
+ Response string
+ Status uint64
+ Duration uint64
}
func (msg *IOSNetworkCall) Encode() []byte {
@@ -2780,10 +2810,10 @@ func (msg *IOSNetworkCall) TypeID() int {
type IOSSwipeEvent struct {
message
Timestamp uint64
- Length uint64
- Label string
- X uint64
- Y uint64
+ Length uint64
+ Label string
+ X uint64
+ Y uint64
Direction string
}
@@ -2810,8 +2840,8 @@ func (msg *IOSSwipeEvent) TypeID() int {
type IOSBatchMeta struct {
message
- Timestamp uint64
- Length uint64
+ Timestamp uint64
+ Length uint64
FirstIndex uint64
}
@@ -2836,19 +2866,19 @@ func (msg *IOSBatchMeta) TypeID() int {
type IOSPerformanceAggregated struct {
message
TimestampStart uint64
- TimestampEnd uint64
- MinFPS uint64
- AvgFPS uint64
- MaxFPS uint64
- MinCPU uint64
- AvgCPU uint64
- MaxCPU uint64
- MinMemory uint64
- AvgMemory uint64
- MaxMemory uint64
- MinBattery uint64
- AvgBattery uint64
- MaxBattery uint64
+ TimestampEnd uint64
+ MinFPS uint64
+ AvgFPS uint64
+ MaxFPS uint64
+ MinCPU uint64
+ AvgCPU uint64
+ MaxCPU uint64
+ MinMemory uint64
+ AvgMemory uint64
+ MaxMemory uint64
+ MinBattery uint64
+ AvgBattery uint64
+ MaxBattery uint64
}
func (msg *IOSPerformanceAggregated) Encode() []byte {
@@ -2882,11 +2912,11 @@ func (msg *IOSPerformanceAggregated) TypeID() int {
type IOSIssueEvent struct {
message
- Timestamp uint64
- Type string
+ Timestamp uint64
+ Type string
ContextString string
- Context string
- Payload string
+ Context string
+ Payload string
}
func (msg *IOSIssueEvent) Encode() []byte {
@@ -2908,4 +2938,3 @@ func (msg *IOSIssueEvent) Decode() Message {
func (msg *IOSIssueEvent) TypeID() int {
return 111
}
-
diff --git a/backend/pkg/messages/read-message.go b/backend/pkg/messages/read-message.go
index 910922b8a..f71869977 100644
--- a/backend/pkg/messages/read-message.go
+++ b/backend/pkg/messages/read-message.go
@@ -1254,6 +1254,30 @@ func DecodeNetworkRequest(reader BytesReader) (Message, error) {
return msg, err
}
+func DecodeWSChannel(reader BytesReader) (Message, error) {
+ var err error = nil
+ msg := &WSChannel{}
+ if msg.ChType, err = reader.ReadString(); err != nil {
+ return nil, err
+ }
+ if msg.ChannelName, err = reader.ReadString(); err != nil {
+ return nil, err
+ }
+ if msg.Data, err = reader.ReadString(); err != nil {
+ return nil, err
+ }
+ if msg.Timestamp, err = reader.ReadUint(); err != nil {
+ return nil, err
+ }
+ if msg.Dir, err = reader.ReadString(); err != nil {
+ return nil, err
+ }
+ if msg.MessageType, err = reader.ReadString(); err != nil {
+ return nil, err
+ }
+ return msg, err
+}
+
func DecodeInputChange(reader BytesReader) (Message, error) {
var err error = nil
msg := &InputChange{}
@@ -1991,6 +2015,8 @@ func ReadMessage(t uint64, reader BytesReader) (Message, error) {
return DecodePartitionedMessage(reader)
case 83:
return DecodeNetworkRequest(reader)
+ case 84:
+ return DecodeWSChannel(reader)
case 112:
return DecodeInputChange(reader)
case 113:
diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py
index d5348a9e5..494af3793 100644
--- a/ee/connectors/msgcodec/messages.py
+++ b/ee/connectors/msgcodec/messages.py
@@ -723,6 +723,18 @@ class NetworkRequest(Message):
self.transferred_body_size = transferred_body_size
+class WSChannel(Message):
+ __id__ = 84
+
+ def __init__(self, ch_type, channel_name, data, timestamp, dir, message_type):
+ self.ch_type = ch_type
+ self.channel_name = channel_name
+ self.data = data
+ self.timestamp = timestamp
+ self.dir = dir
+ self.message_type = message_type
+
+
class InputChange(Message):
__id__ = 112
diff --git a/ee/connectors/msgcodec/messages.pyx b/ee/connectors/msgcodec/messages.pyx
index af0816b95..7e8df67fc 100644
--- a/ee/connectors/msgcodec/messages.pyx
+++ b/ee/connectors/msgcodec/messages.pyx
@@ -1069,6 +1069,25 @@ cdef class NetworkRequest(PyMessage):
self.transferred_body_size = transferred_body_size
+cdef class WSChannel(PyMessage):
+ cdef public int __id__
+ cdef public str ch_type
+ cdef public str channel_name
+ cdef public str data
+ cdef public unsigned long timestamp
+ cdef public str dir
+ cdef public str message_type
+
+ def __init__(self, str ch_type, str channel_name, str data, unsigned long timestamp, str dir, str message_type):
+ self.__id__ = 84
+ self.ch_type = ch_type
+ self.channel_name = channel_name
+ self.data = data
+ self.timestamp = timestamp
+ self.dir = dir
+ self.message_type = message_type
+
+
cdef class InputChange(PyMessage):
cdef public int __id__
cdef public unsigned long id
diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py
index 4aba0f775..fe3a34324 100644
--- a/ee/connectors/msgcodec/msgcodec.py
+++ b/ee/connectors/msgcodec/msgcodec.py
@@ -660,6 +660,16 @@ class MessageCodec(Codec):
transferred_body_size=self.read_uint(reader)
)
+ if message_id == 84:
+ return WSChannel(
+ ch_type=self.read_string(reader),
+ channel_name=self.read_string(reader),
+ data=self.read_string(reader),
+ timestamp=self.read_uint(reader),
+ dir=self.read_string(reader),
+ message_type=self.read_string(reader)
+ )
+
if message_id == 112:
return InputChange(
id=self.read_uint(reader),
diff --git a/ee/connectors/msgcodec/msgcodec.pyx b/ee/connectors/msgcodec/msgcodec.pyx
index c918be6ea..ff097f7d8 100644
--- a/ee/connectors/msgcodec/msgcodec.pyx
+++ b/ee/connectors/msgcodec/msgcodec.pyx
@@ -758,6 +758,16 @@ cdef class MessageCodec:
transferred_body_size=self.read_uint(reader)
)
+ if message_id == 84:
+ return WSChannel(
+ ch_type=self.read_string(reader),
+ channel_name=self.read_string(reader),
+ data=self.read_string(reader),
+ timestamp=self.read_uint(reader),
+ dir=self.read_string(reader),
+ message_type=self.read_string(reader)
+ )
+
if message_id == 112:
return InputChange(
id=self.read_uint(reader),
diff --git a/frontend/app/components/Session_/Player/Controls/EventsList.tsx b/frontend/app/components/Session_/Player/Controls/EventsList.tsx
index 860b6d0c5..7b8de8d6c 100644
--- a/frontend/app/components/Session_/Player/Controls/EventsList.tsx
+++ b/frontend/app/components/Session_/Player/Controls/EventsList.tsx
@@ -9,14 +9,15 @@ function EventsList({ scale }: { scale: number }) {
const { tabStates, eventCount } = store.get();
const events = React.useMemo(() => {
- return Object.values(tabStates)[0]?.eventList || [];
+ return Object.values(tabStates)[0]?.eventList.filter(e => e.time) || [];
}, [eventCount]);
+
return (
<>
{events.map((e) => (
@@ -35,7 +36,7 @@ function MobileEventsList({ scale }: { scale: number }) {
{events.map((e) => (
diff --git a/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx b/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx
index c8f3fc060..29e8f9fb8 100644
--- a/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx
+++ b/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx
@@ -18,6 +18,7 @@ import BottomBlock from '../BottomBlock';
import InfoLine from '../BottomBlock/InfoLine';
import useAutoscroll, { getLastItemTime } from '../useAutoscroll';
import { useRegExListFilterMemo, useTabListFilterMemo } from '../useListFilter';
+import WSModal from './WSModal'
const INDEX_KEY = 'network';
@@ -28,6 +29,7 @@ const CSS = 'css';
const IMG = 'img';
const MEDIA = 'media';
const OTHER = 'other';
+const WS = 'websocket';
const TYPE_TO_TAB = {
[ResourceType.XHR]: XHR,
@@ -36,10 +38,11 @@ const TYPE_TO_TAB = {
[ResourceType.CSS]: CSS,
[ResourceType.IMG]: IMG,
[ResourceType.MEDIA]: MEDIA,
+ [ResourceType.WS]: WS,
[ResourceType.OTHER]: OTHER,
};
-const TAP_KEYS = [ALL, XHR, JS, CSS, IMG, MEDIA, OTHER] as const;
+const TAP_KEYS = [ALL, XHR, JS, CSS, IMG, MEDIA, OTHER, WS] as const;
const TABS = TAP_KEYS.map((tab) => ({
text: tab === 'xhr' ? 'Fetch/XHR' : tab,
key: tab,
@@ -156,6 +159,8 @@ function NetworkPanelCont({ startedAt, panelHeight }: { startedAt: number; panel
resourceList = [],
fetchListNow = [],
resourceListNow = [],
+ websocketList = [],
+ websocketListNow = [],
} = tabStates[currentTab];
return (
@@ -170,11 +175,19 @@ function NetworkPanelCont({ startedAt, panelHeight }: { startedAt: number; panel
resourceListNow={resourceListNow}
player={player}
startedAt={startedAt}
+ websocketList={websocketList as WSMessage[]}
+ websocketListNow={websocketListNow as WSMessage[]}
/>
);
}
-function MobileNetworkPanelCont({ startedAt, panelHeight }: { startedAt: number, panelHeight: number }) {
+function MobileNetworkPanelCont({
+ startedAt,
+ panelHeight,
+}: {
+ startedAt: number;
+ panelHeight: number;
+}) {
const { player, store } = React.useContext(MobilePlayerContext);
const domContentLoadedTime = undefined;
@@ -185,6 +198,8 @@ function MobileNetworkPanelCont({ startedAt, panelHeight }: { startedAt: number,
resourceList = [],
fetchListNow = [],
resourceListNow = [],
+ websocketList = [],
+ websocketListNow = [],
} = store.get();
return (
@@ -200,10 +215,22 @@ function MobileNetworkPanelCont({ startedAt, panelHeight }: { startedAt: number,
resourceListNow={resourceListNow}
player={player}
startedAt={startedAt}
+ // @ts-ignore
+ websocketList={websocketList}
+ // @ts-ignore
+ websocketListNow={websocketListNow}
/>
);
}
+type WSMessage = Timed & {
+ channelName: string;
+ data: string;
+ timestamp: number;
+ dir: 'up' | 'down';
+ messageType: string;
+}
+
interface Props {
domContentLoadedTime?: {
time: number;
@@ -218,6 +245,8 @@ interface Props {
resourceList: Timed[];
fetchListNow: Timed[];
resourceListNow: Timed[];
+ websocketList: Array;
+ websocketListNow: Array;
player: WebPlayer | MobilePlayer;
startedAt: number;
isMobile?: boolean;
@@ -237,6 +266,7 @@ const NetworkPanelComp = observer(
startedAt,
isMobile,
panelHeight,
+ websocketList,
}: Props) => {
const { showModal } = useModal();
const [sortBy, setSortBy] = useState('time');
@@ -251,6 +281,14 @@ const NetworkPanelComp = observer(
const activeTab = devTools[INDEX_KEY].activeTab;
const activeIndex = devTools[INDEX_KEY].index;
+ const socketList = useMemo(
+ () =>
+ websocketList.filter(
+ (ws, i, arr) => arr.findIndex((it) => it.channelName === ws.channelName) === i
+ ),
+ [websocketList]
+ );
+
const list = useMemo(
() =>
// TODO: better merge (with body size info) - do it in player
@@ -283,8 +321,20 @@ const NetworkPanelComp = observer(
})
)
.concat(fetchList)
+ .concat(
+ socketList.map((ws) => ({
+ ...ws,
+ type: 'websocket',
+ method: 'ws',
+ url: ws.channelName,
+ name: ws.channelName,
+ status: '101',
+ duration: 0,
+ transferredBodySize: 0,
+ }))
+ )
.sort((a, b) => a.time - b.time),
- [resourceList.length, fetchList.length]
+ [resourceList.length, fetchList.length, socketList]
);
let filteredList = useMemo(() => {
@@ -354,6 +404,18 @@ const NetworkPanelComp = observer(
}, [domContentLoadedTime, loadTime]);
const showDetailsModal = (item: any) => {
+ if (item.type === 'websocket') {
+ const socketMsgList = websocketList.filter((ws) => ws.channelName === item.channelName);
+ console.log(socketMsgList)
+
+ return showModal(
+ , {
+ right: true, width: 700,
+ }
+ )
+ }
setIsDetailsModalActive(true);
showModal(
;
+}
+
+function WSModal({ socketMsgList }: Props) {
+ return (
+
+
+
+ {socketMsgList.map((msg) => (
+
+ ))}
+
+
+ );
+}
+
+function MsgDirection({ dir }: { dir: 'up' | 'down' }) {
+ return (
+
+ );
+}
+
+function Row({ msg }) {
+ const [isOpen, setIsOpen] = React.useState(false);
+
+ return (
+ <>
+ 100 ? 'hover:bg-active-blue cursor-pointer' : ''
+ }`}
+ onClick={() => (msg.data.length > 100 ? setIsOpen(!isOpen) : null)}
+ style={{ width: 700 }}
+ >
+
+
+
{msg.messageType}
+
+ {msg.data}
+
+ {msg.data.length > 100 ? (
+
+ {isOpen ? '-' : '+'}
+
+ ) : null}
+
+
{msg.data.length}
+
{durationFromMs(msg.time, true)}
+
+ {isOpen ? (
+
+ ) : null}
+ >
+ );
+}
+
+export default WSModal;
diff --git a/frontend/app/date.ts b/frontend/app/date.ts
index 38a240cdf..a87d5785e 100644
--- a/frontend/app/date.ts
+++ b/frontend/app/date.ts
@@ -44,10 +44,10 @@ export function durationFromMsFormatted(ms: number): string {
return durationFormatted(Duration.fromMillis(ms || 0));
}
-export function durationFromMs(ms: number): string {
+export function durationFromMs(ms: number, isFull?: boolean): string {
const dur = Duration.fromMillis(ms)
- return dur.toFormat('hh:mm:ss')
+ return dur.toFormat(`hh:mm:ss${ isFull ? '.SSS' : '' }`)
}
export const durationFormattedFull = (duration: Duration): string => {
diff --git a/frontend/app/player/mobile/IOSLists.tsx b/frontend/app/player/mobile/IOSLists.ts
similarity index 96%
rename from frontend/app/player/mobile/IOSLists.tsx
rename to frontend/app/player/mobile/IOSLists.ts
index 04c599633..fe983f3e2 100644
--- a/frontend/app/player/mobile/IOSLists.tsx
+++ b/frontend/app/player/mobile/IOSLists.ts
@@ -10,7 +10,7 @@ const SIMPLE_LIST_NAMES = [
"frustrations",
"performance"
] as const
-const MARKED_LIST_NAMES = [ "log", "resource", "fetch", "stack" ] as const
+const MARKED_LIST_NAMES = [ "log", "resource", "fetch", "stack", "websocket" ] as const
const LIST_NAMES = [...SIMPLE_LIST_NAMES, ...MARKED_LIST_NAMES ] as const
diff --git a/frontend/app/player/mobile/IOSMessageManager.ts b/frontend/app/player/mobile/IOSMessageManager.ts
index fe41a6f06..def6025fd 100644
--- a/frontend/app/player/mobile/IOSMessageManager.ts
+++ b/frontend/app/player/mobile/IOSMessageManager.ts
@@ -226,6 +226,9 @@ export default class IOSMessageManager implements IMessageManager {
case MType.IosNetworkCall:
this.lists.lists.fetch.insert(getResourceFromNetworkRequest(msg, this.sessionStart))
break;
+ case MType.WsChannel:
+ this.lists.lists.websocket.insert(msg)
+ break;
case MType.IosEvent:
// @ts-ignore
this.lists.lists.event.insert({...msg, source: 'openreplay'});
diff --git a/frontend/app/player/web/Lists.ts b/frontend/app/player/web/Lists.ts
index 113e58036..73021c4ac 100644
--- a/frontend/app/player/web/Lists.ts
+++ b/frontend/app/player/web/Lists.ts
@@ -4,7 +4,7 @@ import type { Timed } from '../common/types';
const SIMPLE_LIST_NAMES = [ "event", "redux", "mobx", "vuex", "zustand", "ngrx", "graphql", "exceptions", "profiles", "frustrations"] as const
-const MARKED_LIST_NAMES = [ "log", "resource", "fetch", "stack" ] as const
+const MARKED_LIST_NAMES = [ "log", "resource", "fetch", "stack", "websocket" ] as const
//const entityNamesSimple = [ "event", "profile" ];
const LIST_NAMES = [...SIMPLE_LIST_NAMES, ...MARKED_LIST_NAMES ] as const
diff --git a/frontend/app/player/web/TabManager.ts b/frontend/app/player/web/TabManager.ts
index 2dc7c3554..2534dad01 100644
--- a/frontend/app/player/web/TabManager.ts
+++ b/frontend/app/player/web/TabManager.ts
@@ -1,12 +1,21 @@
-import type { Store } from "Player";
-import { getResourceFromNetworkRequest, getResourceFromResourceTiming, Log, ResourceType } from "Player";
-import ListWalker from "Player/common/ListWalker";
-import Lists, { INITIAL_STATE as LISTS_INITIAL_STATE, InitialLists, State as ListsState } from "Player/web/Lists";
-import CanvasManager from "Player/web/managers/CanvasManager";
-import { VElement } from "Player/web/managers/DOM/VirtualDOM";
-import PagesManager from "Player/web/managers/PagesManager";
-import PerformanceTrackManager from "Player/web/managers/PerformanceTrackManager";
-import WindowNodeCounter from "Player/web/managers/WindowNodeCounter";
+import type { Store } from 'Player';
+import {
+ getResourceFromNetworkRequest,
+ getResourceFromResourceTiming,
+ Log,
+ ResourceType,
+} from 'Player';
+import ListWalker from 'Player/common/ListWalker';
+import Lists, {
+ INITIAL_STATE as LISTS_INITIAL_STATE,
+ InitialLists,
+ State as ListsState,
+} from 'Player/web/Lists';
+import CanvasManager from 'Player/web/managers/CanvasManager';
+import { VElement } from 'Player/web/managers/DOM/VirtualDOM';
+import PagesManager from 'Player/web/managers/PagesManager';
+import PerformanceTrackManager from 'Player/web/managers/PerformanceTrackManager';
+import WindowNodeCounter from 'Player/web/managers/WindowNodeCounter';
import {
CanvasNode,
ConnectionInformation,
@@ -15,22 +24,22 @@ import {
ResourceTiming,
SetPageLocation,
SetViewportScroll,
- SetViewportSize
-} from "Player/web/messages";
-import { isDOMType } from "Player/web/messages/filters.gen";
-import Screen from "Player/web/Screen/Screen";
+ SetViewportSize,
+} from 'Player/web/messages';
+import { isDOMType } from 'Player/web/messages/filters.gen';
+import Screen from 'Player/web/Screen/Screen';
// @ts-ignore
-import { Decoder } from "syncod";
-import { TYPES as EVENT_TYPES } from "Types/session/event";
-import type { PerformanceChartPoint } from "./managers/PerformanceTrackManager";
+import { Decoder } from 'syncod';
+import { TYPES as EVENT_TYPES } from 'Types/session/event';
+import type { PerformanceChartPoint } from './managers/PerformanceTrackManager';
export interface TabState extends ListsState {
- performanceAvailability?: PerformanceTrackManager['availability']
- performanceChartData: PerformanceChartPoint[],
- performanceChartTime: PerformanceChartPoint[]
- cssLoading: boolean
- location: string
- urlsList: SetPageLocation[]
+ performanceAvailability?: PerformanceTrackManager['availability'];
+ performanceChartData: PerformanceChartPoint[];
+ performanceChartTime: PerformanceChartPoint[];
+ cssLoading: boolean;
+ location: string;
+ urlsList: SetPageLocation[];
}
/**
@@ -46,10 +55,10 @@ export default class TabSessionManager {
cssLoading: false,
location: '',
urlsList: [],
- }
+ };
public locationManager: ListWalker = new ListWalker();
- private locationEventManager: ListWalker/**/ = new ListWalker();
+ private locationEventManager: ListWalker /**/ = new ListWalker();
private loadedLocationManager: ListWalker = new ListWalker();
private connectionInfoManger: ListWalker = new ListWalker();
private performanceTrackManager: PerformanceTrackManager = new PerformanceTrackManager();
@@ -61,8 +70,10 @@ export default class TabSessionManager {
public readonly decoder = new Decoder();
private lists: Lists;
- private navigationStartOffset = 0
- private canvasManagers: { [key: string]: { manager: CanvasManager, start: number, running: boolean } } = {}
+ private navigationStartOffset = 0;
+ private canvasManagers: {
+ [key: string]: { manager: CanvasManager; start: number; running: boolean };
+ } = {};
private canvasReplayWalker: ListWalker = new ListWalker();
constructor(
@@ -70,36 +81,37 @@ export default class TabSessionManager {
private readonly state: Store<{ tabStates: { [tabId: string]: TabState } }>,
private readonly screen: Screen,
private readonly id: string,
- private readonly setSize: ({ height, width }: { height: number, width: number }) => void,
+ private readonly setSize: ({ height, width }: { height: number; width: number }) => void,
private readonly sessionStart: number,
- initialLists?: Partial,
+ initialLists?: Partial
) {
- this.pagesManager = new PagesManager(screen, this.session.isMobile, this.setCSSLoading)
- this.lists = new Lists(initialLists)
- initialLists?.event?.forEach((e: Record) => { // TODO: to one of "Movable" module
+ this.pagesManager = new PagesManager(screen, this.session.isMobile, this.setCSSLoading);
+ this.lists = new Lists(initialLists);
+ initialLists?.event?.forEach((e: Record) => {
+ // TODO: to one of "Movable" module
if (e.type === EVENT_TYPES.LOCATION) {
this.locationEventManager.append(e);
}
- })
+ });
}
public getNode = (id: number) => {
- return this.pagesManager.getNode(id)
- }
+ return this.pagesManager.getNode(id);
+ };
public updateLists(lists: Partial) {
Object.keys(lists).forEach((key: 'event' | 'stack' | 'exceptions') => {
- const currentList = this.lists.lists[key]
- lists[key]!.forEach(item => currentList.insert(item))
- })
+ const currentList = this.lists.lists[key];
+ lists[key]!.forEach((item) => currentList.insert(item));
+ });
lists?.event?.forEach((e: Record) => {
if (e.type === EVENT_TYPES.LOCATION) {
this.locationEventManager.append(e);
}
- })
- const eventCount = lists?.event?.length || 0
+ });
+ const eventCount = lists?.event?.length || 0;
- const currentState = this.state.get()
+ const currentState = this.state.get();
this.state.update({
// @ts-ignore comes from parent state
eventCount: currentState.eventCount + eventCount,
@@ -108,9 +120,9 @@ export default class TabSessionManager {
[this.id]: {
...currentState.tabStates[this.id],
...this.lists.getFullListsState(),
- }
- }
- })
+ },
+ },
+ });
}
updateLocalState(state: Partial) {
@@ -119,22 +131,22 @@ export default class TabSessionManager {
...this.state.get().tabStates,
[this.id]: {
...this.state.get().tabStates[this.id],
- ...state
- }
- }
- })
+ ...state,
+ },
+ },
+ });
}
private setCSSLoading = (cssLoading: boolean) => {
- this.screen.displayFrame(!cssLoading)
+ this.screen.displayFrame(!cssLoading);
this.updateLocalState({
- cssLoading
- })
+ cssLoading,
+ });
this.state.update({
- // @ts-ignore
- ready: !this.state.get().messagesLoading && !cssLoading
- })
- }
+ // @ts-ignore
+ ready: !this.state.get().messagesLoading && !cssLoading,
+ });
+ };
public resetMessageManagers() {
this.locationEventManager = new ListWalker();
@@ -144,12 +156,11 @@ export default class TabSessionManager {
this.scrollManager = new ListWalker();
this.resizeManager = new ListWalker();
- this.performanceTrackManager = new PerformanceTrackManager()
+ this.performanceTrackManager = new PerformanceTrackManager();
this.windowNodeCounter = new WindowNodeCounter();
- this.pagesManager = new PagesManager(this.screen, this.session.isMobile, this.setCSSLoading)
+ this.pagesManager = new PagesManager(this.screen, this.session.isMobile, this.setCSSLoading);
}
-
distributeMessage(msg: Message): void {
switch (msg.tp) {
case MType.CanvasNode:
@@ -166,7 +177,6 @@ export default class TabSessionManager {
);
this.canvasManagers[managerId] = { manager, start: msg.timestamp, running: false };
this.canvasReplayWalker.append(msg);
-
}
break;
case MType.SetPageLocation:
@@ -185,7 +195,7 @@ export default class TabSessionManager {
this.performanceTrackManager.append(msg);
break;
case MType.SetPageVisibility:
- this.performanceTrackManager.handleVisibility(msg)
+ this.performanceTrackManager.handleVisibility(msg);
break;
case MType.ConnectionInformation:
this.connectionInfoManger.append(msg);
@@ -199,18 +209,23 @@ export default class TabSessionManager {
this.lists.lists.log.append(
// @ts-ignore : TODO: enums in the message schema
Log(msg)
- )
+ );
break;
case MType.ResourceTimingDeprecated:
case MType.ResourceTiming:
// TODO: merge `resource` and `fetch` lists into one here instead of UI
if (msg.initiator !== ResourceType.FETCH && msg.initiator !== ResourceType.XHR) {
- this.lists.lists.resource.insert(getResourceFromResourceTiming(msg as ResourceTiming, this.sessionStart))
+ this.lists.lists.resource.insert(
+ getResourceFromResourceTiming(msg as ResourceTiming, this.sessionStart)
+ );
}
break;
case MType.Fetch:
case MType.NetworkRequest:
- this.lists.lists.fetch.insert(getResourceFromNetworkRequest(msg, this.sessionStart))
+ this.lists.lists.fetch.insert(getResourceFromNetworkRequest(msg, this.sessionStart));
+ break;
+ case MType.WsChannel:
+ this.lists.lists.websocket.insert(msg);
break;
case MType.Redux:
this.lists.lists.redux.append(msg);
@@ -222,8 +237,8 @@ export default class TabSessionManager {
this.lists.lists.vuex.append(msg);
break;
case MType.Zustand:
- this.lists.lists.zustand.append(msg)
- break
+ this.lists.lists.zustand.append(msg);
+ break;
case MType.MobX:
this.lists.lists.mobx.append(msg);
break;
@@ -254,8 +269,8 @@ export default class TabSessionManager {
this.performanceTrackManager.setCurrentNodesCount(this.windowNodeCounter.count);
break;
}
- this.performanceTrackManager.addNodeCountPointIfNeed(msg.time)
- isDOMType(msg.tp) && this.pagesManager.appendMessage(msg)
+ this.performanceTrackManager.addNodeCountPointIfNeed(msg.time);
+ isDOMType(msg.tp) && this.pagesManager.appendMessage(msg);
break;
}
}
@@ -274,13 +289,13 @@ export default class TabSessionManager {
stateToUpdate.domContentLoadedTime = {
time: llEvent.domContentLoadedTime + this.navigationStartOffset, //TODO: predefined list of load event for the network tab (merge events & SetPageLocation: add navigationStart to db)
value: llEvent.domContentLoadedTime,
- }
+ };
}
if (llEvent.loadTime != null) {
stateToUpdate.loadTime = {
time: llEvent.loadTime + this.navigationStartOffset,
value: llEvent.loadTime,
- }
+ };
}
if (llEvent.domBuildingTime != null) {
stateToUpdate.domBuildingTime = llEvent.domBuildingTime;
@@ -290,7 +305,7 @@ export default class TabSessionManager {
const lastLocationMsg = this.locationManager.moveGetLast(t, index);
if (!!lastLocationMsg) {
// @ts-ignore comes from parent state
- this.state.update({ location: lastLocationMsg.url })
+ this.state.update({ location: lastLocationMsg.url });
}
// ConnectionInformation message is not used at this moment
// const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index);
@@ -303,40 +318,42 @@ export default class TabSessionManager {
stateToUpdate.performanceChartTime = lastPerformanceTrackMessage.time;
}
- Object.assign(stateToUpdate, this.lists.moveGetState(t))
+ Object.assign(stateToUpdate, this.lists.moveGetState(t));
Object.keys(stateToUpdate).length > 0 && this.updateLocalState(stateToUpdate);
/* Sequence of the managers is important here */
// Preparing the size of "screen"
const lastResize = this.resizeManager.moveGetLast(t, index);
if (!!lastResize) {
- this.setSize(lastResize)
+ this.setSize(lastResize);
}
this.pagesManager.moveReady(t).then(() => {
const lastScroll = this.scrollManager.moveGetLast(t, index);
if (!!lastScroll && this.screen.window) {
this.screen.window.scrollTo(lastScroll.x, lastScroll.y);
}
- const canvasMsg = this.canvasReplayWalker.moveGetLast(t)
+ const canvasMsg = this.canvasReplayWalker.moveGetLast(t);
if (canvasMsg) {
this.canvasManagers[`${canvasMsg.timestamp}_${canvasMsg.nodeId}`].manager.startVideo();
this.canvasManagers[`${canvasMsg.timestamp}_${canvasMsg.nodeId}`].running = true;
}
- const runningManagers = Object.keys(this.canvasManagers).filter((key) => this.canvasManagers[key].running);
+ const runningManagers = Object.keys(this.canvasManagers).filter(
+ (key) => this.canvasManagers[key].running
+ );
runningManagers.forEach((key) => {
const manager = this.canvasManagers[key].manager;
manager.move(t);
- })
- })
+ });
+ });
}
public decodeMessage(msg: Message) {
- return this.decoder.decode(msg)
+ return this.decoder.decode(msg);
}
public _sortMessagesHack = (msgs: Message[]) => {
// @ts-ignore Hack for upet (TODO: fix ordering in one mutation in tracker(removes first))
- const headChildrenIds = msgs.filter(m => m.parentID === 1).map(m => m.id);
+ const headChildrenIds = msgs.filter((m) => m.parentID === 1).map((m) => m.id);
this.pagesManager.sortPages((m1, m2) => {
if (m1.time === m2.time) {
if (m1.tp === MType.RemoveNode && m2.tp !== MType.RemoveNode) {
@@ -347,7 +364,7 @@ export default class TabSessionManager {
if (headChildrenIds.includes(m2.id)) {
return 1;
}
- } else if (m2.tp === MType.RemoveNode && m1.tp === MType.RemoveNode) {
+ } else if (m2.tp === MType.RemoveNode && m1.tp === MType.RemoveNode) {
const m1FromHead = headChildrenIds.includes(m1.id);
const m2FromHead = headChildrenIds.includes(m2.id);
if (m1FromHead && !m2FromHead) {
@@ -358,25 +375,25 @@ export default class TabSessionManager {
}
}
return 0;
- })
- }
+ });
+ };
public onFileReadSuccess = () => {
- const stateToUpdate : Partial> = {
+ const stateToUpdate: Partial> = {
performanceChartData: this.performanceTrackManager.chartData,
performanceAvailability: this.performanceTrackManager.availability,
urlsList: this.locationManager.list,
...this.lists.getFullListsState(),
- }
+ };
- this.updateLocalState(stateToUpdate)
- }
+ this.updateLocalState(stateToUpdate);
+ };
public getListsFullState = () => {
- return this.lists.getFullListsState()
- }
+ return this.lists.getFullListsState();
+ };
clean() {
- this.pagesManager.reset()
+ this.pagesManager.reset();
}
-}
\ No newline at end of file
+}
diff --git a/frontend/app/player/web/messages/RawMessageReader.gen.ts b/frontend/app/player/web/messages/RawMessageReader.gen.ts
index 793d3967e..a392655ba 100644
--- a/frontend/app/player/web/messages/RawMessageReader.gen.ts
+++ b/frontend/app/player/web/messages/RawMessageReader.gen.ts
@@ -651,6 +651,24 @@ export default class RawMessageReader extends PrimitiveReader {
};
}
+ case 84: {
+ const chType = this.readString(); if (chType === null) { return resetPointer() }
+ const channelName = this.readString(); if (channelName === null) { return resetPointer() }
+ const data = this.readString(); if (data === null) { return resetPointer() }
+ const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() }
+ const dir = this.readString(); if (dir === null) { return resetPointer() }
+ const messageType = this.readString(); if (messageType === null) { return resetPointer() }
+ return {
+ tp: MType.WsChannel,
+ chType,
+ channelName,
+ data,
+ timestamp,
+ dir,
+ messageType,
+ };
+ }
+
case 113: {
const selectionStart = this.readUint(); if (selectionStart === null) { return resetPointer() }
const selectionEnd = this.readUint(); if (selectionEnd === null) { return resetPointer() }
diff --git a/frontend/app/player/web/messages/message.gen.ts b/frontend/app/player/web/messages/message.gen.ts
index efc5d6cd6..b121ae69f 100644
--- a/frontend/app/player/web/messages/message.gen.ts
+++ b/frontend/app/player/web/messages/message.gen.ts
@@ -56,6 +56,7 @@ import type {
RawAdoptedSsRemoveOwner,
RawZustand,
RawNetworkRequest,
+ RawWsChannel,
RawSelectionChange,
RawMouseThrashing,
RawResourceTiming,
@@ -181,6 +182,8 @@ export type Zustand = RawZustand & Timed
export type NetworkRequest = RawNetworkRequest & Timed
+export type WsChannel = RawWsChannel & Timed
+
export type SelectionChange = RawSelectionChange & Timed
export type MouseThrashing = RawMouseThrashing & Timed
diff --git a/frontend/app/player/web/messages/raw.gen.ts b/frontend/app/player/web/messages/raw.gen.ts
index f808a7713..ca3af1886 100644
--- a/frontend/app/player/web/messages/raw.gen.ts
+++ b/frontend/app/player/web/messages/raw.gen.ts
@@ -54,6 +54,7 @@ export const enum MType {
AdoptedSsRemoveOwner = 77,
Zustand = 79,
NetworkRequest = 83,
+ WsChannel = 84,
SelectionChange = 113,
MouseThrashing = 114,
ResourceTiming = 116,
@@ -441,6 +442,16 @@ export interface RawNetworkRequest {
transferredBodySize: number,
}
+export interface RawWsChannel {
+ tp: MType.WsChannel,
+ chType: string,
+ channelName: string,
+ data: string,
+ timestamp: number,
+ dir: string,
+ messageType: string,
+}
+
export interface RawSelectionChange {
tp: MType.SelectionChange,
selectionStart: number,
@@ -575,4 +586,4 @@ export interface RawIosIssueEvent {
}
-export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawSelectionChange | RawMouseThrashing | RawResourceTiming | RawTabChange | RawTabData | RawCanvasNode | RawIosEvent | RawIosScreenChanges | RawIosClickEvent | RawIosInputEvent | RawIosPerformanceEvent | RawIosLog | RawIosInternalError | RawIosNetworkCall | RawIosSwipeEvent | RawIosIssueEvent;
+export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawWsChannel | RawSelectionChange | RawMouseThrashing | RawResourceTiming | RawTabChange | RawTabData | RawCanvasNode | RawIosEvent | RawIosScreenChanges | RawIosClickEvent | RawIosInputEvent | RawIosPerformanceEvent | RawIosLog | RawIosInternalError | RawIosNetworkCall | RawIosSwipeEvent | RawIosIssueEvent;
diff --git a/frontend/app/player/web/messages/tracker-legacy.gen.ts b/frontend/app/player/web/messages/tracker-legacy.gen.ts
index 5ee4cf6a0..09d7576c6 100644
--- a/frontend/app/player/web/messages/tracker-legacy.gen.ts
+++ b/frontend/app/player/web/messages/tracker-legacy.gen.ts
@@ -55,6 +55,7 @@ export const TP_MAP = {
77: MType.AdoptedSsRemoveOwner,
79: MType.Zustand,
83: MType.NetworkRequest,
+ 84: MType.WsChannel,
113: MType.SelectionChange,
114: MType.MouseThrashing,
116: MType.ResourceTiming,
diff --git a/frontend/app/player/web/messages/tracker.gen.ts b/frontend/app/player/web/messages/tracker.gen.ts
index d7042a355..6ad41e111 100644
--- a/frontend/app/player/web/messages/tracker.gen.ts
+++ b/frontend/app/player/web/messages/tracker.gen.ts
@@ -442,6 +442,16 @@ type TrNetworkRequest = [
transferredBodySize: number,
]
+type TrWSChannel = [
+ type: 84,
+ chType: string,
+ channelName: string,
+ data: string,
+ timestamp: number,
+ dir: string,
+ messageType: string,
+]
+
type TrInputChange = [
type: 112,
id: number,
@@ -500,7 +510,7 @@ type TrCanvasNode = [
]
-export type TrackerMessage = TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTiming | TrTabChange | TrTabData | TrCanvasNode
+export type TrackerMessage = TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrWSChannel | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTiming | TrTabChange | TrTabData | TrCanvasNode
export default function translate(tMsg: TrackerMessage): RawMessage | null {
switch(tMsg[0]) {
@@ -952,6 +962,18 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null {
}
}
+ case 84: {
+ return {
+ tp: MType.WsChannel,
+ chType: tMsg[1],
+ channelName: tMsg[2],
+ data: tMsg[3],
+ timestamp: tMsg[4],
+ dir: tMsg[5],
+ messageType: tMsg[6],
+ }
+ }
+
case 113: {
return {
tp: MType.SelectionChange,
diff --git a/frontend/app/player/web/types/resource.ts b/frontend/app/player/web/types/resource.ts
index ce2f3eb45..d76557e78 100644
--- a/frontend/app/player/web/types/resource.ts
+++ b/frontend/app/player/web/types/resource.ts
@@ -9,6 +9,7 @@ export const enum ResourceType {
CSS = 'css',
IMG = 'img',
MEDIA = 'media',
+ WS = 'websocket',
OTHER = 'other',
}
diff --git a/mobs/messages.rb b/mobs/messages.rb
index 538f1eeb4..9c6b7e0ba 100644
--- a/mobs/messages.rb
+++ b/mobs/messages.rb
@@ -458,6 +458,15 @@ message 83, 'NetworkRequest', :replayer => :devtools do
uint 'TransferredBodySize'
end
+message 84, 'WSChannel', :replayer => :devtools do
+ string 'ChType'
+ string 'ChannelName'
+ string 'Data'
+ uint 'Timestamp'
+ string 'Dir'
+ string 'MessageType'
+end
+
# 90-111 reserved iOS
message 112, 'InputChange', :replayer => false do
diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json
index 9a293089a..fce53ae94 100644
--- a/tracker/tracker/package.json
+++ b/tracker/tracker/package.json
@@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
- "version": "11.0.2",
+ "version": "11.0.0-beta.7",
"keywords": [
"logging",
"replay"
diff --git a/tracker/tracker/src/common/messages.gen.ts b/tracker/tracker/src/common/messages.gen.ts
index 46eda477e..188ba2caa 100644
--- a/tracker/tracker/src/common/messages.gen.ts
+++ b/tracker/tracker/src/common/messages.gen.ts
@@ -64,6 +64,7 @@ export declare const enum Type {
BatchMetadata = 81,
PartitionedMessage = 82,
NetworkRequest = 83,
+ WSChannel = 84,
InputChange = 112,
SelectionChange = 113,
MouseThrashing = 114,
@@ -512,6 +513,16 @@ export type NetworkRequest = [
/*transferredBodySize:*/ number,
]
+export type WSChannel = [
+ /*type:*/ Type.WSChannel,
+ /*chType:*/ string,
+ /*channelName:*/ string,
+ /*data:*/ string,
+ /*timestamp:*/ number,
+ /*dir:*/ string,
+ /*messageType:*/ string,
+]
+
export type InputChange = [
/*type:*/ Type.InputChange,
/*id:*/ number,
@@ -570,5 +581,5 @@ export type CanvasNode = [
]
-type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode
+type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode
export default Message
diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts
index 8565b2696..d11c57134 100644
--- a/tracker/tracker/src/main/app/index.ts
+++ b/tracker/tracker/src/main/app/index.ts
@@ -1,5 +1,13 @@
import type Message from './messages.gen.js'
-import { Timestamp, Metadata, UserID, Type as MType, TabChange, TabData } from './messages.gen.js'
+import {
+ Timestamp,
+ Metadata,
+ UserID,
+ Type as MType,
+ TabChange,
+ TabData,
+ WSChannel,
+} from './messages.gen.js'
import {
now,
adjustTimeOrigin,
@@ -812,6 +820,26 @@ export default class App {
return this.session.getTabId()
}
+ /**
+ * Creates a named hook that expects event name, data string and msg direction (up/down),
+ * it will skip any message bigger than 5 mb or event name bigger than 255 symbols
+ * @returns {(msgType: string, data: string, dir: 'up' | 'down') => void}
+ * */
+ trackWs(channelName: string): (msgType: string, data: string, dir: 'up' | 'down') => void {
+ const channel = channelName
+ return (msgType: string, data: string, dir: 'up' | 'down' = 'down') => {
+ if (
+ typeof msgType !== 'string' ||
+ typeof data !== 'string' ||
+ data.length > 5 * 1024 * 1024 ||
+ msgType.length > 255
+ ) {
+ return
+ }
+ this.send(WSChannel('websocket', channel, data, this.timestamp(), dir, msgType))
+ }
+ }
+
stop(stopWorker = true): void {
if (this.activityState !== ActivityState.NotActive) {
try {
diff --git a/tracker/tracker/src/main/app/messages.gen.ts b/tracker/tracker/src/main/app/messages.gen.ts
index f186a5f27..57b4722f9 100644
--- a/tracker/tracker/src/main/app/messages.gen.ts
+++ b/tracker/tracker/src/main/app/messages.gen.ts
@@ -817,6 +817,25 @@ export function NetworkRequest(
]
}
+export function WSChannel(
+ chType: string,
+ channelName: string,
+ data: string,
+ timestamp: number,
+ dir: string,
+ messageType: string,
+): Messages.WSChannel {
+ return [
+ Messages.Type.WSChannel,
+ chType,
+ channelName,
+ data,
+ timestamp,
+ dir,
+ messageType,
+ ]
+}
+
export function InputChange(
id: number,
value: string,
diff --git a/tracker/tracker/src/main/index.ts b/tracker/tracker/src/main/index.ts
index 3c70078a3..cf90f27a4 100644
--- a/tracker/tracker/src/main/index.ts
+++ b/tracker/tracker/src/main/index.ts
@@ -234,6 +234,20 @@ export default class API {
return this.app.active()
}
+ /**
+ * Creates a named hook that expects event name, data string and msg direction (up/down),
+ * it will skip any message bigger than 5 mb or event name bigger than 255 symbols
+ * msg direction is "down" (incoming) by default
+ *
+ * @returns {(msgType: string, data: string, dir: 'up' | 'down') => void}
+ * */
+ trackWs(channelName: string) {
+ if (this.app === null) {
+ return
+ }
+ return this.app.trackWs(channelName)
+ }
+
start(startOpts?: Partial): Promise {
if (!IN_BROWSER) {
console.error(
diff --git a/tracker/tracker/src/webworker/MessageEncoder.gen.ts b/tracker/tracker/src/webworker/MessageEncoder.gen.ts
index 4ae5cfbd3..cf9f4855e 100644
--- a/tracker/tracker/src/webworker/MessageEncoder.gen.ts
+++ b/tracker/tracker/src/webworker/MessageEncoder.gen.ts
@@ -258,6 +258,10 @@ export default class MessageEncoder extends PrimitiveEncoder {
return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.string(msg[4]) && this.string(msg[5]) && this.uint(msg[6]) && this.uint(msg[7]) && this.uint(msg[8]) && this.uint(msg[9])
break
+ case Messages.Type.WSChannel:
+ return this.string(msg[1]) && this.string(msg[2]) && this.string(msg[3]) && this.uint(msg[4]) && this.string(msg[5]) && this.string(msg[6])
+ break
+
case Messages.Type.InputChange:
return this.uint(msg[1]) && this.string(msg[2]) && this.boolean(msg[3]) && this.string(msg[4]) && this.int(msg[5]) && this.int(msg[6])
break