@multiplayer-app/session-recorder-node
Version:
Multiplayer Fullstack Session Recorder for Node.js
199 lines • 8.57 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionRecorder = void 0;
const session_recorder_common_1 = require("@multiplayer-app/session-recorder-common");
const api_service_1 = require("./services/api.service");
const helper_1 = require("./helper");
const config_1 = require("./config");
class SessionRecorder {
/**
* Initialize session recorder with default or custom configurations
*/
constructor() {
this._isInitialized = false;
this._shortSessionId = false;
this._sessionType = session_recorder_common_1.SessionType.PLAIN;
this._sessionState = 'STOPPED';
this._apiService = new api_service_1.ApiService();
this._sessionShortIdGenerator = session_recorder_common_1.SessionRecorderSdk.getIdGenerator(session_recorder_common_1.MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH);
this._resourceAttributes = {};
}
/**
* @description Initialize the session recorder
* @param apiKey - multiplayer otlp key
* @param traceIdGenerator - multiplayer compatible trace id generator
*/
init(config) {
var _a, _b;
this._resourceAttributes = config.resourceAttributes || {
[session_recorder_common_1.ATTR_MULTIPLAYER_SESSION_RECORDER_VERSION]: config_1.SESSION_RECORDER_VERSION
};
this._isInitialized = true;
if (typeof config.generateSessionShortIdLocally === 'function') {
this._sessionShortIdGenerator = config.generateSessionShortIdLocally;
}
if (!((_a = config === null || config === void 0 ? void 0 : config.apiKey) === null || _a === void 0 ? void 0 : _a.length)) {
throw new Error('Api key not provided');
}
if (!((_b = config === null || config === void 0 ? void 0 : config.traceIdGenerator) === null || _b === void 0 ? void 0 : _b.setSessionId)) {
throw new Error('Incompatible trace id generator');
}
this._traceIdGenerator = config.traceIdGenerator;
this._apiService.init({ apiKey: config.apiKey });
}
/**
* @description Start a new session
* @param {SessionType} SessionType - the type of session to start
* @param {ISession} [sessionPayload] - session metadata
* @returns {Promise<void>}
*/
async start(sessionType, sessionPayload) {
var _a;
if (!this._isInitialized) {
throw new Error('Configuration not initialized. Call init() before performing any actions.');
}
if ((sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.shortId)
&& ((_a = sessionPayload === null || sessionPayload === void 0 ? void 0 : sessionPayload.shortId) === null || _a === void 0 ? void 0 : _a.length) !== session_recorder_common_1.MULTIPLAYER_TRACE_DEBUG_SESSION_SHORT_ID_LENGTH) {
throw new Error('Invalid short session id');
}
sessionPayload = sessionPayload || {};
if (this._sessionState !== 'STOPPED') {
throw new Error('Session should be ended before starting new one.');
}
this._sessionType = sessionType;
let session;
sessionPayload.name = sessionPayload.name
? sessionPayload.name
: `Session on ${(0, helper_1.getFormattedDate)(Date.now())}`;
sessionPayload.resourceAttributes = {
...this._resourceAttributes,
...sessionPayload.resourceAttributes
};
if (this._sessionType === session_recorder_common_1.SessionType.CONTINUOUS) {
session = await this._apiService.startContinuousSession(sessionPayload);
}
else {
session = await this._apiService.startSession(sessionPayload);
}
this._shortSessionId = session.shortId;
this._traceIdGenerator.setSessionId(this._shortSessionId, this._sessionType);
this._sessionState = 'STARTED';
}
/**
* @description Save the continuous session
* @param {String} [reason]
* @returns {Promise<void>}
*/
static async save(reason) {
session_recorder_common_1.SessionRecorderSdk.saveContinuousSession(reason);
}
/**
* @description Save the continuous session
* @param {ISession} [sessionData]
* @returns {Promise<void>}
*/
async save(sessionData) {
try {
if (!this._isInitialized) {
throw new Error('Configuration not initialized. Call init() before performing any actions.');
}
if (this._sessionState === 'STOPPED'
|| typeof this._shortSessionId !== 'string') {
throw new Error('Session should be active or paused');
}
if (this._sessionType !== session_recorder_common_1.SessionType.CONTINUOUS) {
throw new Error('Invalid session type');
}
await this._apiService.saveContinuousSession(this._shortSessionId, {
...(sessionData || {}),
name: (sessionData === null || sessionData === void 0 ? void 0 : sessionData.name)
? sessionData.name
: `Session on ${(0, helper_1.getFormattedDate)(Date.now())}`
});
}
catch (e) {
throw e;
}
}
/**
* @description Stop the current session with an optional comment
* @param {ISession} [sessionData] - user-provided comment to include in session metadata
* @returns {Promise<void>}
*/
async stop(sessionData) {
try {
if (!this._isInitialized) {
throw new Error('Configuration not initialized. Call init() before performing any actions.');
}
if (this._sessionState === 'STOPPED'
|| typeof this._shortSessionId !== 'string') {
throw new Error('Session should be active or paused');
}
if (this._sessionType !== session_recorder_common_1.SessionType.PLAIN) {
throw new Error('Invalid session type');
}
await this._apiService.stopSession(this._shortSessionId, sessionData || {});
}
catch (e) {
throw e;
}
finally {
this._traceIdGenerator.setSessionId('');
this._shortSessionId = false;
this._sessionState = 'STOPPED';
}
}
/**
* @description Cancel the current session
* @returns {Promise<void>}
*/
async cancel() {
try {
if (!this._isInitialized) {
throw new Error('Configuration not initialized. Call init() before performing any actions.');
}
if (this._sessionState === 'STOPPED'
|| typeof this._shortSessionId !== 'string') {
throw new Error('Session should be active or paused');
}
if (this._sessionType === session_recorder_common_1.SessionType.CONTINUOUS) {
await this._apiService.stopContinuousSession(this._shortSessionId);
}
else if (this._sessionType === session_recorder_common_1.SessionType.PLAIN) {
await this._apiService.cancelSession(this._shortSessionId);
}
}
catch (e) {
throw e;
}
finally {
this._traceIdGenerator.setSessionId('');
this._shortSessionId = false;
this._sessionState = 'STOPPED';
}
}
/**
* @description Check if continuous session should be started/stopped automatically
* @param {ISession} [sessionPayload]
* @returns {Promise<void>}
*/
async checkRemoteContinuousSession(sessionPayload) {
if (!this._isInitialized) {
throw new Error('Configuration not initialized. Call init() before performing any actions.');
}
sessionPayload = sessionPayload || {};
sessionPayload.resourceAttributes = {
...(sessionPayload.resourceAttributes || {}),
...this._resourceAttributes,
};
const { state } = await this._apiService.checkRemoteSession(sessionPayload);
if (state == 'START' && this._sessionState !== 'STARTED') {
await this.start(session_recorder_common_1.SessionType.CONTINUOUS, sessionPayload);
}
else if (state == 'STOP' && this._sessionState !== 'STOPPED') {
await this.stop();
}
}
}
exports.SessionRecorder = SessionRecorder;
//# sourceMappingURL=sessionRecorder.js.map