@multiplayer-app/session-recorder-browser 2.0.81-beta.0 → 2.0.83-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/socket-io.js +5329 -0
- package/dist/index.js +31057 -52972
- package/dist/index.umd.js +27501 -36001
- package/dist/observable.d.ts +9 -0
- package/dist/observable.js +39 -0
- package/dist/otel/instrumentations/index.d.ts +4 -1
- package/dist/otel/instrumentations/index.js +88 -88
- package/dist/services/socket.service.d.ts +1 -1
- package/dist/services/socket.service.js +3 -3
- package/dist/session-recorder.d.ts +1 -1
- package/dist/session-recorder.js +1 -1
- package/dist/sessionWidget/index.d.ts +1 -1
- package/dist/sessionWidget/index.js +1 -1
- package/dist/socket-io.index.js +22 -0
- package/dist/types/session-recorder.d.ts +1 -1
- package/package.json +12 -10
- package/dist/browser/index.js +0 -57124
- package/dist/exporters/index.js +0 -3
- package/dist/exporters/index.js.LICENSE.txt +0 -269
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class Observable<N extends string> {
|
|
2
|
+
protected _observers: Map<N, Set<Function>>;
|
|
3
|
+
on(name: N, f: Function): void;
|
|
4
|
+
once(name: N, f: Function): void;
|
|
5
|
+
off(name: N, f: Function): void;
|
|
6
|
+
emit(name: N, args: any[]): void;
|
|
7
|
+
destroy(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=observable.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export class Observable {
|
|
2
|
+
constructor() {
|
|
3
|
+
this._observers = new Map();
|
|
4
|
+
}
|
|
5
|
+
on(name, f) {
|
|
6
|
+
let listeners = this._observers.get(name);
|
|
7
|
+
if (!listeners) {
|
|
8
|
+
listeners = new Set();
|
|
9
|
+
this._observers.set(name, listeners);
|
|
10
|
+
}
|
|
11
|
+
listeners.add(f);
|
|
12
|
+
}
|
|
13
|
+
once(name, f) {
|
|
14
|
+
const _f = (...args) => {
|
|
15
|
+
this.off(name, _f);
|
|
16
|
+
f(...args);
|
|
17
|
+
};
|
|
18
|
+
this.on(name, _f);
|
|
19
|
+
}
|
|
20
|
+
off(name, f) {
|
|
21
|
+
const observers = this._observers.get(name);
|
|
22
|
+
if (observers) {
|
|
23
|
+
observers.delete(f);
|
|
24
|
+
if (observers.size === 0) {
|
|
25
|
+
this._observers.delete(name);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
emit(name, args) {
|
|
30
|
+
const listeners = this._observers.get(name);
|
|
31
|
+
if (listeners) {
|
|
32
|
+
Array.from(listeners).forEach((f) => f(...args));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
destroy() {
|
|
36
|
+
this._observers.clear();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=observable.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
|
|
2
|
+
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
|
|
3
|
+
import { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';
|
|
1
4
|
import { TracerBrowserConfig } from '../../types';
|
|
2
|
-
export declare const getInstrumentations: (config: TracerBrowserConfig) =>
|
|
5
|
+
export declare const getInstrumentations: (config: TracerBrowserConfig) => (XMLHttpRequestInstrumentation | FetchInstrumentation | UserInteractionInstrumentation)[];
|
|
3
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
|
|
2
|
+
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
|
|
3
|
+
import { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';
|
|
2
4
|
import { headersToObject, processHttpPayload, extractResponseBody, getElementInnerText, getElementTextContent, } from '../helpers';
|
|
3
5
|
import { OTEL_IGNORE_URLS } from '../../config';
|
|
4
6
|
export const getInstrumentations = (config) => {
|
|
5
7
|
return [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
new XMLHttpRequestInstrumentation({
|
|
9
|
+
clearTimingResources: true,
|
|
10
|
+
ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
|
|
11
|
+
propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
|
|
12
|
+
applyCustomAttributesOnSpan: (span, xhr) => {
|
|
13
|
+
if (!config)
|
|
14
|
+
return;
|
|
15
|
+
const { captureBody, captureHeaders } = config;
|
|
16
|
+
try {
|
|
17
|
+
if (!captureBody && !captureHeaders) {
|
|
13
18
|
return;
|
|
14
|
-
const { captureBody, captureHeaders } = config;
|
|
15
|
-
try {
|
|
16
|
-
if (!captureBody && !captureHeaders) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
const networkRequest = xhr.networkRequest;
|
|
21
|
-
const requestBody = networkRequest.requestBody;
|
|
22
|
-
const responseBody = networkRequest.responseBody;
|
|
23
|
-
const requestHeaders = networkRequest.requestHeaders || {};
|
|
24
|
-
const responseHeaders = networkRequest.responseHeaders || {};
|
|
25
|
-
const payload = {
|
|
26
|
-
requestBody,
|
|
27
|
-
responseBody,
|
|
28
|
-
requestHeaders,
|
|
29
|
-
responseHeaders,
|
|
30
|
-
};
|
|
31
|
-
processHttpPayload(payload, config, span);
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
// eslint-disable-next-line
|
|
35
|
-
console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture xml-http payload', error);
|
|
36
19
|
}
|
|
37
|
-
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
const networkRequest = xhr.networkRequest;
|
|
22
|
+
const requestBody = networkRequest.requestBody;
|
|
23
|
+
const responseBody = networkRequest.responseBody;
|
|
24
|
+
const requestHeaders = networkRequest.requestHeaders || {};
|
|
25
|
+
const responseHeaders = networkRequest.responseHeaders || {};
|
|
26
|
+
const payload = {
|
|
27
|
+
requestBody,
|
|
28
|
+
responseBody,
|
|
29
|
+
requestHeaders,
|
|
30
|
+
responseHeaders,
|
|
31
|
+
};
|
|
32
|
+
processHttpPayload(payload, config, span);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// eslint-disable-next-line
|
|
36
|
+
console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture xml-http payload', error);
|
|
37
|
+
}
|
|
38
38
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
}),
|
|
40
|
+
new FetchInstrumentation({
|
|
41
|
+
clearTimingResources: true,
|
|
42
|
+
ignoreUrls: [...OTEL_IGNORE_URLS, ...(config.ignoreUrls || [])],
|
|
43
|
+
propagateTraceHeaderCorsUrls: config.propagateTraceHeaderCorsUrls,
|
|
44
|
+
applyCustomAttributesOnSpan: async (span, request, response) => {
|
|
45
|
+
if (!config)
|
|
46
|
+
return;
|
|
47
|
+
const { captureBody, captureHeaders } = config;
|
|
48
|
+
try {
|
|
49
|
+
if (!captureBody && !captureHeaders) {
|
|
45
50
|
return;
|
|
46
|
-
const { captureBody, captureHeaders } = config;
|
|
47
|
-
try {
|
|
48
|
-
if (!captureBody && !captureHeaders) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
// Try to get data from our fetch wrapper first
|
|
52
|
-
// @ts-ignore
|
|
53
|
-
const networkRequest = response === null || response === void 0 ? void 0 : response.networkRequest;
|
|
54
|
-
let requestBody = null;
|
|
55
|
-
let responseBody = null;
|
|
56
|
-
let requestHeaders = {};
|
|
57
|
-
let responseHeaders = {};
|
|
58
|
-
if (networkRequest) {
|
|
59
|
-
// Use data captured by our fetch wrapper
|
|
60
|
-
requestBody = networkRequest.requestBody;
|
|
61
|
-
responseBody = networkRequest.responseBody;
|
|
62
|
-
requestHeaders = networkRequest.requestHeaders || {};
|
|
63
|
-
responseHeaders = networkRequest.responseHeaders || {};
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
// Fallback to original OpenTelemetry approach
|
|
67
|
-
requestBody = request.body;
|
|
68
|
-
requestHeaders = headersToObject(request.headers);
|
|
69
|
-
responseHeaders = headersToObject(response instanceof Response ? response.headers : undefined);
|
|
70
|
-
if (response instanceof Response && response.body) {
|
|
71
|
-
responseBody = await extractResponseBody(response);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const payload = {
|
|
75
|
-
requestBody,
|
|
76
|
-
responseBody,
|
|
77
|
-
requestHeaders,
|
|
78
|
-
responseHeaders,
|
|
79
|
-
};
|
|
80
|
-
processHttpPayload(payload, config, span);
|
|
81
51
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
52
|
+
// Try to get data from our fetch wrapper first
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
const networkRequest = response === null || response === void 0 ? void 0 : response.networkRequest;
|
|
55
|
+
let requestBody = null;
|
|
56
|
+
let responseBody = null;
|
|
57
|
+
let requestHeaders = {};
|
|
58
|
+
let responseHeaders = {};
|
|
59
|
+
if (networkRequest) {
|
|
60
|
+
// Use data captured by our fetch wrapper
|
|
61
|
+
requestBody = networkRequest.requestBody;
|
|
62
|
+
responseBody = networkRequest.responseBody;
|
|
63
|
+
requestHeaders = networkRequest.requestHeaders || {};
|
|
64
|
+
responseHeaders = networkRequest.responseHeaders || {};
|
|
85
65
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
66
|
+
else {
|
|
67
|
+
// Fallback to original OpenTelemetry approach
|
|
68
|
+
requestBody = request.body;
|
|
69
|
+
requestHeaders = headersToObject(request.headers);
|
|
70
|
+
responseHeaders = headersToObject(response instanceof Response ? response.headers : undefined);
|
|
71
|
+
if (response instanceof Response && response.body) {
|
|
72
|
+
responseBody = await extractResponseBody(response);
|
|
73
|
+
}
|
|
92
74
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
75
|
+
const payload = {
|
|
76
|
+
requestBody,
|
|
77
|
+
responseBody,
|
|
78
|
+
requestHeaders,
|
|
79
|
+
responseHeaders,
|
|
80
|
+
};
|
|
81
|
+
processHttpPayload(payload, config, span);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// eslint-disable-next-line
|
|
85
|
+
console.error('[MULTIPLAYER_SESSION_RECORDER] Failed to capture fetch payload', error);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
new UserInteractionInstrumentation({
|
|
90
|
+
shouldPreventSpanCreation: (_event, element, span) => {
|
|
91
|
+
if (span['parentSpanContext']) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
span.setAttribute('target.innerText', getElementInnerText(element));
|
|
95
|
+
span.setAttribute('target.textContent', getElementTextContent(element));
|
|
96
|
+
Array.from(element.attributes).forEach((attribute) => {
|
|
97
|
+
span.setAttribute(`target.attribute.${attribute.name}`, attribute.value);
|
|
98
|
+
});
|
|
99
|
+
return false;
|
|
100
100
|
},
|
|
101
101
|
}),
|
|
102
102
|
];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Observable } from '
|
|
1
|
+
import { Observable } from '../observable';
|
|
2
2
|
import { SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_SAVE_BUFFER_EVENT } from '../config';
|
|
3
3
|
import { type ISession, type IUserAttributes } from '@multiplayer-app/session-recorder-common';
|
|
4
4
|
export type SocketServiceEvents = typeof SESSION_STOPPED_EVENT | typeof SESSION_AUTO_CREATED | typeof REMOTE_SESSION_RECORDING_START | typeof REMOTE_SESSION_RECORDING_STOP | typeof SESSION_SAVE_BUFFER_EVENT;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Observable } from 'lib0/observable';
|
|
1
|
+
import { Observable } from '../observable';
|
|
3
2
|
import messagingService from '../services/messaging.service';
|
|
4
3
|
import { SESSION_ADD_EVENT, SESSION_AUTO_CREATED, SESSION_STOPPED_EVENT, SESSION_SUBSCRIBE_EVENT, SESSION_UNSUBSCRIBE_EVENT, SOCKET_SET_USER_EVENT, REMOTE_SESSION_RECORDING_START, REMOTE_SESSION_RECORDING_STOP, SESSION_STARTED_EVENT, SESSION_SAVE_BUFFER_EVENT, } from '../config';
|
|
5
4
|
import { ATTR_MULTIPLAYER_SESSION_CLIENT_ID, } from '@multiplayer-app/session-recorder-common';
|
|
@@ -60,12 +59,13 @@ export class SocketService extends Observable {
|
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
|
-
_initConnection() {
|
|
62
|
+
async _initConnection() {
|
|
64
63
|
if (this.isConnecting || this.isConnected || !this.isInitialized)
|
|
65
64
|
return;
|
|
66
65
|
this.attempts++;
|
|
67
66
|
this.isConnecting = true;
|
|
68
67
|
this.usePostMessage = false;
|
|
68
|
+
const { default: io } = await import(/* webpackChunkName: "socket-io" */ 'socket.io-client');
|
|
69
69
|
this.socket = io(this.options.socketUrl, {
|
|
70
70
|
path: '/v0/radar/ws',
|
|
71
71
|
auth: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Observable } from '
|
|
1
|
+
import { Observable } from './observable';
|
|
2
2
|
import { SessionType, type ISession, type IUserAttributes } from '@multiplayer-app/session-recorder-common';
|
|
3
3
|
import { SessionState, SessionRecorderOptions, SessionRecorderEvents } from './types';
|
|
4
4
|
import { ISessionRecorder } from './types';
|
package/dist/session-recorder.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Observable } from '
|
|
1
|
+
import { Observable } from '../observable';
|
|
2
2
|
import { SessionWidgetConfig, SessionState, ToastConfig } from '../types';
|
|
3
3
|
import { ButtonState, ContinuousRecordingSaveButtonState } from './buttonStateConfigs';
|
|
4
4
|
import './styles/button.scss';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Observable } from '
|
|
1
|
+
import { Observable } from '../observable';
|
|
2
2
|
import { insertTrustedHTML, injectStylesIntoShadowRoot, formatTimeForSessionTimer } from '../utils';
|
|
3
3
|
import { SessionState } from '../types';
|
|
4
4
|
import { POPOVER_WIDTH, NON_DRAGGABLE_OFFSET, POPOVER_DISTANCE_FROM_BUTTON, } from './constants';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as __WEBPACK_EXTERNAL_MODULE_socket_io_client_a48daf0e__ from "socket.io-client";
|
|
2
|
+
export const __webpack_esm_id__ = "socket-io";
|
|
3
|
+
export const __webpack_esm_ids__ = ["socket-io"];
|
|
4
|
+
export const __webpack_esm_modules__ = {
|
|
5
|
+
|
|
6
|
+
/***/ "socket.io-client"
|
|
7
|
+
/*!***********************************!*\
|
|
8
|
+
!*** external "socket.io-client" ***!
|
|
9
|
+
\***********************************/
|
|
10
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
11
|
+
|
|
12
|
+
var x = (y) => {
|
|
13
|
+
var x = {}; __webpack_require__.d(x, y); return x
|
|
14
|
+
}
|
|
15
|
+
var y = (x) => (() => (x))
|
|
16
|
+
module.exports = x({ ["default"]: () => (__WEBPACK_EXTERNAL_MODULE_socket_io_client_a48daf0e__["default"]) });
|
|
17
|
+
|
|
18
|
+
/***/ }
|
|
19
|
+
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=socket-io.index.js.map
|
|
@@ -4,7 +4,7 @@ import { PropagateTraceHeaderCorsUrls } from '@opentelemetry/sdk-trace-web';
|
|
|
4
4
|
import type { MaskTextFn, MaskInputFn, MaskInputOptions } from 'rrweb-snapshot';
|
|
5
5
|
import type { maskTextClass } from '@rrweb/types';
|
|
6
6
|
import { LogData } from '@rrweb/rrweb-plugin-console-record';
|
|
7
|
-
import { Observable } from '
|
|
7
|
+
import { Observable } from '../observable';
|
|
8
8
|
import type { NavigationRecorderPublicApi } from '../navigation';
|
|
9
9
|
export declare enum WidgetButtonPlacement {
|
|
10
10
|
topLeft = "top-left",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplayer-app/session-recorder-browser",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.83-beta.0",
|
|
4
4
|
"description": "Multiplayer Fullstack Session Recorder for Browser",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Multiplayer Software, Inc.",
|
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
"types": "./dist/index.d.ts",
|
|
29
29
|
"import": "./dist/index.js",
|
|
30
30
|
"require": "./dist/index.umd.js"
|
|
31
|
-
}
|
|
32
|
-
"./browser": "./dist/browser/index.js",
|
|
33
|
-
"./exporters": "./dist/exporters/index.js"
|
|
31
|
+
}
|
|
34
32
|
},
|
|
35
33
|
"engines": {
|
|
36
34
|
"node": ">=18",
|
|
@@ -50,8 +48,12 @@
|
|
|
50
48
|
"lint": "eslint 'src/**/*.ts' --config eslint.config.js",
|
|
51
49
|
"preversion": "npm run lint",
|
|
52
50
|
"postversion:skip": "git push && git push --tags",
|
|
53
|
-
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc && webpack",
|
|
54
|
-
"
|
|
51
|
+
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc && webpack --config-name esm --config-name umd && node scripts/sync-exports.js",
|
|
52
|
+
"build:browser": "webpack --config-name browser && node scripts/sync-exports.js",
|
|
53
|
+
"build:exporters": "webpack --config-name exporters && node scripts/sync-exports.js",
|
|
54
|
+
"build:extras": "webpack --config-name browser --config-name exporters && node scripts/sync-exports.js",
|
|
55
|
+
"build:all": "rm -rf dist tsconfig.tsbuildinfo && tsc && webpack && node scripts/sync-exports.js",
|
|
56
|
+
"prepublishOnly": "npm run build:all"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@types/node": "^22.0.0",
|
|
@@ -71,12 +73,13 @@
|
|
|
71
73
|
"webpack-cli": "5.1.4"
|
|
72
74
|
},
|
|
73
75
|
"dependencies": {
|
|
74
|
-
"@multiplayer-app/session-recorder-common": "2.0.
|
|
75
|
-
"@opentelemetry/auto-instrumentations-web": "0.49.0",
|
|
76
|
-
"@opentelemetry/context-zone": "2.0.1",
|
|
76
|
+
"@multiplayer-app/session-recorder-common": "2.0.83-beta.0",
|
|
77
77
|
"@opentelemetry/core": "2.0.1",
|
|
78
78
|
"@opentelemetry/exporter-trace-otlp-http": "0.203.0",
|
|
79
79
|
"@opentelemetry/instrumentation": "0.203.0",
|
|
80
|
+
"@opentelemetry/instrumentation-fetch": "0.203.0",
|
|
81
|
+
"@opentelemetry/instrumentation-user-interaction": "0.48.1",
|
|
82
|
+
"@opentelemetry/instrumentation-xml-http-request": "0.203.0",
|
|
80
83
|
"@opentelemetry/otlp-exporter-base": "0.203.0",
|
|
81
84
|
"@opentelemetry/otlp-transformer": "0.203.0",
|
|
82
85
|
"@opentelemetry/resources": "2.0.1",
|
|
@@ -86,7 +89,6 @@
|
|
|
86
89
|
"@rrweb/packer": "2.0.0-alpha.20",
|
|
87
90
|
"@rrweb/rrweb-plugin-console-record": "2.0.0-alpha.20",
|
|
88
91
|
"dompurify": "^3.4.2",
|
|
89
|
-
"lib0": "0.2.82",
|
|
90
92
|
"rrweb": "2.0.0-alpha.20",
|
|
91
93
|
"socket.io-client": "4.7.5",
|
|
92
94
|
"to-json-schema": "^0.2.5"
|