From 3c9a9ec017602d60cab5da3aad5aac6063277c59 Mon Sep 17 00:00:00 2001 From: sylenien Date: Mon, 5 Sep 2022 12:23:11 +0200 Subject: [PATCH 001/185] fix(tracker): fix session url grabber --- tracker/tracker/package.json | 2 +- tracker/tracker/src/main/app/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 67511049e..0cb606dc5 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": "3.6.0", + "version": "3.6.1", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts index 2f9525164..10d53b22a 100644 --- a/tracker/tracker/src/main/app/index.ts +++ b/tracker/tracker/src/main/app/index.ts @@ -306,7 +306,7 @@ export default class App { return undefined } - return this.options.ingestPoint.replace(/\/ingest$/, `${projectID}/session/${sessionID}`) + return this.options.ingestPoint.replace(/ingest$/, `${projectID}/session/${sessionID}`) } getHost(): string { From fb6470628209f11a237b4a3564ea9f921e512df1 Mon Sep 17 00:00:00 2001 From: Mehdi Osman Date: Mon, 5 Sep 2022 13:44:28 +0200 Subject: [PATCH 002/185] Update .env.sample --- frontend/.env.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.env.sample b/frontend/.env.sample index 4972c59e4..e904fb376 100644 --- a/frontend/.env.sample +++ b/frontend/.env.sample @@ -23,4 +23,4 @@ MINIO_SECRET_KEY = '' # APP and TRACKER VERSIONS VERSION = '1.8.0' -TRACKER_VERSION = '3.6.0' +TRACKER_VERSION = '3.6.1' From bef74d5284675dbda36608ac590d8f012db008b9 Mon Sep 17 00:00:00 2001 From: Alexander Zavorotynskiy Date: Tue, 6 Sep 2022 14:35:16 +0200 Subject: [PATCH 003/185] feat(backend): skip corrupted batch --- backend/cmd/heuristics/main.go | 9 ++++++++- backend/pkg/messages/batch.go | 2 +- backend/pkg/messages/raw.go | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/cmd/heuristics/main.go b/backend/cmd/heuristics/main.go index 977cbda9d..49b3326bb 100644 --- a/backend/cmd/heuristics/main.go +++ b/backend/cmd/heuristics/main.go @@ -53,9 +53,16 @@ func main() { cfg.TopicRawWeb, }, func(sessionID uint64, iter messages.Iterator, meta *types.Meta) { + var lastMessageID uint64 for iter.Next() { statsLogger.Collect(sessionID, meta) - builderMap.HandleMessage(sessionID, iter.Message().Decode(), iter.Message().Meta().Index) + msg := iter.Message().Decode() + if msg == nil { + log.Printf("failed batch, sess: %d, lastIndex: %d", sessionID, lastMessageID) + continue + } + lastMessageID = msg.Meta().Index + builderMap.HandleMessage(sessionID, msg, iter.Message().Meta().Index) } }, false, diff --git a/backend/pkg/messages/batch.go b/backend/pkg/messages/batch.go index 955d0cfc0..7dd6172bd 100644 --- a/backend/pkg/messages/batch.go +++ b/backend/pkg/messages/batch.go @@ -90,7 +90,7 @@ func (i *iteratorImpl) Next() bool { switch i.msgType { case MsgBatchMetadata: if i.index != 0 { // Might be several 0-0 BatchMeta in a row without an error though - log.Printf("Batch Meta found at the end of the batch") + log.Printf("Batch Metadata found at the end of the batch") return false } m := i.msg.Decode().(*BatchMetadata) diff --git a/backend/pkg/messages/raw.go b/backend/pkg/messages/raw.go index daa59accd..b9dba5de2 100644 --- a/backend/pkg/messages/raw.go +++ b/backend/pkg/messages/raw.go @@ -54,6 +54,7 @@ func (m *RawMessage) Decode() Message { msg, err := ReadMessage(m.tp, bytes.NewReader(m.data[1:])) if err != nil { log.Printf("decode err: %s", err) + return nil } msg.Meta().SetMeta(m.meta) return msg From 4c4304a41984e5a46d0ce94f175f6fa86fbb0808 Mon Sep 17 00:00:00 2001 From: sylenien Date: Tue, 30 Aug 2022 16:19:31 +0200 Subject: [PATCH 004/185] feat(tracker): capture pinia state updates --- tracker/tracker-vuex/src/index.ts | 70 ++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/tracker/tracker-vuex/src/index.ts b/tracker/tracker-vuex/src/index.ts index 30333904e..68256dc20 100644 --- a/tracker/tracker-vuex/src/index.ts +++ b/tracker/tracker-vuex/src/index.ts @@ -1,10 +1,35 @@ -import { App, Messages } from '@openreplay/tracker'; +import { App, Messages } from "@openreplay/tracker"; import { Encoder, sha1 } from "./syncod/index.js"; export interface Options { filter: (mutation: any, state: any) => boolean; transformer: (state: any) => any; mutationTransformer: (mutation: any) => any; + storeName?: string; +} + +function processMutationAndState( + app: App, + options: Options, + encoder: Encoder, + mutation: any, + state: any +) { + if (options.filter(mutation, state)) { + try { + const { type } = mutation; + if (typeof type === "string" && type) { + app.send(Messages.StateAction(type)); + } + const _mutation = encoder.encode(options.mutationTransformer(mutation)); + const _state = encoder.encode(options.transformer(state)); + const _table = encoder.commit(); + for (let key in _table) app.send(Messages.OTable(key, _table[key])); + app.send(Messages.Vuex(_mutation, _state)); + } catch { + encoder.clear(); + } + } } export default function(opts: Partial = {}) { @@ -12,7 +37,8 @@ export default function(opts: Partial = {}) { { filter: () => true, transformer: state => state, - mutationTransformer: mutation => mutation + mutationTransformer: mutation => mutation, + storeName: undefined, }, opts ); @@ -21,26 +47,32 @@ export default function(opts: Partial = {}) { return Function.prototype; } const encoder = new Encoder(sha1, 50); + const state = {}; return store => { - store.subscribe((mutation, state) => { - if (options.filter(mutation, state)) { + // Vuex + if (store.subscribe) { + const randomId = Math.random().toString(36).substring(2, 9) + store.subscribe((mutation, storeState) => { + state[options.storeName || randomId] = state + processMutationAndState(app, options, encoder, mutation, storeState); + }); + } + + // Pinia + if (store.$onAction) { + store.$onAction(({ name, store, args }) => { try { - const { type } = mutation; - if (typeof type === 'string' && type) { - app.send(Messages.StateAction(type)); - } - const _mutation = encoder.encode( - options.mutationTransformer(mutation) - ); - const _state = encoder.encode(options.transformer(state)); - const _table = encoder.commit(); - for (let key in _table) app.send(Messages.OTable(key, _table[key])); - app.send(Messages.Vuex(_mutation, _state)); - } catch { - encoder.clear(); + state[options.storeName || store.$id] = store.$state; + const mutation = { + type: name, + payload: args + }; + processMutationAndState(app, options, encoder, mutation, state); + } catch (e) { + app.debug.error(e) } - } - }); + }); + } }; }; } From dff9cd92bfdca3bff4aa5ab5ed906c67a94e665c Mon Sep 17 00:00:00 2001 From: sylenien Date: Tue, 30 Aug 2022 16:29:10 +0200 Subject: [PATCH 005/185] feat(tracker): fix store name arg --- tracker/tracker-vuex/src/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tracker/tracker-vuex/src/index.ts b/tracker/tracker-vuex/src/index.ts index 68256dc20..37cd0d2cc 100644 --- a/tracker/tracker-vuex/src/index.ts +++ b/tracker/tracker-vuex/src/index.ts @@ -5,7 +5,6 @@ export interface Options { filter: (mutation: any, state: any) => boolean; transformer: (state: any) => any; mutationTransformer: (mutation: any) => any; - storeName?: string; } function processMutationAndState( @@ -38,7 +37,6 @@ export default function(opts: Partial = {}) { filter: () => true, transformer: state => state, mutationTransformer: mutation => mutation, - storeName: undefined, }, opts ); @@ -48,12 +46,12 @@ export default function(opts: Partial = {}) { } const encoder = new Encoder(sha1, 50); const state = {}; - return store => { + return (store, storeName) => { // Vuex if (store.subscribe) { const randomId = Math.random().toString(36).substring(2, 9) store.subscribe((mutation, storeState) => { - state[options.storeName || randomId] = state + state[storeName || randomId] = state processMutationAndState(app, options, encoder, mutation, storeState); }); } @@ -62,7 +60,7 @@ export default function(opts: Partial = {}) { if (store.$onAction) { store.$onAction(({ name, store, args }) => { try { - state[options.storeName || store.$id] = store.$state; + state[storeName || store.$id] = store.$state; const mutation = { type: name, payload: args From 0003e1130356f3feb72984df6cd626843e8fccba Mon Sep 17 00:00:00 2001 From: sylenien Date: Wed, 31 Aug 2022 09:47:29 +0200 Subject: [PATCH 006/185] fix(tracker): fix store naming --- tracker/tracker-vuex/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracker/tracker-vuex/src/index.ts b/tracker/tracker-vuex/src/index.ts index 37cd0d2cc..f8d8c1dba 100644 --- a/tracker/tracker-vuex/src/index.ts +++ b/tracker/tracker-vuex/src/index.ts @@ -46,7 +46,7 @@ export default function(opts: Partial = {}) { } const encoder = new Encoder(sha1, 50); const state = {}; - return (store, storeName) => { + return (storeName: string) => (store) => { // Vuex if (store.subscribe) { const randomId = Math.random().toString(36).substring(2, 9) From 96f563b0999bd499e302bbbec802ca953ed0f106 Mon Sep 17 00:00:00 2001 From: sylenien Date: Wed, 7 Sep 2022 15:53:41 +0200 Subject: [PATCH 007/185] change(tracker): change version to 4.0 --- tracker/tracker-vuex/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracker/tracker-vuex/package.json b/tracker/tracker-vuex/package.json index 005a9393c..69f43df64 100644 --- a/tracker/tracker-vuex/package.json +++ b/tracker/tracker-vuex/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-vuex", "description": "Tracker plugin for Vuex state recording", - "version": "3.0.0", + "version": "4.0.0", "keywords": [ "vuex", "logging", From a8f5eac861fbb3da655c6e18602c7dcfafe6d0e3 Mon Sep 17 00:00:00 2001 From: Mehdi Osman Date: Wed, 7 Sep 2022 18:33:45 +0200 Subject: [PATCH 008/185] Update .env.sample --- frontend/.env.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.env.sample b/frontend/.env.sample index e904fb376..00e148561 100644 --- a/frontend/.env.sample +++ b/frontend/.env.sample @@ -23,4 +23,4 @@ MINIO_SECRET_KEY = '' # APP and TRACKER VERSIONS VERSION = '1.8.0' -TRACKER_VERSION = '3.6.1' +TRACKER_VERSION = '4.0.0' From ec966902e33d5755ab1da7cbd0bd3bb3e07b0d26 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 21:40:42 +0100 Subject: [PATCH 009/185] feat(chalice): get replay resources from experimental table --- ee/api/chalicelib/core/__init__.py | 3 +++ ee/api/chalicelib/core/resources.py | 30 ++++++++++++++++++++--------- ee/api/env.default | 3 ++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/ee/api/chalicelib/core/__init__.py b/ee/api/chalicelib/core/__init__.py index 4f6268b65..550327129 100644 --- a/ee/api/chalicelib/core/__init__.py +++ b/ee/api/chalicelib/core/__init__.py @@ -42,3 +42,6 @@ if config("EXP_FUNNELS", cast=bool, default=False): from . import significance_exp as significance else: from . import significance as significance + +if config("EXP_RESOURCES", cast=bool, default=False): + print(">>> Using experimental resources for session-replay") diff --git a/ee/api/chalicelib/core/resources.py b/ee/api/chalicelib/core/resources.py index 71e493a4d..ad4f0da99 100644 --- a/ee/api/chalicelib/core/resources.py +++ b/ee/api/chalicelib/core/resources.py @@ -1,4 +1,4 @@ -from chalicelib.utils import helper +from chalicelib.utils import helper, exp_ch_helper from chalicelib.utils import ch_client from chalicelib.utils.TimeUTC import TimeUTC from decouple import config @@ -9,14 +9,26 @@ def get_by_session_id(session_id, project_id, start_ts, duration): if duration is None or (type(duration) != 'int' and type(duration) != 'float') or duration < 0: duration = 0 delta = config("events_ts_delta", cast=int, default=60 * 60) * 1000 - ch_query = """\ - SELECT - datetime,url,type,duration,ttfb,header_size,encoded_body_size,decoded_body_size,success,coalesce(status,if(success, 200, status)) AS status - FROM resources - WHERE session_id = toUInt64(%(session_id)s) - AND project_id=%(project_id)s - AND datetime >= toDateTime(%(res_start_ts)s / 1000) - AND datetime <= toDateTime(%(res_end_ts)s / 1000);""" + if config("EXP_RESOURCES", cast=bool, default=False): + ch_query = f"""SELECT + datetime,url,type,duration,ttfb,header_size, + encoded_body_size,decoded_body_size,success, + if(success, 200, 400) AS status + FROM {exp_ch_helper.get_main_resources_table(start_ts)} + WHERE session_id = toUInt16(%(session_id)s) + AND project_id=%(project_id)s + AND datetime >= toDateTime(%(res_start_ts)s / 1000) + AND datetime <= toDateTime(%(res_end_ts)s / 1000);""" + else: + ch_query = """SELECT + datetime,url,type,duration,ttfb,header_size, + encoded_body_size,decoded_body_size,success, + coalesce(status,if(success, 200, status)) AS status + FROM resources + WHERE session_id = toUInt64(%(session_id)s) + AND project_id=%(project_id)s + AND datetime >= toDateTime(%(res_start_ts)s / 1000) + AND datetime <= toDateTime(%(res_end_ts)s / 1000);""" params = {"session_id": session_id, "project_id": project_id, "start_ts": start_ts, "duration": duration, "res_start_ts": start_ts - delta, "res_end_ts": start_ts + duration + delta, } rows = ch.execute(query=ch_query, params=params) diff --git a/ee/api/env.default b/ee/api/env.default index 2d4a4c1e6..3a6ec44a4 100644 --- a/ee/api/env.default +++ b/ee/api/env.default @@ -66,4 +66,5 @@ EXP_ERRORS_SEARCH=false EXP_METRICS=false EXP_7D_MV=false EXP_ALERTS=false -EXP_FUNNELS=false \ No newline at end of file +EXP_FUNNELS=false +EXP_RESOURCES=true \ No newline at end of file From 46dcd82558a660a8169d9bccb415bcbcc67de37f Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 21:47:07 +0100 Subject: [PATCH 010/185] feat(chalice): handle unreachable sourcemap reader --- api/chalicelib/core/sourcemaps_parser.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/api/chalicelib/core/sourcemaps_parser.py b/api/chalicelib/core/sourcemaps_parser.py index 83116aed7..be6d83281 100644 --- a/api/chalicelib/core/sourcemaps_parser.py +++ b/api/chalicelib/core/sourcemaps_parser.py @@ -14,8 +14,15 @@ def get_original_trace(key, positions): "S3_SECRET": config('S3_SECRET'), "region": config('sessions_region') } - r = requests.post(config("sourcemaps_reader"), json=payload) - if r.status_code != 200: + try: + r = requests.post(config("sourcemaps_reader"), json=payload, + timeout=config("sourcemapTimeout", cast=int, default=5)) + if r.status_code != 200: + return {} + return r.json() + except requests.exceptions.Timeout: + print("Timeout getting sourcemap") + return {} + except Exception as e: + print("issue getting sourcemap") return {} - - return r.json() From 449ce64cb3d9e1f7d10108576d54c1f111ab554e Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 21:51:31 +0100 Subject: [PATCH 011/185] feat(chalice): sourcemaps reader support multi-envs --- api/chalicelib/core/sourcemaps_parser.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/api/chalicelib/core/sourcemaps_parser.py b/api/chalicelib/core/sourcemaps_parser.py index be6d83281..018441ae6 100644 --- a/api/chalicelib/core/sourcemaps_parser.py +++ b/api/chalicelib/core/sourcemaps_parser.py @@ -9,11 +9,12 @@ def get_original_trace(key, positions): "positions": positions, "padding": 5, "bucket": config('sourcemaps_bucket'), - "S3_HOST": config('S3_HOST'), - "S3_KEY": config('S3_KEY'), - "S3_SECRET": config('S3_SECRET'), - "region": config('sessions_region') + "S3_KEY": config('S3_KEY', default=config('AWS_ACCESS_KEY_ID')), + "S3_SECRET": config('S3_SECRET', default=config('AWS_SECRET_ACCESS_KEY')), + "region": config('sessions_region', default=config('AWS_DEFAULT_REGION')) } + if len(config('S3_HOST', default="")) > 0: + payload["S3_HOST"] = config('S3_HOST') try: r = requests.post(config("sourcemaps_reader"), json=payload, timeout=config("sourcemapTimeout", cast=int, default=5)) From 5f6b1e65ea9752f24ee2a5644c231409702d79f4 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 21:55:38 +0100 Subject: [PATCH 012/185] feat(chalice): sourcemap clean log --- api/chalicelib/core/sourcemaps.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/api/chalicelib/core/sourcemaps.py b/api/chalicelib/core/sourcemaps.py index 73341cb4d..4bd0606b7 100644 --- a/api/chalicelib/core/sourcemaps.py +++ b/api/chalicelib/core/sourcemaps.py @@ -80,12 +80,7 @@ def get_traces_group(project_id, payload): payloads = {} all_exists = True for i, u in enumerate(frames): - print("===============================") - print(u["absPath"]) - print("converted to:") key = __get_key(project_id, u["absPath"]) # use filename instead? - print(key) - print("===============================") if key not in payloads: file_exists = s3.exists(config('sourcemaps_bucket'), key) all_exists = all_exists and file_exists From 68310653efbff81f14e18d215900261d77aca1e1 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 22:20:43 +0100 Subject: [PATCH 013/185] feat(sourcemaps-reader): logs --- sourcemap-reader/server.js | 8 ++++---- sourcemap-reader/servers/sourcemaps-handler.js | 8 ++++---- sourcemap-reader/servers/sourcemaps-server.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sourcemap-reader/server.js b/sourcemap-reader/server.js index 073cb4cfc..c67e50428 100644 --- a/sourcemap-reader/server.js +++ b/sourcemap-reader/server.js @@ -3,17 +3,17 @@ const sourcemapsReaderServer = require('./servers/sourcemaps-server'); const express = require('express'); const {request_logger} = require("./utils/helper"); -const HOST = '0.0.0.0'; -const PORT = 9000; +const HOST = process.env.MAIN_HOST || '127.0.0.1'; +const PORT = process.env.MAIN_PORT || 9000; const app = express(); -app.use(request_logger("[wsapp]")); +app.use(request_logger("[SR]")); app.use('/sourcemaps', sourcemapsReaderServer); app.use('/heapdump', dumps.router); const server = app.listen(PORT, HOST, () => { - console.log(`WS App listening on http://${HOST}:${PORT}`); + console.log(`SR App listening on http://${HOST}:${PORT}`); console.log('Press Ctrl+C to quit.'); }); module.exports = {server}; \ No newline at end of file diff --git a/sourcemap-reader/servers/sourcemaps-handler.js b/sourcemap-reader/servers/sourcemaps-handler.js index 25185ffa3..de9af4220 100644 --- a/sourcemap-reader/servers/sourcemaps-handler.js +++ b/sourcemap-reader/servers/sourcemaps-handler.js @@ -42,8 +42,8 @@ module.exports.sourcemapReader = async event => { return new Promise(function (resolve, reject) { s3.getObject(options, (err, data) => { if (err) { - console.log("Get S3 object failed"); - console.log(err); + console.error("[SR] Get S3 object failed"); + console.error(err); return reject(err); } let sourcemap = data.Body.toString(); @@ -68,13 +68,13 @@ module.exports.sourcemapReader = async event => { preview = preview.slice(start, original.line + event.padding); } } else { - console.log("source not found, null preview for:"); + console.log("[SR] source not found, null preview for:"); console.log(original.source); preview = [] } url = URL.parse(original.source); } else { - console.log("couldn't find original position of:"); + console.log("[SR] couldn't find original position of:"); console.log({ line: event.positions[i].line, column: event.positions[i].column diff --git a/sourcemap-reader/servers/sourcemaps-server.js b/sourcemap-reader/servers/sourcemaps-server.js index ced43125c..7ac6da992 100644 --- a/sourcemap-reader/servers/sourcemaps-server.js +++ b/sourcemap-reader/servers/sourcemaps-server.js @@ -9,7 +9,7 @@ router.post('/', (req, res) => { }); req.on('end', function () { data = JSON.parse(data); - console.log("Starting parser for: " + data.key); + console.log("[SR] Starting parser for: " + data.key); // process.env = {...process.env, ...data.bucket_config}; handler.sourcemapReader(data) .then((results) => { @@ -18,7 +18,7 @@ router.post('/', (req, res) => { res.end(JSON.stringify(results)); }) .catch((e) => { - console.error("Something went wrong"); + console.error("[SR] Something went wrong"); console.error(e); res.statusCode(500); res.end(e); From 63500e64cdefc53b55d319d1f10245b67f3c2dc9 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Wed, 7 Sep 2022 22:41:01 +0100 Subject: [PATCH 014/185] feat(assist): socket error handler on connection --- ee/utilities/servers/websocket-cluster.js | 2 +- ee/utilities/servers/websocket.js | 2 +- sourcemap-reader/server.js | 4 ++-- utilities/servers/websocket.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ee/utilities/servers/websocket-cluster.js b/ee/utilities/servers/websocket-cluster.js index 4f310468a..bc68be6aa 100644 --- a/ee/utilities/servers/websocket-cluster.js +++ b/ee/utilities/servers/websocket-cluster.js @@ -283,6 +283,7 @@ module.exports = { start: (server, prefix) => { createSocketIOServer(server, prefix); io.on('connection', async (socket) => { + socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); debug && console.log(`WS started:${socket.id}, Query:${JSON.stringify(socket.handshake.query)}`); socket._connectedAt = new Date(); socket.peerId = socket.handshake.query.peerId; @@ -351,7 +352,6 @@ module.exports = { socket.on(EVENTS_DEFINITION.listen.CONNECT_ERROR, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_ERROR, err)); socket.on(EVENTS_DEFINITION.listen.CONNECT_FAILED, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_FAILED, err)); - socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); socket.onAny(async (eventName, ...args) => { if (Object.values(EVENTS_DEFINITION.listen).indexOf(eventName) >= 0) { diff --git a/ee/utilities/servers/websocket.js b/ee/utilities/servers/websocket.js index 224f44490..11685ee78 100644 --- a/ee/utilities/servers/websocket.js +++ b/ee/utilities/servers/websocket.js @@ -261,6 +261,7 @@ module.exports = { start: (server, prefix) => { createSocketIOServer(server, prefix); io.on('connection', async (socket) => { + socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); debug && console.log(`WS started:${socket.id}, Query:${JSON.stringify(socket.handshake.query)}`); socket._connectedAt = new Date(); socket.peerId = socket.handshake.query.peerId; @@ -327,7 +328,6 @@ module.exports = { socket.on(EVENTS_DEFINITION.listen.CONNECT_ERROR, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_ERROR, err)); socket.on(EVENTS_DEFINITION.listen.CONNECT_FAILED, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_FAILED, err)); - socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); socket.onAny(async (eventName, ...args) => { if (Object.values(EVENTS_DEFINITION.listen).indexOf(eventName) >= 0) { diff --git a/sourcemap-reader/server.js b/sourcemap-reader/server.js index c67e50428..327994042 100644 --- a/sourcemap-reader/server.js +++ b/sourcemap-reader/server.js @@ -3,8 +3,8 @@ const sourcemapsReaderServer = require('./servers/sourcemaps-server'); const express = require('express'); const {request_logger} = require("./utils/helper"); -const HOST = process.env.MAIN_HOST || '127.0.0.1'; -const PORT = process.env.MAIN_PORT || 9000; +const HOST = process.env.SR_HOST || '127.0.0.1'; +const PORT = process.env.SR_PORT || 9000; const app = express(); app.use(request_logger("[SR]")); diff --git a/utilities/servers/websocket.js b/utilities/servers/websocket.js index 70c472e67..351ce5be2 100644 --- a/utilities/servers/websocket.js +++ b/utilities/servers/websocket.js @@ -242,6 +242,7 @@ module.exports = { start: (server, prefix) => { createSocketIOServer(server, prefix); io.on('connection', async (socket) => { + socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); debug && console.log(`WS started:${socket.id}, Query:${JSON.stringify(socket.handshake.query)}`); socket._connectedAt = new Date(); socket.peerId = socket.handshake.query.peerId; @@ -308,7 +309,6 @@ module.exports = { socket.on(EVENTS_DEFINITION.listen.CONNECT_ERROR, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_ERROR, err)); socket.on(EVENTS_DEFINITION.listen.CONNECT_FAILED, err => errorHandler(EVENTS_DEFINITION.listen.CONNECT_FAILED, err)); - socket.on(EVENTS_DEFINITION.listen.ERROR, err => errorHandler(EVENTS_DEFINITION.listen.ERROR, err)); socket.onAny(async (eventName, ...args) => { if (Object.values(EVENTS_DEFINITION.listen).indexOf(eventName) >= 0) { From d8f1d362b6cc172e0a4d10070eeba030628af8af Mon Sep 17 00:00:00 2001 From: sylenien Date: Thu, 8 Sep 2022 10:42:17 +0200 Subject: [PATCH 015/185] change(tracker): change version to 4.0 --- tracker/tracker-assist/package.json | 2 +- tracker/tracker/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tracker/tracker-assist/package.json b/tracker/tracker-assist/package.json index f7f20cc39..ba5dad088 100644 --- a/tracker/tracker-assist/package.json +++ b/tracker/tracker-assist/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-assist", "description": "Tracker plugin for screen assistance through the WebRTC", - "version": "3.6.0", + "version": "4.0.0", "keywords": [ "WebRTC", "assistance", diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 0cb606dc5..59ca4bb50 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": "3.6.1", + "version": "4.0.0", "keywords": [ "logging", "replay" From e189b3fef58ca55e8f74cb96d1fc21c69c48a5d5 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 8 Sep 2022 12:08:09 +0100 Subject: [PATCH 016/185] feat(peers): uncaughtException handler feat(peers): sub-dependencies upgrade --- ee/utilities/server.js | 2 +- peers/package-lock.json | 206 ++++++++++++++++----------------- peers/server.js | 13 ++- peers/servers/peerjs-server.js | 6 +- utilities/server.js | 3 +- 5 files changed, 119 insertions(+), 111 deletions(-) diff --git a/ee/utilities/server.js b/ee/utilities/server.js index 13a89be79..f80059a00 100644 --- a/ee/utilities/server.js +++ b/ee/utilities/server.js @@ -8,7 +8,7 @@ if (process.env.redis === "true") { socket = require("./servers/websocket"); } -const HOST = '0.0.0.0'; +const HOST = process.env.LISTEN_HOST || '0.0.0.0'; const PORT = process.env.LISTEN_PORT || 9001; let debug = process.env.debug === "1" || false; diff --git a/peers/package-lock.json b/peers/package-lock.json index 043a3ba6d..a903cfd08 100644 --- a/peers/package-lock.json +++ b/peers/package-lock.json @@ -47,9 +47,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.30", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz", + "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -57,14 +57,14 @@ } }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/node": { - "version": "17.0.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", - "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==" + "version": "18.7.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", + "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" }, "node_modules/@types/qs": { "version": "6.9.7", @@ -77,11 +77,11 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "dependencies": { - "@types/mime": "^1", + "@types/mime": "*", "@types/node": "*" } }, @@ -130,7 +130,7 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/body-parser": { "version": "1.20.0", @@ -175,6 +175,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -231,7 +239,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -256,7 +264,7 @@ "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } @@ -504,7 +512,7 @@ "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } @@ -512,12 +520,12 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } @@ -534,19 +542,19 @@ } }, "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -555,7 +563,7 @@ "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/negotiator": { "version": "0.6.3", @@ -568,7 +576,7 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } @@ -644,7 +652,7 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/peer": { "version": "0.6.1", @@ -668,15 +676,6 @@ "node": ">=10" } }, - "node_modules/peer/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -728,7 +727,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } @@ -807,7 +806,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -890,15 +889,24 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } @@ -906,7 +914,7 @@ "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "node_modules/wrap-ansi": { "version": "6.2.0", @@ -922,9 +930,9 @@ } }, "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "engines": { "node": ">=8.3.0" }, @@ -978,14 +986,6 @@ "engines": { "node": ">=6" } - }, - "node_modules/yargs-parser/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } } }, "dependencies": { @@ -1023,9 +1023,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.30", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz", + "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -1033,14 +1033,14 @@ } }, "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/node": { - "version": "17.0.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", - "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==" + "version": "18.7.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", + "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" }, "@types/qs": { "version": "6.9.7", @@ -1053,11 +1053,11 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "requires": { - "@types/mime": "^1", + "@types/mime": "*", "@types/node": "*" } }, @@ -1094,7 +1094,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "body-parser": { "version": "1.20.0", @@ -1129,6 +1129,11 @@ "get-intrinsic": "^1.0.2" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -1173,7 +1178,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "cors": { "version": "2.8.5", @@ -1195,7 +1200,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "depd": { "version": "2.0.0", @@ -1382,17 +1387,17 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "mime": { "version": "1.6.0", @@ -1400,22 +1405,22 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "negotiator": { "version": "0.6.3", @@ -1425,7 +1430,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.2", @@ -1474,7 +1479,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "peer": { "version": "0.6.1", @@ -1490,13 +1495,6 @@ "uuid": "^3.4.0", "ws": "^7.2.3", "yargs": "^15.3.1" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "proxy-addr": { @@ -1535,7 +1533,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-main-filename": { "version": "2.0.0", @@ -1593,7 +1591,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setprototypeof": { "version": "1.2.0", @@ -1655,17 +1653,22 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "wrap-ansi": { "version": "6.2.0", @@ -1678,9 +1681,9 @@ } }, "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "requires": {} }, "y18n": { @@ -1713,13 +1716,6 @@ "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } } } } diff --git a/peers/server.js b/peers/server.js index 39f46d4f1..cea4e94f2 100644 --- a/peers/server.js +++ b/peers/server.js @@ -4,8 +4,9 @@ const {peerRouter, peerConnection, peerDisconnect, peerError} = require('./serve const express = require('express'); const {ExpressPeerServer} = require('peer'); -const HOST = '0.0.0.0'; -const PORT = 9000; +const debug = process.env.debug === "1" || false; +const HOST = process.env.LISTEN_HOST || '0.0.0.0'; +const PORT = process.env.LISTEN_PORT || 9000; const app = express(); @@ -30,4 +31,10 @@ peerServer.on('disconnect', peerDisconnect); peerServer.on('error', peerError); app.use('/', peerServer); app.enable('trust proxy'); -module.exports = {server}; \ No newline at end of file +module.exports = {server}; + +process.on('uncaughtException', err => { + console.log(`Uncaught Exception: ${err.message}`); + debug && console.log(err.stack); + // process.exit(1); +}); \ No newline at end of file diff --git a/peers/servers/peerjs-server.js b/peers/servers/peerjs-server.js index a99ec1665..fba50cb3c 100644 --- a/peers/servers/peerjs-server.js +++ b/peers/servers/peerjs-server.js @@ -37,7 +37,11 @@ const peerDisconnect = (client) => { } const peerError = (error) => { - console.error('error fired'); + //https://peerjs.com/docs/#peeron-error + console.error('Error detected in Peers'); + console.error('Error type:'); + console.error(error.type); + console.error('Error message:'); console.error(error); } diff --git a/utilities/server.js b/utilities/server.js index 331d45a80..96ef8d389 100644 --- a/utilities/server.js +++ b/utilities/server.js @@ -3,7 +3,8 @@ const express = require('express'); const socket = require("./servers/websocket"); const {request_logger} = require("./utils/helper"); -const HOST = '0.0.0.0'; +const debug = process.env.debug === "1" || false; +const HOST = process.env.LISTEN_HOST || '0.0.0.0'; const PORT = process.env.LISTEN_PORT || 9001; const wsapp = express(); From 31512e7f6976f54fe0849d3ae6abaa95d2761488 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 8 Sep 2022 12:38:43 +0100 Subject: [PATCH 017/185] feat(chalice): fixed get replay resources from experimental table --- ee/api/chalicelib/core/resources.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ee/api/chalicelib/core/resources.py b/ee/api/chalicelib/core/resources.py index ad4f0da99..e5d7ee126 100644 --- a/ee/api/chalicelib/core/resources.py +++ b/ee/api/chalicelib/core/resources.py @@ -15,8 +15,8 @@ def get_by_session_id(session_id, project_id, start_ts, duration): encoded_body_size,decoded_body_size,success, if(success, 200, 400) AS status FROM {exp_ch_helper.get_main_resources_table(start_ts)} - WHERE session_id = toUInt16(%(session_id)s) - AND project_id=%(project_id)s + WHERE session_id = toUInt64(%(session_id)s) + AND project_id = toUInt16(%(project_id)s) AND datetime >= toDateTime(%(res_start_ts)s / 1000) AND datetime <= toDateTime(%(res_end_ts)s / 1000);""" else: @@ -26,7 +26,7 @@ def get_by_session_id(session_id, project_id, start_ts, duration): coalesce(status,if(success, 200, status)) AS status FROM resources WHERE session_id = toUInt64(%(session_id)s) - AND project_id=%(project_id)s + AND project_id = toUInt64(%(project_id)s) AND datetime >= toDateTime(%(res_start_ts)s / 1000) AND datetime <= toDateTime(%(res_end_ts)s / 1000);""" params = {"session_id": session_id, "project_id": project_id, "start_ts": start_ts, "duration": duration, From 0eed5b58d417975bed051b023a46cde67c67db7f Mon Sep 17 00:00:00 2001 From: Alexander Zavorotynskiy Date: Thu, 8 Sep 2022 16:21:41 +0200 Subject: [PATCH 018/185] feat(backend): extra checks to avoid nil cast panic --- backend/cmd/assets/main.go | 12 ++++++++-- backend/cmd/db/main.go | 3 +++ backend/cmd/sink/main.go | 6 ++++- backend/pkg/messages/batch.go | 42 +++++++++++++++++++++++++++++------ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/backend/cmd/assets/main.go b/backend/cmd/assets/main.go index 629224da7..d62a25876 100644 --- a/backend/cmd/assets/main.go +++ b/backend/cmd/assets/main.go @@ -37,11 +37,19 @@ func main() { func(sessionID uint64, iter messages.Iterator, meta *types.Meta) { for iter.Next() { if iter.Type() == messages.MsgAssetCache { - msg := iter.Message().Decode().(*messages.AssetCache) + m := iter.Message().Decode() + if m == nil { + return + } + msg := m.(*messages.AssetCache) cacher.CacheURL(sessionID, msg.URL) totalAssets.Add(context.Background(), 1) } else if iter.Type() == messages.MsgErrorEvent { - msg := iter.Message().Decode().(*messages.ErrorEvent) + m := iter.Message().Decode() + if m == nil { + return + } + msg := m.(*messages.ErrorEvent) if msg.Source != "js_exception" { continue } diff --git a/backend/cmd/db/main.go b/backend/cmd/db/main.go index 2ea57b459..82e96dae6 100644 --- a/backend/cmd/db/main.go +++ b/backend/cmd/db/main.go @@ -69,6 +69,9 @@ func main() { continue } msg := iter.Message().Decode() + if msg == nil { + return + } // Just save session data into db without additional checks if err := saver.InsertMessage(sessionID, msg); err != nil { diff --git a/backend/cmd/sink/main.go b/backend/cmd/sink/main.go index d247d17b2..f0b145fae 100644 --- a/backend/cmd/sink/main.go +++ b/backend/cmd/sink/main.go @@ -76,7 +76,11 @@ func main() { iter.Type() == MsgCSSInsertRuleURLBased || iter.Type() == MsgAdoptedSSReplaceURLBased || iter.Type() == MsgAdoptedSSInsertRuleURLBased { - msg = assetMessageHandler.ParseAssets(sessionID, msg.Decode()) // TODO: filter type only once (use iterator inide or bring ParseAssets out here). + m := msg.Decode() + if m == nil { + return + } + msg = assetMessageHandler.ParseAssets(sessionID, m) // TODO: filter type only once (use iterator inide or bring ParseAssets out here). } // Filter message diff --git a/backend/pkg/messages/batch.go b/backend/pkg/messages/batch.go index 7dd6172bd..58b177aea 100644 --- a/backend/pkg/messages/batch.go +++ b/backend/pkg/messages/batch.go @@ -93,7 +93,11 @@ func (i *iteratorImpl) Next() bool { log.Printf("Batch Metadata found at the end of the batch") return false } - m := i.msg.Decode().(*BatchMetadata) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*BatchMetadata) i.index = m.PageNo<<32 + m.FirstIndex // 2^32 is the maximum count of messages per page (ha-ha) i.timestamp = m.Timestamp i.version = m.Version @@ -108,7 +112,11 @@ func (i *iteratorImpl) Next() bool { log.Printf("Batch Meta found at the end of the batch") return false } - m := i.msg.Decode().(*BatchMeta) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*BatchMeta) i.index = m.PageNo<<32 + m.FirstIndex // 2^32 is the maximum count of messages per page (ha-ha) i.timestamp = m.Timestamp isBatchMeta = true @@ -118,24 +126,44 @@ func (i *iteratorImpl) Next() bool { log.Printf("Batch Meta found at the end of the batch") return false } - m := i.msg.Decode().(*IOSBatchMeta) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*IOSBatchMeta) i.index = m.FirstIndex i.timestamp = int64(m.Timestamp) isBatchMeta = true // continue readLoop case MsgTimestamp: - m := i.msg.Decode().(*Timestamp) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*Timestamp) i.timestamp = int64(m.Timestamp) // No skipping here for making it easy to encode back the same sequence of message // continue readLoop case MsgSessionStart: - m := i.msg.Decode().(*SessionStart) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*SessionStart) i.timestamp = int64(m.Timestamp) case MsgSessionEnd: - m := i.msg.Decode().(*SessionEnd) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*SessionEnd) i.timestamp = int64(m.Timestamp) case MsgSetPageLocation: - m := i.msg.Decode().(*SetPageLocation) + msg := i.msg.Decode() + if msg == nil { + return false + } + m := msg.(*SetPageLocation) i.url = m.URL } i.msg.Meta().Index = i.index From 3d82a6558bec811c7ad73a046e66f2409d402205 Mon Sep 17 00:00:00 2001 From: sylenien Date: Fri, 9 Sep 2022 11:27:23 +0200 Subject: [PATCH 019/185] feat(ui): add pinia integration doc --- frontend/app/assets/integrations/pinia.svg | 1 + .../Client/Integrations/Integrations.tsx | 2 + .../Client/Integrations/PiniaDoc/PiniaDoc.tsx | 102 ++++++++++++++++++ .../Client/Integrations/PiniaDoc/index.js | 1 + 4 files changed, 106 insertions(+) create mode 100644 frontend/app/assets/integrations/pinia.svg create mode 100644 frontend/app/components/Client/Integrations/PiniaDoc/PiniaDoc.tsx create mode 100644 frontend/app/components/Client/Integrations/PiniaDoc/index.js diff --git a/frontend/app/assets/integrations/pinia.svg b/frontend/app/assets/integrations/pinia.svg new file mode 100644 index 000000000..3a20cba15 --- /dev/null +++ b/frontend/app/assets/integrations/pinia.svg @@ -0,0 +1 @@ + diff --git a/frontend/app/components/Client/Integrations/Integrations.tsx b/frontend/app/components/Client/Integrations/Integrations.tsx index 8e301ac8a..cde34ed89 100644 --- a/frontend/app/components/Client/Integrations/Integrations.tsx +++ b/frontend/app/components/Client/Integrations/Integrations.tsx @@ -29,6 +29,7 @@ import AssistDoc from './AssistDoc'; import { PageTitle, Loader } from 'UI'; import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG'; import withPageTitle from 'HOCs/withPageTitle'; +import PiniaDoc from './PiniaDoc' interface Props { fetch: (name: string, siteId: string) => void; @@ -162,6 +163,7 @@ const integrations = [ integrations: [ { title: 'Redux', slug: '', icon: 'integrations/redux', component: }, { title: 'VueX', slug: '', icon: 'integrations/vuejs', component: }, + { title: 'Pinia', slug: '', icon: 'integrations/pinia', component: }, { title: 'GraphQL', slug: '', icon: 'integrations/graphql', component: }, { title: 'NgRx', slug: '', icon: 'integrations/ngrx', component: }, { title: 'MobX', slug: '', icon: 'integrations/mobx', component: }, diff --git a/frontend/app/components/Client/Integrations/PiniaDoc/PiniaDoc.tsx b/frontend/app/components/Client/Integrations/PiniaDoc/PiniaDoc.tsx new file mode 100644 index 000000000..8a2033a2d --- /dev/null +++ b/frontend/app/components/Client/Integrations/PiniaDoc/PiniaDoc.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import Highlight from 'react-highlight'; +import ToggleContent from '../../../shared/ToggleContent'; +import DocLink from 'Shared/DocLink/DocLink'; +import { connect } from 'react-redux'; + +const PiniaDoc = (props) => { + const { projectKey } = props; + return ( +
+

VueX

+
+
+ This plugin allows you to capture Pinia mutations + state and inspect them later on while + replaying session recordings. This is very useful for understanding and fixing issues. +
+ +
Installation
+ {`npm i @openreplay/tracker-vuex --save`} + +
Usage
+

+ Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put + the generated plugin into your plugins field of your store. +

+
+ + + {`import Vuex from 'vuex' +import OpenReplay from '@openreplay/tracker'; +import trackerVuex from '@openreplay/tracker-vuex'; +//... +const tracker = new OpenReplay({ + projectKey: '${projectKey}' +}); +tracker.start(); +//... +const examplePiniaStore = useExamplePiniaStore() +// check list of available options below +const vuexPlugin = tracker.use(trackerVuex()) +// add a name to your store, optional +//(will be randomly generated otherwise) +const piniaStorePlugin = vuexPlugin('STORE NAME') + +// start tracking state updates +piniaStorePlugin(examplePiniaStore) +// now you can use examplePiniaStore as +// usual pinia store +// (destructure values or return it as a whole etc) +`} + + } + second={ + + {`import Vuex from 'vuex' +import OpenReplay from '@openreplay/tracker/cjs'; +import trackerVuex from '@openreplay/tracker-vuex/cjs'; +//... +const tracker = new OpenReplay({ + projectKey: '${projectKey}' +}); +//... + +// start tracker when the app is mounted +tracker.start(); + +//... +const examplePiniaStore = useExamplePiniaStore() +// check list of available options below +const vuexPlugin = tracker.use(trackerVuex()) +// add a name to your store, optional +// (will be randomly generated otherwise) +const piniaStorePlugin = vuexPlugin('STORE NAME') + +// start tracking state updates +piniaStorePlugin(examplePiniaStore) +// now you can use examplePiniaStore as +// usual pinia store +// (destructure values or return it as a whole etc) +}`} + + } + /> + + +
+
+ ); +}; + +PiniaDoc.displayName = 'PiniaDoc'; + +export default connect((state) => ({ + projectKey: state.getIn(['site', 'instance', 'projectKey']), +}))(PiniaDoc); diff --git a/frontend/app/components/Client/Integrations/PiniaDoc/index.js b/frontend/app/components/Client/Integrations/PiniaDoc/index.js new file mode 100644 index 000000000..730c76beb --- /dev/null +++ b/frontend/app/components/Client/Integrations/PiniaDoc/index.js @@ -0,0 +1 @@ +export { default } from './PiniaDoc' From f360d8416dae2305a1b9ea6ba01030b7f3490576 Mon Sep 17 00:00:00 2001 From: sylenien Date: Thu, 8 Sep 2022 15:06:18 +0200 Subject: [PATCH 020/185] feat(tracker): add zustand support --- backend/pkg/messages/filters.go | 2 +- backend/pkg/messages/messages.go | 36 +++ backend/pkg/messages/read-message.go | 15 ++ ee/connectors/msgcodec/messages.py | 16 +- ee/connectors/msgcodec/msgcodec.py | 21 +- .../messages/RawMessageReader.ts | 10 + .../MessageDistributor/messages/message.ts | 3 + .../player/MessageDistributor/messages/raw.ts | 8 +- .../messages/tracker-legacy.ts | 1 + .../MessageDistributor/messages/tracker.ts | 16 +- mobs/messages.rb | 21 +- tracker/tracker-vuex/package.json | 5 +- tracker/tracker-vuex/src/index.ts | 2 +- tracker/tracker-zustand/.gitignore | 6 + tracker/tracker-zustand/.npmignore | 5 + tracker/tracker-zustand/LICENSE | 19 ++ tracker/tracker-zustand/README.md | 48 ++++ tracker/tracker-zustand/package.json | 35 +++ tracker/tracker-zustand/src/index.ts | 62 +++++ tracker/tracker-zustand/src/syncod/chars.ts | 18 ++ tracker/tracker-zustand/src/syncod/encoder.ts | 220 ++++++++++++++++++ tracker/tracker-zustand/src/syncod/index.ts | 5 + tracker/tracker-zustand/src/syncod/sha1.ts | 104 +++++++++ tracker/tracker-zustand/tsconfig-cjs.json | 8 + tracker/tracker-zustand/tsconfig.json | 12 + tracker/tracker/package.json | 2 +- tracker/tracker/src/common/messages.gen.ts | 9 +- tracker/tracker/src/main/app/messages.gen.ts | 11 + .../src/webworker/MessageEncoder.gen.ts | 4 + 29 files changed, 690 insertions(+), 34 deletions(-) create mode 100644 tracker/tracker-zustand/.gitignore create mode 100644 tracker/tracker-zustand/.npmignore create mode 100644 tracker/tracker-zustand/LICENSE create mode 100644 tracker/tracker-zustand/README.md create mode 100644 tracker/tracker-zustand/package.json create mode 100644 tracker/tracker-zustand/src/index.ts create mode 100644 tracker/tracker-zustand/src/syncod/chars.ts create mode 100644 tracker/tracker-zustand/src/syncod/encoder.ts create mode 100644 tracker/tracker-zustand/src/syncod/index.ts create mode 100644 tracker/tracker-zustand/src/syncod/sha1.ts create mode 100644 tracker/tracker-zustand/tsconfig-cjs.json create mode 100644 tracker/tracker-zustand/tsconfig.json diff --git a/backend/pkg/messages/filters.go b/backend/pkg/messages/filters.go index c28e07742..e79d1d987 100644 --- a/backend/pkg/messages/filters.go +++ b/backend/pkg/messages/filters.go @@ -2,7 +2,7 @@ package messages func IsReplayerType(id int) bool { - return 0 == id || 4 == id || 5 == id || 6 == id || 7 == id || 8 == id || 9 == id || 10 == id || 11 == id || 12 == id || 13 == id || 14 == id || 15 == id || 16 == id || 18 == id || 19 == id || 20 == id || 22 == id || 37 == id || 38 == id || 39 == id || 40 == id || 41 == id || 44 == id || 45 == id || 46 == id || 47 == id || 48 == id || 49 == id || 54 == id || 55 == id || 59 == id || 60 == id || 61 == id || 67 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 90 == id || 93 == id || 96 == id || 100 == id || 102 == id || 103 == id || 105 == id + return 0 == id || 4 == id || 5 == id || 6 == id || 7 == id || 8 == id || 9 == id || 10 == id || 11 == id || 12 == id || 13 == id || 14 == id || 15 == id || 16 == id || 18 == id || 19 == id || 20 == id || 22 == id || 37 == id || 38 == id || 39 == id || 40 == id || 41 == id || 44 == id || 45 == id || 46 == id || 47 == id || 48 == id || 49 == id || 54 == id || 55 == id || 59 == id || 60 == id || 61 == id || 67 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 79 == id || 90 == id || 93 == id || 96 == id || 100 == id || 102 == id || 103 == id || 105 == id } func IsIOSType(id int) bool { diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go index 27712cb1f..8cdb95722 100644 --- a/backend/pkg/messages/messages.go +++ b/backend/pkg/messages/messages.go @@ -156,6 +156,8 @@ const ( MsgAdoptedSSRemoveOwner = 77 + MsgZustand = 79 + MsgIOSBatchMeta = 107 MsgIOSSessionStart = 90 @@ -3038,6 +3040,40 @@ func (msg *AdoptedSSRemoveOwner) TypeID() int { return 77 } +type Zustand struct { + message + Mutation string + State string +} + +func (msg *Zustand) Encode() []byte { + buf := make([]byte, 21+len(msg.Mutation)+len(msg.State)) + buf[0] = 79 + p := 1 + p = WriteString(msg.Mutation, buf, p) + p = WriteString(msg.State, buf, p) + return buf[:p] +} + +func (msg *Zustand) EncodeWithIndex() []byte { + encoded := msg.Encode() + if IsIOSType(msg.TypeID()) { + return encoded + } + data := make([]byte, len(encoded)+8) + copy(data[8:], encoded[:]) + binary.LittleEndian.PutUint64(data[0:], msg.Meta().Index) + return data +} + +func (msg *Zustand) Decode() Message { + return msg +} + +func (msg *Zustand) TypeID() int { + return 79 +} + type IOSBatchMeta struct { message Timestamp uint64 diff --git a/backend/pkg/messages/read-message.go b/backend/pkg/messages/read-message.go index 2b12601d9..1b0f579af 100644 --- a/backend/pkg/messages/read-message.go +++ b/backend/pkg/messages/read-message.go @@ -1306,6 +1306,18 @@ func DecodeAdoptedSSRemoveOwner(reader io.Reader) (Message, error) { return msg, err } +func DecodeZustand(reader io.Reader) (Message, error) { + var err error = nil + msg := &Zustand{} + if msg.Mutation, err = ReadString(reader); err != nil { + return nil, err + } + if msg.State, err = ReadString(reader); err != nil { + return nil, err + } + return msg, err +} + func DecodeIOSBatchMeta(reader io.Reader) (Message, error) { var err error = nil msg := &IOSBatchMeta{} @@ -1939,6 +1951,9 @@ func ReadMessage(t uint64, reader io.Reader) (Message, error) { case 77: return DecodeAdoptedSSRemoveOwner(reader) + case 79: + return DecodeZustand(reader) + case 107: return DecodeIOSBatchMeta(reader) diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py index f645e2995..e1fe393a4 100644 --- a/ee/connectors/msgcodec/messages.py +++ b/ee/connectors/msgcodec/messages.py @@ -63,13 +63,6 @@ class SessionStart(Message): self.user_id = user_id -class SessionDisconnect(Message): - __id__ = 2 - - def __init__(self, timestamp): - self.timestamp = timestamp - - class SessionEnd(Message): __id__ = 3 @@ -106,7 +99,6 @@ class CreateDocument(Message): __id__ = 7 def __init__(self, ): - pass @@ -752,6 +744,14 @@ class AdoptedSSRemoveOwner(Message): self.id = id +class Zustand(Message): + __id__ = 79 + + def __init__(self, mutation, state): + self.mutation = mutation + self.state = state + + class IOSBatchMeta(Message): __id__ = 107 diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py index 76468682a..d53c3e75d 100644 --- a/ee/connectors/msgcodec/msgcodec.py +++ b/ee/connectors/msgcodec/msgcodec.py @@ -2,6 +2,7 @@ from msgcodec.codec import Codec from msgcodec.messages import * +from typing import List import io class MessageCodec(Codec): @@ -42,7 +43,7 @@ class MessageCodec(Codec): raise UnicodeDecodeError(f"Error while decoding message key (SessionID) from {b}\n{e}") return decoded - def decode_detailed(self, b: bytes): + def decode_detailed(self, b: bytes) -> List[Message]: reader = io.BytesIO(b) messages_list = list() messages_list.append(self.handler(reader, 0)) @@ -61,7 +62,7 @@ class MessageCodec(Codec): break return messages_list - def handler(self, reader: io.BytesIO, mode=0): + def handler(self, reader: io.BytesIO, mode=0) -> Message: message_id = self.read_message_id(reader) if mode == 1: # We skip the three bytes representing the length of message. It can be used to skip unwanted messages @@ -71,9 +72,10 @@ class MessageCodec(Codec): # Old format with no bytes for message length return self.read_head_message(reader, message_id) else: - raise IOError() + raise IOError() + + def read_head_message(self, reader: io.BytesIO, message_id) -> Message: - def read_head_message(self, reader: io.BytesIO, message_id: int): if message_id == 80: return BatchMeta( page_no=self.read_uint(reader), @@ -121,11 +123,6 @@ class MessageCodec(Codec): user_id=self.read_string(reader) ) - if message_id == 2: - return SessionDisconnect( - timestamp=self.read_uint(reader) - ) - if message_id == 3: return SessionEnd( timestamp=self.read_uint(reader) @@ -665,6 +662,12 @@ class MessageCodec(Codec): id=self.read_uint(reader) ) + if message_id == 79: + return Zustand( + mutation=self.read_string(reader), + state=self.read_string(reader) + ) + if message_id == 107: return IOSBatchMeta( timestamp=self.read_uint(reader), diff --git a/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts b/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts index 4536a7c0e..d925d8bcc 100644 --- a/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts +++ b/frontend/app/player/MessageDistributor/messages/RawMessageReader.ts @@ -527,6 +527,16 @@ export default class RawMessageReader extends PrimitiveReader { }; } + case 79: { + const mutation = this.readString(); if (mutation === null) { return resetPointer() } + const state = this.readString(); if (state === null) { return resetPointer() } + return { + tp: "zustand", + mutation, + state, + }; + } + case 90: { const timestamp = this.readUint(); if (timestamp === null) { return resetPointer() } const projectID = this.readUint(); if (projectID === null) { return resetPointer() } diff --git a/frontend/app/player/MessageDistributor/messages/message.ts b/frontend/app/player/MessageDistributor/messages/message.ts index 490f817ea..397bbfaa4 100644 --- a/frontend/app/player/MessageDistributor/messages/message.ts +++ b/frontend/app/player/MessageDistributor/messages/message.ts @@ -47,6 +47,7 @@ import type { RawAdoptedSsDeleteRule, RawAdoptedSsAddOwner, RawAdoptedSsRemoveOwner, + RawZustand, RawIosSessionStart, RawIosCustomEvent, RawIosScreenChanges, @@ -147,6 +148,8 @@ export type AdoptedSsAddOwner = RawAdoptedSsAddOwner & Timed export type AdoptedSsRemoveOwner = RawAdoptedSsRemoveOwner & Timed +export type Zustand = RawZustand & Timed + export type IosSessionStart = RawIosSessionStart & Timed export type IosCustomEvent = RawIosCustomEvent & Timed diff --git a/frontend/app/player/MessageDistributor/messages/raw.ts b/frontend/app/player/MessageDistributor/messages/raw.ts index a546ca799..c7a133440 100644 --- a/frontend/app/player/MessageDistributor/messages/raw.ts +++ b/frontend/app/player/MessageDistributor/messages/raw.ts @@ -300,6 +300,12 @@ export interface RawAdoptedSsRemoveOwner { id: number, } +export interface RawZustand { + tp: "zustand", + mutation: string, + state: string, +} + export interface RawIosSessionStart { tp: "ios_session_start", timestamp: number, @@ -371,4 +377,4 @@ export interface RawIosNetworkCall { } -export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawConnectionInformation | RawSetPageVisibility | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawIosSessionStart | RawIosCustomEvent | RawIosScreenChanges | RawIosClickEvent | RawIosPerformanceEvent | RawIosLog | RawIosNetworkCall; +export type RawMessage = RawTimestamp | RawSetPageLocation | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawConsoleLog | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawRedux | RawVuex | RawMobX | RawNgRx | RawGraphQl | RawPerformanceTrack | RawConnectionInformation | RawSetPageVisibility | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawIosSessionStart | RawIosCustomEvent | RawIosScreenChanges | RawIosClickEvent | RawIosPerformanceEvent | RawIosLog | RawIosNetworkCall; diff --git a/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts b/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts index c89f8a47c..088731bbc 100644 --- a/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts +++ b/frontend/app/player/MessageDistributor/messages/tracker-legacy.ts @@ -60,6 +60,7 @@ export const TP_MAP = { 75: "adopted_ss_delete_rule", 76: "adopted_ss_add_owner", 77: "adopted_ss_remove_owner", + 79: "zustand", 90: "ios_session_start", 93: "ios_custom_event", 96: "ios_screen_changes", diff --git a/frontend/app/player/MessageDistributor/messages/tracker.ts b/frontend/app/player/MessageDistributor/messages/tracker.ts index 34493f32c..865b0ce11 100644 --- a/frontend/app/player/MessageDistributor/messages/tracker.ts +++ b/frontend/app/player/MessageDistributor/messages/tracker.ts @@ -382,8 +382,14 @@ type TrAdoptedSSRemoveOwner = [ id: number, ] +type TrZustand = [ + type: 79, + mutation: string, + state: string, +] -export type TrackerMessage = TrBatchMetadata | TrPartitionedMessage | TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrJSException | TrRawCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner + +export type TrackerMessage = TrBatchMetadata | TrPartitionedMessage | TrTimestamp | TrSetPageLocation | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrJSException | TrRawCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrRedux | TrVuex | TrMobX | TrNgRx | TrGraphQL | TrPerformanceTrack | TrResourceTiming | TrConnectionInformation | TrSetPageVisibility | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrZustand export default function translate(tMsg: TrackerMessage): RawMessage | null { switch(tMsg[0]) { @@ -750,6 +756,14 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { } } + case 79: { + return { + tp: "zustand", + mutation: tMsg[1], + state: tMsg[2], + } + } + default: return null } diff --git a/mobs/messages.rb b/mobs/messages.rb index 61f141121..09acdb6f2 100644 --- a/mobs/messages.rb +++ b/mobs/messages.rb @@ -1,7 +1,7 @@ -# Special one for Batch Metadata. Message id could define the version +# Special one for Batch Metadata. Message id could define the version # Depricated since tracker 3.6.0 in favor of BatchMetadata -message 80, 'BatchMeta', :replayer => false, :tracker => false do +message 80, 'BatchMeta', :replayer => false, :tracker => false do uint 'PageNo' uint 'FirstIndex' int 'Timestamp' @@ -421,7 +421,7 @@ message 70, 'CreateIFrameDocument' do uint 'FrameID' uint 'ID' end - + #Since 3.6.0 AdoptedStyleSheets message 71, 'AdoptedSSReplaceURLBased' do uint 'SheetID' @@ -432,26 +432,31 @@ message 72, 'AdoptedSSReplace', :tracker => false do uint 'SheetID' string 'Text' end -message 73, 'AdoptedSSInsertRuleURLBased' do +message 73, 'AdoptedSSInsertRuleURLBased' do uint 'SheetID' string 'Rule' uint 'Index' string 'BaseURL' end -message 74, 'AdoptedSSInsertRule', :tracker => false do +message 74, 'AdoptedSSInsertRule', :tracker => false do uint 'SheetID' string 'Rule' uint 'Index' end -message 75, 'AdoptedSSDeleteRule' do +message 75, 'AdoptedSSDeleteRule' do uint 'SheetID' uint 'Index' end -message 76, 'AdoptedSSAddOwner' do +message 76, 'AdoptedSSAddOwner' do uint 'SheetID' uint 'ID' end -message 77, 'AdoptedSSRemoveOwner' do +message 77, 'AdoptedSSRemoveOwner' do uint 'SheetID' uint 'ID' end + +message 79, 'Zustand' do + string 'Mutation' + string 'State' +end diff --git a/tracker/tracker-vuex/package.json b/tracker/tracker-vuex/package.json index 69f43df64..1fd8a8c19 100644 --- a/tracker/tracker-vuex/package.json +++ b/tracker/tracker-vuex/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-vuex", "description": "Tracker plugin for Vuex state recording", - "version": "4.0.0", + "version": "4.0.1", "keywords": [ "vuex", "logging", @@ -23,8 +23,7 @@ }, "dependencies": {}, "peerDependencies": { - "@openreplay/tracker": "^3.4.8", - "@ngrx/store": ">=4" + "@openreplay/tracker": "^3.4.8" }, "devDependencies": { "@openreplay/tracker": "^3.4.8", diff --git a/tracker/tracker-vuex/src/index.ts b/tracker/tracker-vuex/src/index.ts index f8d8c1dba..a7a92cba0 100644 --- a/tracker/tracker-vuex/src/index.ts +++ b/tracker/tracker-vuex/src/index.ts @@ -52,7 +52,7 @@ export default function(opts: Partial = {}) { const randomId = Math.random().toString(36).substring(2, 9) store.subscribe((mutation, storeState) => { state[storeName || randomId] = state - processMutationAndState(app, options, encoder, mutation, storeState); + processMutationAndState(app, options, encoder, mutation, state); }); } diff --git a/tracker/tracker-zustand/.gitignore b/tracker/tracker-zustand/.gitignore new file mode 100644 index 000000000..6ddaccbb5 --- /dev/null +++ b/tracker/tracker-zustand/.gitignore @@ -0,0 +1,6 @@ +node_modules +npm-debug.log +lib +cjs +.cache +*.DS_Store \ No newline at end of file diff --git a/tracker/tracker-zustand/.npmignore b/tracker/tracker-zustand/.npmignore new file mode 100644 index 000000000..4ea62cab6 --- /dev/null +++ b/tracker/tracker-zustand/.npmignore @@ -0,0 +1,5 @@ +src +tsconfig-cjs.json +tsconfig.json +.prettierrc.json +.cache \ No newline at end of file diff --git a/tracker/tracker-zustand/LICENSE b/tracker/tracker-zustand/LICENSE new file mode 100644 index 000000000..15669f768 --- /dev/null +++ b/tracker/tracker-zustand/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 Asayer, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tracker/tracker-zustand/README.md b/tracker/tracker-zustand/README.md new file mode 100644 index 000000000..83bd0318b --- /dev/null +++ b/tracker/tracker-zustand/README.md @@ -0,0 +1,48 @@ +# OpenReplay Tracker Vuex plugin +A Vuex plugin for OpenReplay Tracker. This plugin allows you to see the application state during session replay. + +## Installation +```bash +npm i @openreplay/tracker-vuex +``` + +## Usage +Initialize the `@openreplay/tracker` package as usual and load the plugin into it. +Then put the generated plugin into your `plugins` field of your store. + +```js +import Vuex from 'vuex' +import Tracker from '@openreplay/tracker'; +import trackerVuex from '@openreplay/tracker-vuex'; + +const tracker = new Tracker({ + projectKey: YOUR_PROJECT_KEY, +}); + +const store = new Vuex.Store({ + // ... + plugins: [tracker.plugin(trackerVuex())], +}); +``` + +You can customize the plugin behavior with options to sanitize your data. They are similar to the ones from the standard `createLogger` plugin. + +```js +trackerVuex({ + filter (mutation, state) { + // returns `true` if a mutation should be logged + // `mutation` is a `{ type, payload }` + return mutation.type !== "aBlacklistedMutation"; + }, + transformer (state) { + // transform the state before logging it. + // for example return only a specific sub-tree + return state.subTree; + }, + mutationTransformer (mutation) { + // mutations are logged in the format of `{ type, payload }` + // we can format it any way we want. + return mutation.type; + }, +}) +``` diff --git a/tracker/tracker-zustand/package.json b/tracker/tracker-zustand/package.json new file mode 100644 index 000000000..60fa6a74f --- /dev/null +++ b/tracker/tracker-zustand/package.json @@ -0,0 +1,35 @@ +{ + "name": "@openreplay/tracker-zustand", + "description": "Tracker plugin for Zustand state recording", + "version": "1.0.0", + "keywords": [ + "zustand", + "state", + "logging", + "replay" + ], + "author": "Nikita Melnikov ", + "contributors": [ + "Aleksandr K " + ], + "license": "MIT", + "type": "module", + "main": "./lib/index.js", + "scripts": { + "lint": "prettier --write 'src/**/*.ts' && tsc --noEmit", + "build": "npm run build-es && npm run build-cjs", + "build-es": "rm -Rf lib && tsc", + "build-cjs": "rm -Rf cjs && tsc --project tsconfig-cjs.json && echo '{ \"type\": \"commonjs\" }' > cjs/package.json && replace-in-files cjs/* --string='@openreplay/tracker' --replacement='@openreplay/tracker/cjs'", + "prepublishOnly": "npm run build" + }, + "dependencies": {}, + "peerDependencies": { + "@openreplay/tracker": "^4.0.0" + }, + "devDependencies": { + "@openreplay/tracker": "file:../tracker", + "prettier": "^1.18.2", + "replace-in-files-cli": "^1.0.0", + "typescript": "^4.6.0-dev.20211126" + } +} diff --git a/tracker/tracker-zustand/src/index.ts b/tracker/tracker-zustand/src/index.ts new file mode 100644 index 000000000..bf9186fb1 --- /dev/null +++ b/tracker/tracker-zustand/src/index.ts @@ -0,0 +1,62 @@ +import { App, Messages } from "@openreplay/tracker"; +import { Encoder, sha1 } from "./syncod/index.js"; + +export interface Options { + filter: (mutation: any, state: any) => boolean; + transformer: (state: any) => any; + mutationTransformer: (mutation: any) => any; +} + +function processMutationAndState( + app: App, + options: Options, + encoder: Encoder, + mutation: string[], + state: Record +) { + if (options.filter(mutation, state)) { + try { + const _mutation = encoder.encode(options.mutationTransformer(mutation)); + const _state = encoder.encode(options.transformer(state)); + const _table = encoder.commit(); + for (let key in _table) app.send(Messages.OTable(key, _table[key])); + app.send(Messages.Zustand(_mutation, _state)); + } catch (e) { + encoder.clear(); + app.debug.error(e) + } + } +} + +export default function(opts: Partial = {}) { + const options: Options = Object.assign( + { + filter: () => true, + transformer: state => state, + mutationTransformer: mutation => mutation, + }, + opts + ); + return (app: App | null) => { + if (app === null) { + return Function.prototype; + } + const encoder = new Encoder(sha1, 50); + const state = {}; + return (storeName: string = Math.random().toString(36).substring(2, 9)) => + (config: Function) => + (set: (...args: any) => void, get: () => Record, api: any) => + config( + (...args) => { + set(...args) + const newState = get(); + state[storeName] = newState + const triggeredActions = args.map(action => action.toString?.()) + + processMutationAndState(app, options, encoder, triggeredActions, state) + }, + get, + api + ) + }; +} diff --git a/tracker/tracker-zustand/src/syncod/chars.ts b/tracker/tracker-zustand/src/syncod/chars.ts new file mode 100644 index 000000000..ed0d4d0c5 --- /dev/null +++ b/tracker/tracker-zustand/src/syncod/chars.ts @@ -0,0 +1,18 @@ +const chars = {}; + +[ + "DEL", + "UNDEF", + "TRUE", + "FALSE", + "NUMBER", + "BIGINT", + "FUNCTION", + "STRING", + "SYMBOL", + "NULL", + "OBJECT", + "ARRAY" +].forEach((k, i) => (chars[k] = String.fromCharCode(i + 0xe000))); + +export default chars; diff --git a/tracker/tracker-zustand/src/syncod/encoder.ts b/tracker/tracker-zustand/src/syncod/encoder.ts new file mode 100644 index 000000000..db531a0b2 --- /dev/null +++ b/tracker/tracker-zustand/src/syncod/encoder.ts @@ -0,0 +1,220 @@ +import _ from "./chars.js"; +// @ts-ignore + +// @ts-ignore +export default class Encoder { +// @ts-ignore + constructor(hash, slen = Infinity) { +// @ts-ignore + this._hash = hash; +// @ts-ignore + this._slen = slen; +// @ts-ignore + this._refmap = new Map(); +// @ts-ignore + this._refset = new Set(); +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + _ref_str(str) { +// @ts-ignore + if (str.length < this._slen && str.indexOf(_.DEL) === -1) { +// @ts-ignore + return str; +// @ts-ignore + } +// @ts-ignore + let ref = this._refmap.get(str); +// @ts-ignore + if (ref === undefined) { +// @ts-ignore + ref = this._hash(str); +// @ts-ignore + this._refmap.set(str, ref); +// @ts-ignore + } +// @ts-ignore + return ref; +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + _encode_prim(obj) { +// @ts-ignore + switch (typeof obj) { +// @ts-ignore + case "undefined": +// @ts-ignore + return _.UNDEF; +// @ts-ignore + case "boolean": +// @ts-ignore + return obj ? _.TRUE : _.FALSE; +// @ts-ignore + case "number": +// @ts-ignore + return _.NUMBER + obj.toString(); +// @ts-ignore + case "bigint": +// @ts-ignore + return _.BIGINT + obj.toString(); +// @ts-ignore + case "function": +// @ts-ignore + return _.FUNCTION; +// @ts-ignore + case "string": +// @ts-ignore + return _.STRING + this._ref_str(obj); +// @ts-ignore + case "symbol": +// @ts-ignore + return _.SYMBOL + this._ref_str(obj.toString().slice(7, -1)); +// @ts-ignore + } +// @ts-ignore + if (obj === null) { +// @ts-ignore + return _.NULL; +// @ts-ignore + } +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + _encode_obj(obj, ref = this._refmap.get(obj)) { +// @ts-ignore + return (Array.isArray(obj) ? _.ARRAY : _.OBJECT) + ref; +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + _encode_term(obj) { +// @ts-ignore + return this._encode_prim(obj) || this._encode_obj(obj); +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + _encode_deep(obj, depth) { +// @ts-ignore + const enc = this._encode_prim(obj); +// @ts-ignore + if (enc !== undefined) { +// @ts-ignore + return enc; +// @ts-ignore + } +// @ts-ignore + const ref = this._refmap.get(obj); +// @ts-ignore + switch (typeof ref) { +// @ts-ignore + case "number": +// @ts-ignore + return (depth - ref).toString(); +// @ts-ignore + case "string": +// @ts-ignore + return this._encode_obj(obj, ref); +// @ts-ignore + } +// @ts-ignore + this._refmap.set(obj, depth); +// @ts-ignore + const hash = this._hash( +// @ts-ignore + (Array.isArray(obj) +// @ts-ignore + ? obj.map(v => this._encode_deep(v, depth + 1)) +// @ts-ignore + : Object.keys(obj) +// @ts-ignore + .sort() +// @ts-ignore + .map( +// @ts-ignore + k => +// @ts-ignore + this._ref_str(k) + _.DEL + this._encode_deep(obj[k], depth + 1) +// @ts-ignore + ) +// @ts-ignore + ).join(_.DEL) +// @ts-ignore + ); +// @ts-ignore + this._refmap.set(obj, hash); +// @ts-ignore + return this._encode_obj(obj, hash); +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + encode(obj) { +// @ts-ignore + return this._encode_deep(obj, 0); +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + commit() { +// @ts-ignore + const dict = {}; +// @ts-ignore + this._refmap.forEach((ref, obj) => { +// @ts-ignore + if (this._refset.has(ref)) { +// @ts-ignore + return; +// @ts-ignore + } +// @ts-ignore + this._refset.add(ref); +// @ts-ignore + if (typeof obj !== "string") { +// @ts-ignore + obj = (Array.isArray(obj) +// @ts-ignore + ? obj.map(v => this._encode_term(v)) +// @ts-ignore + : Object.keys(obj).map( +// @ts-ignore + k => this._ref_str(k) + _.DEL + this._encode_term(obj[k]) +// @ts-ignore + ) +// @ts-ignore + ).join(_.DEL); +// @ts-ignore + } +// @ts-ignore + dict[ref] = obj; +// @ts-ignore + }); +// @ts-ignore + this._refmap.clear(); +// @ts-ignore + return dict; +// @ts-ignore + } +// @ts-ignore + +// @ts-ignore + clear() { +// @ts-ignore + this._refmap.clear(); +// @ts-ignore + this._refset.clear(); +// @ts-ignore + } +// @ts-ignore +} +// @ts-ignore diff --git a/tracker/tracker-zustand/src/syncod/index.ts b/tracker/tracker-zustand/src/syncod/index.ts new file mode 100644 index 000000000..de6f7c64c --- /dev/null +++ b/tracker/tracker-zustand/src/syncod/index.ts @@ -0,0 +1,5 @@ +// TODO: SSR solution for all asayer libraries +import Encoder from "./encoder.js"; +import sha1 from "./sha1.js"; + +export { Encoder, sha1 }; diff --git a/tracker/tracker-zustand/src/syncod/sha1.ts b/tracker/tracker-zustand/src/syncod/sha1.ts new file mode 100644 index 000000000..addacc2cd --- /dev/null +++ b/tracker/tracker-zustand/src/syncod/sha1.ts @@ -0,0 +1,104 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +function core_sha1(x, len) { + x[len >> 5] |= 0x80 << (24 - (len % 32)); + x[(((len + 64) >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for (var j = 0; j < 80; j++) { + if (j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + var t = safe_add( + safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j)) + ); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); +} + +function sha1_ft(t, b, c, d) { + if (t < 20) return (b & c) | (~b & d); + if (t < 40) return b ^ c ^ d; + if (t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +function sha1_kt(t) { + return t < 20 + ? 1518500249 + : t < 40 + ? 1859775393 + : t < 60 + ? -1894007588 + : -899497514; +} + +function safe_add(x, y) { + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} + +function rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} + +function str2binb(str) { + var bin = Array(); + var mask = (1 << 16) - 1; + for (var i = 0; i < str.length * 16; i += 16) + bin[i >> 5] |= (str.charCodeAt(i / 16) & mask) << (32 - 16 - (i % 32)); + return bin; +} + +function binb2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i += 3) { + var triplet = + (((binarray[i >> 2] >> (8 * (3 - (i % 4)))) & 0xff) << 16) | + (((binarray[(i + 1) >> 2] >> (8 * (3 - ((i + 1) % 4)))) & 0xff) << 8) | + ((binarray[(i + 2) >> 2] >> (8 * (3 - ((i + 2) % 4)))) & 0xff); + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= binarray.length * 32) + str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); + } + } + return str; +} + +export default function(s) { + return binb2b64(core_sha1(str2binb(s), s.length * 16)); +} diff --git a/tracker/tracker-zustand/tsconfig-cjs.json b/tracker/tracker-zustand/tsconfig-cjs.json new file mode 100644 index 000000000..2e91a035b --- /dev/null +++ b/tracker/tracker-zustand/tsconfig-cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "./cjs", + "declaration": false + }, +} \ No newline at end of file diff --git a/tracker/tracker-zustand/tsconfig.json b/tracker/tracker-zustand/tsconfig.json new file mode 100644 index 000000000..0c5b8d1b3 --- /dev/null +++ b/tracker/tracker-zustand/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "noImplicitThis": true, + "strictNullChecks": true, + "alwaysStrict": true, + "target": "es6", + "module": "es6", + "moduleResolution": "nodenext", + "declaration": true, + "outDir": "./lib" + } +} diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 59ca4bb50..5699bcdf9 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": "4.0.0", + "version": "4.0.1", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/common/messages.gen.ts b/tracker/tracker/src/common/messages.gen.ts index 3b45ec023..107416711 100644 --- a/tracker/tracker/src/common/messages.gen.ts +++ b/tracker/tracker/src/common/messages.gen.ts @@ -56,6 +56,7 @@ export declare const enum Type { AdoptedSSDeleteRule = 75, AdoptedSSAddOwner = 76, AdoptedSSRemoveOwner = 77, + Zustand = 79, } @@ -438,6 +439,12 @@ export type AdoptedSSRemoveOwner = [ /*id:*/ number, ] +export type Zustand = [ + /*type:*/ Type.Zustand, + /*mutation:*/ string, + /*state:*/ string, +] -type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSException | RawCustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner + +type Message = BatchMetadata | PartitionedMessage | Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | ConsoleLog | PageLoadTiming | PageRenderTiming | JSException | RawCustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | ResourceTiming | ConnectionInformation | SetPageVisibility | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | Zustand export default Message diff --git a/tracker/tracker/src/main/app/messages.gen.ts b/tracker/tracker/src/main/app/messages.gen.ts index 05f4f2894..7bbbeb615 100644 --- a/tracker/tracker/src/main/app/messages.gen.ts +++ b/tracker/tracker/src/main/app/messages.gen.ts @@ -707,3 +707,14 @@ export function AdoptedSSRemoveOwner( ] } +export function Zustand( + mutation: string, + state: string, +): Messages.Zustand { + return [ + Messages.Type.Zustand, + mutation, + state, + ] +} + diff --git a/tracker/tracker/src/webworker/MessageEncoder.gen.ts b/tracker/tracker/src/webworker/MessageEncoder.gen.ts index c38fa77a8..78151ba9f 100644 --- a/tracker/tracker/src/webworker/MessageEncoder.gen.ts +++ b/tracker/tracker/src/webworker/MessageEncoder.gen.ts @@ -229,6 +229,10 @@ export default class MessageEncoder extends PrimitiveEncoder { return this.uint(msg[1]) && this.uint(msg[2]) break + case Messages.Type.Zustand: + return this.string(msg[1]) && this.string(msg[2]) + break + } } From 7e22c1a260de95cf9ff4f3b31146feca8e134219 Mon Sep 17 00:00:00 2001 From: sylenien Date: Thu, 8 Sep 2022 15:09:19 +0200 Subject: [PATCH 021/185] fix(tracker): rm tracker change --- tracker/tracker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 5699bcdf9..59ca4bb50 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": "4.0.1", + "version": "4.0.0", "keywords": [ "logging", "replay" From 65f40d2f3d14ee7710c416b42c7b119c67abcfd0 Mon Sep 17 00:00:00 2001 From: sylenien Date: Thu, 8 Sep 2022 15:09:46 +0200 Subject: [PATCH 022/185] fix(tracker): rm tracker change --- tracker/tracker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 59ca4bb50..5699bcdf9 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": "4.0.0", + "version": "4.0.1", "keywords": [ "logging", "replay" From 0d8dd27ac1ca7ae951a19cdaa992e9f22693f862 Mon Sep 17 00:00:00 2001 From: sylenien Date: Fri, 9 Sep 2022 11:37:12 +0200 Subject: [PATCH 023/185] feat(ui): zustand support for the replayer --- .../components/Session_/Player/Controls/Controls.js | 4 ++++ frontend/app/components/Session_/Storage/Storage.js | 4 ++++ frontend/app/player/MessageDistributor/Lists.ts | 2 +- .../player/MessageDistributor/MessageDistributor.ts | 10 ++++++++-- frontend/app/player/store/selectors.js | 6 +++++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/frontend/app/components/Session_/Player/Controls/Controls.js b/frontend/app/components/Session_/Player/Controls/Controls.js index 0601e092f..1dcbbaa21 100644 --- a/frontend/app/components/Session_/Player/Controls/Controls.js +++ b/frontend/app/components/Session_/Player/Controls/Controls.js @@ -48,6 +48,8 @@ function getStorageIconName(type) { return 'vendors/vuex'; case STORAGE_TYPES.NGRX: return 'vendors/ngrx'; + case STORAGE_TYPES.ZUSTAND: + return 'vendors/zustand'; case STORAGE_TYPES.NONE: return 'store'; } @@ -73,6 +75,8 @@ function getStorageName(type) { return 'VUEX'; case STORAGE_TYPES.NGRX: return 'NGRX'; + case STORAGE_TYPES.ZUSTAND: + return 'ZUSTAND'; case STORAGE_TYPES.NONE: return 'STATE'; } diff --git a/frontend/app/components/Session_/Storage/Storage.js b/frontend/app/components/Session_/Storage/Storage.js index b1cf53dfc..62e9eda19 100644 --- a/frontend/app/components/Session_/Storage/Storage.js +++ b/frontend/app/components/Session_/Storage/Storage.js @@ -121,6 +121,9 @@ export default class Storage extends React.PureComponent { const { type, listNow, list } = this.props; let src; let name; + + // ZUSTAND TODO + console.log(item, type) switch(type) { case STORAGE_TYPES.REDUX: case STORAGE_TYPES.NGRX: @@ -208,6 +211,7 @@ export default class Storage extends React.PureComponent { {'Inspect your application state while you’re replaying your users sessions. OpenReplay supports '} Redux{', '} VueX{', '} + {/* ZUSTAND TODO */} MobX{' and '} NgRx.

diff --git a/frontend/app/player/MessageDistributor/Lists.ts b/frontend/app/player/MessageDistributor/Lists.ts index 0173b2667..a65eff52f 100644 --- a/frontend/app/player/MessageDistributor/Lists.ts +++ b/frontend/app/player/MessageDistributor/Lists.ts @@ -1,7 +1,7 @@ import type { Message } from './messages' import ListWalker from './managers/ListWalker'; -export const LIST_NAMES = ["redux", "mobx", "vuex", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const; +export const LIST_NAMES = ["redux", "mobx", "vuex", "zustand", "ngrx", "graphql", "exceptions", "profiles", "longtasks"] as const; export const INITIAL_STATE = {} LIST_NAMES.forEach(name => { diff --git a/frontend/app/player/MessageDistributor/MessageDistributor.ts b/frontend/app/player/MessageDistributor/MessageDistributor.ts index 2d73081fb..8c47debe2 100644 --- a/frontend/app/player/MessageDistributor/MessageDistributor.ts +++ b/frontend/app/player/MessageDistributor/MessageDistributor.ts @@ -123,7 +123,7 @@ export default class MessageDistributor extends StatedScreen { // TODO: fix types for events, remove immutable js eventList.forEach((e: Record) => { if (e.type === EVENT_TYPES.LOCATION) { //TODO type system - this.locationEventManager.append(e); + this.locationEventManager.append(e); } }); this.session.errors.forEach((e: Record) => { @@ -233,7 +233,7 @@ export default class MessageDistributor extends StatedScreen { this.waitingForFiles = false this.setMessagesLoading(false) }) - + }) } @@ -479,6 +479,12 @@ export default class MessageDistributor extends StatedScreen { this.lists.vuex.append(decoded); } break; + case "zustand": + decoded = this.decodeMessage(msg, ["state", "mutation"]) + logger.log(decoded) + if (decoded != null) { + this.lists.zustand.append(decoded) + } case "mob_x": decoded = this.decodeMessage(msg, ["payload"]); logger.log(decoded) diff --git a/frontend/app/player/store/selectors.js b/frontend/app/player/store/selectors.js index 1a6f0dc2d..36750b56d 100644 --- a/frontend/app/player/store/selectors.js +++ b/frontend/app/player/store/selectors.js @@ -2,6 +2,7 @@ const REDUX = "redux"; const MOBX = "mobx"; const VUEX = "vuex"; const NGRX = "ngrx"; +const ZUSTAND = 'zustand'; const NONE = 0; @@ -10,6 +11,7 @@ export const STORAGE_TYPES = { MOBX, VUEX, NGRX, + ZUSTAND, NONE, }; @@ -24,6 +26,8 @@ export function selectStorageType(state) { return MOBX; } else if (state.ngrxList.length > 0) { return NGRX; + } else if (state.zustandList.length > 0) { + return ZUSTAND; } return NONE; } @@ -41,4 +45,4 @@ export function selectStorageListNow(state) { return state[`${key}ListNow`] || []; } return []; -} \ No newline at end of file +} From 3d86fcf635085ebc86541b392eb4c2293320a6e5 Mon Sep 17 00:00:00 2001 From: sylenien Date: Fri, 9 Sep 2022 12:57:53 +0200 Subject: [PATCH 024/185] feat(ui): zustand actions tab --- .../components/Session_/Storage/Storage.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/frontend/app/components/Session_/Storage/Storage.js b/frontend/app/components/Session_/Storage/Storage.js index 62e9eda19..9bd6c0174 100644 --- a/frontend/app/components/Session_/Storage/Storage.js +++ b/frontend/app/components/Session_/Storage/Storage.js @@ -138,16 +138,23 @@ export default class Storage extends React.PureComponent { src = item.payload; name = `@${item.type} ${src && src.type}`; break; + case STORAGE_TYPES.ZUSTAND: + src = null; + name = item.mutation.join('') } return (
- + {src === null ? ( +
{name}
+ ) : ( + + )}
{ i + 1 < listNow.length &&