@multiplayer-app/session-recorder-react-native 0.0.1-alpha.7 → 0.0.1-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/components/GestureCaptureWrapper.d.ts +6 -0
  2. package/dist/components/GestureCaptureWrapper.js +1 -0
  3. package/dist/components/GestureCaptureWrapper.js.map +1 -0
  4. package/dist/context/SessionRecorderContext.d.ts +1 -2
  5. package/dist/context/SessionRecorderContext.js +1 -1
  6. package/dist/context/SessionRecorderContext.js.map +1 -1
  7. package/dist/otel/helpers.js +1 -1
  8. package/dist/otel/helpers.js.map +1 -1
  9. package/dist/otel/instrumentations/index.js +1 -1
  10. package/dist/otel/instrumentations/index.js.map +1 -1
  11. package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
  12. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
  13. package/dist/patch/xhr.js +1 -1
  14. package/dist/patch/xhr.js.map +1 -1
  15. package/dist/recorder/eventExporter.js +1 -1
  16. package/dist/recorder/eventExporter.js.map +1 -1
  17. package/dist/recorder/gestureHandlerRecorder.d.ts +19 -0
  18. package/dist/recorder/gestureHandlerRecorder.js +1 -0
  19. package/dist/recorder/gestureHandlerRecorder.js.map +1 -0
  20. package/dist/recorder/gestureRecorder.d.ts +13 -1
  21. package/dist/recorder/gestureRecorder.js +1 -1
  22. package/dist/recorder/gestureRecorder.js.map +1 -1
  23. package/dist/recorder/index.d.ts +1 -2
  24. package/dist/recorder/index.js +1 -1
  25. package/dist/recorder/index.js.map +1 -1
  26. package/dist/recorder/navigationTracker.js +1 -1
  27. package/dist/recorder/navigationTracker.js.map +1 -1
  28. package/dist/recorder/screenRecorder.d.ts +31 -6
  29. package/dist/recorder/screenRecorder.js +1 -1
  30. package/dist/recorder/screenRecorder.js.map +1 -1
  31. package/dist/session-recorder.d.ts +3 -1
  32. package/dist/session-recorder.js +1 -1
  33. package/dist/session-recorder.js.map +1 -1
  34. package/dist/types/index.d.ts +32 -1
  35. package/dist/types/index.js +1 -1
  36. package/dist/types/index.js.map +1 -1
  37. package/dist/types/rrweb.d.ts +10 -0
  38. package/dist/utils/index.d.ts +2 -0
  39. package/dist/utils/index.js +1 -1
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/logger.d.ts +112 -0
  42. package/dist/utils/logger.js +1 -0
  43. package/dist/utils/logger.js.map +1 -0
  44. package/dist/utils/rrweb-events.d.ts +65 -0
  45. package/dist/utils/rrweb-events.js +1 -0
  46. package/dist/utils/rrweb-events.js.map +1 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +3 -1
  50. package/src/components/GestureCaptureWrapper.tsx +110 -0
  51. package/src/context/SessionRecorderContext.tsx +76 -81
  52. package/src/otel/helpers.ts +2 -1
  53. package/src/otel/instrumentations/index.ts +5 -4
  54. package/src/otel/instrumentations/reactNativeInstrumentation.ts +2 -1
  55. package/src/patch/xhr.ts +2 -2
  56. package/src/recorder/eventExporter.ts +4 -1
  57. package/src/recorder/gestureHandlerRecorder.ts +157 -0
  58. package/src/recorder/gestureRecorder.ts +93 -19
  59. package/src/recorder/index.ts +16 -18
  60. package/src/recorder/navigationTracker.ts +2 -0
  61. package/src/recorder/screenRecorder.ts +125 -82
  62. package/src/session-recorder.ts +12 -5
  63. package/src/types/index.ts +44 -1
  64. package/src/utils/index.ts +2 -0
  65. package/src/utils/logger.ts +225 -0
  66. package/src/utils/rrweb-events.ts +311 -0
  67. package/src/version.ts +1 -1
  68. package/example-usage.tsx +0 -174
  69. package/src/types/rrweb.ts +0 -122
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});var _platform=require("./platform");Object.keys(_platform).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_platform[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _platform[key];}});});var _session=require("./session");Object.keys(_session).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_session[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _session[key];}});});var _time=require("./time");Object.keys(_time).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_time[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _time[key];}});});var _typeUtils=require("./type-utils");Object.keys(_typeUtils).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_typeUtils[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _typeUtils[key];}});});var _requestUtils=require("./request-utils");Object.keys(_requestUtils).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_requestUtils[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _requestUtils[key];}});});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});var _platform=require("./platform");Object.keys(_platform).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_platform[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _platform[key];}});});var _session=require("./session");Object.keys(_session).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_session[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _session[key];}});});var _time=require("./time");Object.keys(_time).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_time[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _time[key];}});});var _typeUtils=require("./type-utils");Object.keys(_typeUtils).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_typeUtils[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _typeUtils[key];}});});var _requestUtils=require("./request-utils");Object.keys(_requestUtils).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_requestUtils[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _requestUtils[key];}});});var _rrwebEvents=require("./rrweb-events");Object.keys(_rrwebEvents).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_rrwebEvents[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _rrwebEvents[key];}});});var _logger=require("./logger");Object.keys(_logger).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_logger[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _logger[key];}});});
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Centralized logger utility for the session recorder
3
+ * Provides consistent logging across all components
4
+ */
5
+ export declare enum LogLevel {
6
+ DEBUG = 0,
7
+ INFO = 1,
8
+ WARN = 2,
9
+ ERROR = 3
10
+ }
11
+ export interface LoggerConfig {
12
+ level: LogLevel;
13
+ enableConsole: boolean;
14
+ enablePrefix: boolean;
15
+ prefix: string;
16
+ }
17
+ declare class Logger {
18
+ private config;
19
+ private componentPrefixes;
20
+ /**
21
+ * Configure the logger
22
+ * @param config - Logger configuration
23
+ */
24
+ configure(config: Partial<LoggerConfig>): void;
25
+ /**
26
+ * Set the log level
27
+ * @param level - Log level to set
28
+ */
29
+ setLevel(level: LogLevel): void;
30
+ /**
31
+ * Enable or disable console output
32
+ * @param enabled - Whether to enable console output
33
+ */
34
+ setConsoleEnabled(enabled: boolean): void;
35
+ /**
36
+ * Add or update a component prefix
37
+ * @param component - Component name
38
+ * @param emoji - Emoji prefix for the component
39
+ */
40
+ setComponentPrefix(component: string, emoji: string): void;
41
+ /**
42
+ * Get the formatted prefix for a component
43
+ * @param component - Component name
44
+ * @returns Formatted prefix string
45
+ */
46
+ private getPrefix;
47
+ /**
48
+ * Check if a log level should be output
49
+ * @param level - Log level to check
50
+ * @returns True if should output
51
+ */
52
+ private shouldLog;
53
+ /**
54
+ * Format the log message
55
+ * @param component - Component name
56
+ * @param level - Log level
57
+ * @param message - Log message
58
+ * @param data - Additional data to log
59
+ * @returns Formatted log message
60
+ */
61
+ private formatMessage;
62
+ /**
63
+ * Log a debug message
64
+ * @param component - Component name
65
+ * @param message - Log message
66
+ * @param data - Additional data to log
67
+ */
68
+ debug(component: string, message: string, data?: any): void;
69
+ /**
70
+ * Log an info message
71
+ * @param component - Component name
72
+ * @param message - Log message
73
+ * @param data - Additional data to log
74
+ */
75
+ info(component: string, message: string, data?: any): void;
76
+ /**
77
+ * Log a warning message
78
+ * @param component - Component name
79
+ * @param message - Log message
80
+ * @param data - Additional data to log
81
+ */
82
+ warn(component: string, message: string, data?: any): void;
83
+ /**
84
+ * Log an error message
85
+ * @param component - Component name
86
+ * @param message - Log message
87
+ * @param data - Additional data to log
88
+ */
89
+ error(component: string, message: string, data?: any): void;
90
+ /**
91
+ * Log a success message (info level with success emoji)
92
+ * @param component - Component name
93
+ * @param message - Log message
94
+ * @param data - Additional data to log
95
+ */
96
+ success(component: string, message: string, data?: any): void;
97
+ /**
98
+ * Log a failure message (error level with failure emoji)
99
+ * @param component - Component name
100
+ * @param message - Log message
101
+ * @param data - Additional data to log
102
+ */
103
+ failure(component: string, message: string, data?: any): void;
104
+ }
105
+ export declare const logger: Logger;
106
+ export declare const logDebug: (component: string, message: string, data?: any) => void;
107
+ export declare const logInfo: (component: string, message: string, data?: any) => void;
108
+ export declare const logWarn: (component: string, message: string, data?: any) => void;
109
+ export declare const logError: (component: string, message: string, data?: any) => void;
110
+ export declare const logSuccess: (component: string, message: string, data?: any) => void;
111
+ export declare const logFailure: (component: string, message: string, data?: any) => void;
112
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.logger=exports.logWarn=exports.logSuccess=exports.logInfo=exports.logFailure=exports.logError=exports.logDebug=exports.LogLevel=void 0;var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable;})),t.push.apply(t,o);}return t;}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){(0,_defineProperty2["default"])(e,r,t[r]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r));});}return e;}var LogLevel;(function(LogLevel){LogLevel[LogLevel["DEBUG"]=0]="DEBUG";LogLevel[LogLevel["INFO"]=1]="INFO";LogLevel[LogLevel["WARN"]=2]="WARN";LogLevel[LogLevel["ERROR"]=3]="ERROR";})(LogLevel||(exports.LogLevel=LogLevel={}));var Logger=function(){function Logger(){(0,_classCallCheck2["default"])(this,Logger);this.config={level:LogLevel.INFO,enableConsole:true,enablePrefix:true,prefix:'[SessionRecorder]'};this.componentPrefixes=new Map([['ScreenRecorder','📸'],['GestureRecorder','👆'],['GestureCaptureWrapper','📸'],['SessionRecorderContext','🎯'],['EventExporter','📤'],['NavigationTracker','📸'],['RecorderReactNativeSDK','📤'],['DEBUGGER_LIB','🔍']]);}return(0,_createClass2["default"])(Logger,[{key:"configure",value:function configure(config){this.config=_objectSpread(_objectSpread({},this.config),config);}},{key:"setLevel",value:function setLevel(level){this.config.level=level;}},{key:"setConsoleEnabled",value:function setConsoleEnabled(enabled){this.config.enableConsole=enabled;}},{key:"setComponentPrefix",value:function setComponentPrefix(component,emoji){this.componentPrefixes.set(component,emoji);}},{key:"getPrefix",value:function getPrefix(component){if(!this.config.enablePrefix)return'';var emoji=this.componentPrefixes.get(component)||'📝';return"".concat(this.config.prefix," ").concat(emoji," [").concat(component,"]");}},{key:"shouldLog",value:function shouldLog(level){return level>=this.config.level&&this.config.enableConsole;}},{key:"formatMessage",value:function formatMessage(component,level,message,data){var prefix=this.getPrefix(component);var timestamp=new Date().toISOString();var levelName=LogLevel[level];var formattedMessage="".concat(prefix," ").concat(levelName," ").concat(message);if(data!==undefined){formattedMessage+=" ".concat(JSON.stringify(data));}return formattedMessage;}},{key:"debug",value:function debug(component,message,data){if(!this.shouldLog(LogLevel.DEBUG))return;var formattedMessage=this.formatMessage(component,LogLevel.DEBUG,message,data);console.log(formattedMessage);}},{key:"info",value:function info(component,message,data){if(!this.shouldLog(LogLevel.INFO))return;var formattedMessage=this.formatMessage(component,LogLevel.INFO,message,data);console.log(formattedMessage);}},{key:"warn",value:function warn(component,message,data){if(!this.shouldLog(LogLevel.WARN))return;var formattedMessage=this.formatMessage(component,LogLevel.WARN,message,data);console.warn(formattedMessage);}},{key:"error",value:function error(component,message,data){if(!this.shouldLog(LogLevel.ERROR))return;var formattedMessage=this.formatMessage(component,LogLevel.ERROR,message,data);console.error(formattedMessage);}},{key:"success",value:function success(component,message,data){if(!this.shouldLog(LogLevel.INFO))return;var prefix=this.getPrefix(component);var timestamp=new Date().toISOString();var formattedMessage="".concat(prefix," \u2705 ").concat(message);var fullMessage=formattedMessage;if(data!==undefined){fullMessage+=" ".concat(JSON.stringify(data));}console.log(fullMessage);}},{key:"failure",value:function failure(component,message,data){if(!this.shouldLog(LogLevel.ERROR))return;var prefix=this.getPrefix(component);var timestamp=new Date().toISOString();var formattedMessage="".concat(prefix," \u274C ").concat(message);var fullMessage=formattedMessage;if(data!==undefined){fullMessage+=" ".concat(JSON.stringify(data));}console.error(fullMessage);}}]);}();var logger=exports.logger=new Logger();var logDebug=exports.logDebug=function logDebug(component,message,data){return logger.debug(component,message,data);};var logInfo=exports.logInfo=function logInfo(component,message,data){return logger.info(component,message,data);};var logWarn=exports.logWarn=function logWarn(component,message,data){return logger.warn(component,message,data);};var logError=exports.logError=function logError(component,message,data){return logger.error(component,message,data);};var logSuccess=exports.logSuccess=function logSuccess(component,message,data){return logger.success(component,message,data);};var logFailure=exports.logFailure=function logFailure(component,message,data){return logger.failure(component,message,data);};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { eventWithTime, serializedNodeWithId } from '@rrweb/types';
2
+ /**
3
+ * Creates a meta event to mark the start of recording
4
+ * @param sessionId - The session ID
5
+ * @param sessionType - The type of session (PLAIN or CONTINUOUS)
6
+ * @param additionalData - Additional data to include in the meta event
7
+ * @returns MetaEvent object
8
+ */
9
+ export declare function createRecordingMetaEvent(): eventWithTime;
10
+ /**
11
+ * Create a full snapshot event with the given base64 image
12
+ * @param base64Image - Base64 encoded image data
13
+ * @param width - Screen width
14
+ * @param height - Screen height
15
+ * @param captureFormat - Image format (png, jpg, etc.)
16
+ * @param nodeIdCounter - Starting node ID counter (will be modified)
17
+ * @returns Full snapshot event
18
+ */
19
+ export declare function createFullSnapshotEvent(base64Image: string, width: number, height: number, captureFormat: string | undefined, nodeIdCounter: {
20
+ current: number;
21
+ }): eventWithTime;
22
+ /**
23
+ * Create an incremental snapshot event with mutation data to update image src
24
+ * @param base64Image - New base64 encoded image data
25
+ * @param imageNodeId - ID of the image node to update
26
+ * @param captureFormat - Image format (png, jpg, etc.)
27
+ * @returns Incremental snapshot event with mutation data
28
+ */
29
+ export declare function createIncrementalSnapshotWithImageUpdate(base64Image: string, imageNodeId: number, captureFormat?: string): eventWithTime;
30
+ /**
31
+ * Create a simple image node for React Native screen capture
32
+ * @param base64Image - Base64 encoded image data
33
+ * @param width - Image width
34
+ * @param height - Image height
35
+ * @param captureFormat - Image format (png, jpg, etc.)
36
+ * @param nodeId - Node ID for the image
37
+ * @returns Serialized node with ID
38
+ */
39
+ export declare function createImageNode(base64Image: string, width: number, height: number, captureFormat: string | undefined, nodeId: number): serializedNodeWithId;
40
+ /**
41
+ * Create a document node for React Native screen capture
42
+ * @param imageNode - The image node to include
43
+ * @param width - Screen width
44
+ * @param height - Screen height
45
+ * @param nodeIdCounter - Node ID counter (will be modified)
46
+ * @returns Document node
47
+ */
48
+ export declare function createDocumentNode(imageNode: serializedNodeWithId, width: number, height: number, nodeIdCounter: {
49
+ current: number;
50
+ }): serializedNodeWithId;
51
+ /**
52
+ * Generate a simple hash for screen comparison
53
+ * This is a lightweight hash that focuses on the beginning and end of the base64 string
54
+ * to detect changes without doing a full comparison
55
+ * @param base64Image - Base64 encoded image
56
+ * @param sampleSize - Number of characters to sample from each part
57
+ * @returns Hash string for comparison
58
+ */
59
+ export declare function generateScreenHash(base64Image: string, sampleSize?: number): string;
60
+ /**
61
+ * Simple hash function for string comparison
62
+ * @param str - String to hash
63
+ * @returns Hash value as string
64
+ */
65
+ export declare function simpleHash(str: string): string;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.createDocumentNode=createDocumentNode;exports.createFullSnapshotEvent=createFullSnapshotEvent;exports.createImageNode=createImageNode;exports.createIncrementalSnapshotWithImageUpdate=createIncrementalSnapshotWithImageUpdate;exports.createRecordingMetaEvent=createRecordingMetaEvent;exports.generateScreenHash=generateScreenHash;exports.simpleHash=simpleHash;var _reactNative=require("react-native");var _types=require("@rrweb/types");function createRecordingMetaEvent(){var screenDimensions=_reactNative.Dimensions.get('window');return{type:_types.EventType.Meta,data:{href:'https://go.multiplayer.app/session-recorder-react-native',width:screenDimensions.width,height:screenDimensions.height},timestamp:Date.now()};}function createFullSnapshotEvent(base64Image,width,height){var captureFormat=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'jpg';var nodeIdCounter=arguments.length>4?arguments[4]:undefined;var imageNodeId=nodeIdCounter.current++;var imageNode={type:_types.NodeType.Element,id:imageNodeId,tagName:'img',attributes:{src:"data:image/".concat(captureFormat,";base64,").concat(base64Image),width:width.toString(),height:height.toString(),style:"width: ".concat(width,"px; height: ").concat(height,"px;")},childNodes:[]};var rootNode={type:_types.NodeType.Element,id:nodeIdCounter.current++,tagName:'div',attributes:{style:"width: ".concat(width,"px; height: ").concat(height,"px; position: relative;")},childNodes:[imageNode]};var domNode={type:_types.NodeType.Document,childNodes:[{type:_types.NodeType.DocumentType,name:'html',publicId:'',systemId:'',id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'html',attributes:{},childNodes:[{type:_types.NodeType.Element,tagName:'head',attributes:{},childNodes:[{type:_types.NodeType.Element,tagName:'meta',attributes:{charset:'utf-8'},childNodes:[],id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'meta',attributes:{name:'viewport',content:'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'},childNodes:[],id:nodeIdCounter.current++}],id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'body',attributes:{},childNodes:[rootNode],id:nodeIdCounter.current++}],id:nodeIdCounter.current++}],id:nodeIdCounter.current++};return{type:_types.EventType.FullSnapshot,data:{node:domNode,initialOffset:{left:0,top:0}},timestamp:Date.now()};}function createIncrementalSnapshotWithImageUpdate(base64Image,imageNodeId){var captureFormat=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'jpg';var mutationData={source:_types.IncrementalSource.Mutation,texts:[],attributes:[{id:imageNodeId,attributes:{src:"data:image/".concat(captureFormat,";base64,").concat(base64Image)}}],removes:[],adds:[]};return{type:_types.EventType.IncrementalSnapshot,data:mutationData,timestamp:Date.now()};}function createImageNode(base64Image,width,height){var captureFormat=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'jpg';var nodeId=arguments.length>4?arguments[4]:undefined;return{type:_types.NodeType.Element,id:nodeId,tagName:'img',attributes:{src:"data:image/".concat(captureFormat,";base64,").concat(base64Image),width:width.toString(),height:height.toString(),style:"width: ".concat(width,"px; height: ").concat(height,"px;")},childNodes:[]};}function createDocumentNode(imageNode,width,height,nodeIdCounter){var rootNode={type:_types.NodeType.Element,id:nodeIdCounter.current++,tagName:'div',attributes:{style:"width: ".concat(width,"px; height: ").concat(height,"px; position: relative;")},childNodes:[imageNode]};return{type:_types.NodeType.Document,childNodes:[{type:_types.NodeType.DocumentType,name:'html',publicId:'',systemId:'',id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'html',attributes:{},childNodes:[{type:_types.NodeType.Element,tagName:'head',attributes:{},childNodes:[{type:_types.NodeType.Element,tagName:'meta',attributes:{charset:'utf-8'},childNodes:[],id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'meta',attributes:{name:'viewport',content:'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'},childNodes:[],id:nodeIdCounter.current++}],id:nodeIdCounter.current++},{type:_types.NodeType.Element,tagName:'body',attributes:{},childNodes:[rootNode],id:nodeIdCounter.current++}],id:nodeIdCounter.current++}],id:nodeIdCounter.current++};}function generateScreenHash(base64Image){var sampleSize=arguments.length>1&&arguments[1]!==undefined?arguments[1]:100;var start=base64Image.substring(0,sampleSize);var middle=base64Image.substring(Math.floor(base64Image.length/2)-sampleSize/2,Math.floor(base64Image.length/2)+sampleSize/2);var end=base64Image.substring(base64Image.length-sampleSize);var combined=start+middle+end;return simpleHash(combined);}function simpleHash(str){var hash=0;for(var i=0;i<str.length;i++){var _char=str.charCodeAt(i);hash=(hash<<5)-hash+_char;hash=hash&hash;}return Math.abs(hash).toString(36);}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rrweb-events.js","sourceRoot":"","sources":["../../src/utils/rrweb-events.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.0.1-alpha.7";
1
+ export declare const version = "0.0.1-alpha.9";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.version=void 0;var version=exports.version="0.0.1-alpha.7";
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.version=void 0;var version=exports.version="0.0.1-alpha.9";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplayer-app/session-recorder-react-native",
3
- "version": "0.0.1-alpha.7",
3
+ "version": "0.0.1-alpha.9",
4
4
  "description": "Multiplayer Fullstack Session Recorder for React Native",
5
5
  "author": {
6
6
  "name": "Multiplayer Software, Inc.",
@@ -79,11 +79,13 @@
79
79
  "@react-native-async-storage/async-storage": "^1.21.0",
80
80
  "@react-native-community/netinfo": "^11.1.0",
81
81
  "@rrweb/packer": "^2.0.0-alpha.15",
82
+ "@rrweb/types": "^2.0.0-alpha.18",
82
83
  "lib0": "0.2.82",
83
84
  "react-native-gesture-handler": "^2.14.0",
84
85
  "react-native-mmkv": "^2.11.0",
85
86
  "react-native-reanimated": "^3.6.0",
86
87
  "react-native-view-shot": "^4.0.3",
88
+ "rrweb": "^2.0.0-alpha.15",
87
89
  "socket.io-client": "4.7.5"
88
90
  },
89
91
  "peerDependencies": {
@@ -0,0 +1,110 @@
1
+ import React, { ReactNode, useCallback, useEffect, useMemo, useRef } from 'react'
2
+ import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler'
3
+ import { GestureInstrumentation } from '../otel/instrumentations/gestureInstrumentation'
4
+ import { logger } from '../utils'
5
+
6
+ export interface GestureCaptureWrapperProps {
7
+ children: ReactNode
8
+ onGestureRecord: (gestureType: string, data: any) => void
9
+ }
10
+
11
+ export const GestureCaptureWrapper: React.FC<GestureCaptureWrapperProps> = ({ children, onGestureRecord }) => {
12
+ const gestureInstrumentation = useRef(new GestureInstrumentation())
13
+
14
+ useEffect(() => {
15
+ gestureInstrumentation.current.enable()
16
+ }, [])
17
+
18
+ const recordGesture = useCallback(
19
+ (gestureType: string, data: any) => {
20
+ // Record with OpenTelemetry
21
+ logger.debug('GestureCaptureWrapper', 'Recording gesture', { gestureType, data })
22
+ switch (gestureType) {
23
+ case 'tap':
24
+ gestureInstrumentation.current.recordTap(data.x, data.y)
25
+ break
26
+ case 'pan_start':
27
+ case 'pan_update':
28
+ case 'pan_end':
29
+ gestureInstrumentation.current.recordPan(data.translationX || 0, data.translationY || 0)
30
+ break
31
+ case 'long_press':
32
+ gestureInstrumentation.current.recordLongPress(data.duration, undefined)
33
+ break
34
+ }
35
+
36
+ // Record with session recorder
37
+ onGestureRecord(gestureType, data)
38
+ },
39
+ [onGestureRecord]
40
+ )
41
+
42
+ // Create tap gesture
43
+ const tapGesture = useMemo(() => {
44
+ return Gesture.Tap()
45
+ .runOnJS(true)
46
+ .onStart((event) => {
47
+ recordGesture('tap', {
48
+ x: event.x,
49
+ y: event.y,
50
+ timestamp: Date.now()
51
+ })
52
+ })
53
+ }, [recordGesture])
54
+
55
+ // Create pan gesture (for swipes and drags)
56
+ const panGesture = useMemo(() => {
57
+ return Gesture.Pan()
58
+ .runOnJS(true)
59
+ .onStart((event) => {
60
+ recordGesture('pan_start', {
61
+ x: event.x,
62
+ y: event.y,
63
+ timestamp: Date.now()
64
+ })
65
+ })
66
+ .onUpdate((event) => {
67
+ recordGesture('pan_update', {
68
+ x: event.x,
69
+ y: event.y,
70
+ translationX: event.translationX,
71
+ translationY: event.translationY,
72
+ velocityX: event.velocityX,
73
+ velocityY: event.velocityY,
74
+ timestamp: Date.now()
75
+ })
76
+ })
77
+ .onEnd((event) => {
78
+ recordGesture('pan_end', {
79
+ x: event.x,
80
+ y: event.y,
81
+ translationX: event.translationX,
82
+ translationY: event.translationY,
83
+ velocityX: event.velocityX,
84
+ velocityY: event.velocityY,
85
+ timestamp: Date.now()
86
+ })
87
+ })
88
+ }, [recordGesture])
89
+
90
+ // Create long press gesture
91
+ const longPressGesture = useMemo(() => {
92
+ return Gesture.LongPress()
93
+ .runOnJS(true)
94
+ .minDuration(500)
95
+ .onStart((event) => {
96
+ recordGesture('long_press', {
97
+ x: event.x,
98
+ y: event.y,
99
+ duration: 500,
100
+ timestamp: Date.now()
101
+ })
102
+ })
103
+ }, [recordGesture])
104
+
105
+ return (
106
+ <GestureHandlerRootView style={{ flex: 1 }}>
107
+ <GestureDetector gesture={Gesture.Simultaneous(tapGesture, panGesture, longPressGesture)}>{children}</GestureDetector>
108
+ </GestureHandlerRootView>
109
+ )
110
+ }
@@ -1,46 +1,50 @@
1
- import React, { createContext, useContext, ReactNode, PropsWithChildren, useMemo, useState, useEffect, useRef } from 'react'
1
+ import React, { createContext, useContext, ReactNode, PropsWithChildren, useState, useEffect, useRef, useCallback } from 'react'
2
2
  import { Pressable, Text, View } from 'react-native'
3
3
  import { SessionRecorderOptions, SessionState } from '../types'
4
4
  import SessionRecorder from '../session-recorder'
5
+ import { GestureCaptureWrapper } from '../components/GestureCaptureWrapper'
6
+ import sessionRecorder from '../session-recorder'
7
+ import { logger } from '../utils'
5
8
 
6
9
  interface SessionRecorderContextType {
7
- client: typeof SessionRecorder
10
+ instance: typeof SessionRecorder
8
11
  }
9
12
 
10
13
  const SessionRecorderContext = createContext<SessionRecorderContextType | null>(null)
11
14
 
12
15
  export interface SessionRecorderProviderProps extends PropsWithChildren {
13
16
  options: SessionRecorderOptions
14
- client?: typeof SessionRecorder
15
17
  }
16
18
 
17
- export const SessionRecorderProvider: React.FC<SessionRecorderProviderProps> = ({ children, client, options }) => {
19
+ export const SessionRecorderProvider: React.FC<SessionRecorderProviderProps> = ({ children, options }) => {
18
20
  const [sessionState, setSessionState] = useState<SessionState | null>(null)
21
+ const optionsRef = useRef<string>()
19
22
 
20
- const sessionRecorder = useMemo(() => {
21
- if (client) return client
23
+ useEffect(() => {
24
+ const newOptions = JSON.stringify(options)
25
+ if (optionsRef.current === JSON.stringify(options)) return
26
+ optionsRef.current = newOptions
22
27
  SessionRecorder.init(options)
23
- return SessionRecorder
24
- }, [])
28
+ }, [options])
25
29
 
26
30
  useEffect(() => {
27
- if (!sessionRecorder) return
28
- setSessionState(sessionRecorder.sessionState)
29
- }, [sessionRecorder])
31
+ setSessionState(SessionRecorder.sessionState)
32
+ SessionRecorder.on('state-change', (state: SessionState) => {
33
+ setSessionState(state)
34
+ })
35
+ }, [])
30
36
 
31
37
  const onToggleSession = () => {
32
- if (sessionState === SessionState.started) {
33
- setSessionState(SessionState.stopped)
34
- sessionRecorder.stop()
38
+ if (SessionRecorder.sessionState === SessionState.started) {
39
+ SessionRecorder.stop()
35
40
  } else {
36
- setSessionState(SessionState.started)
37
- sessionRecorder.start()
41
+ SessionRecorder.start()
38
42
  }
39
43
  }
40
44
 
41
45
  return (
42
- <SessionRecorderContext.Provider value={{ client: sessionRecorder }}>
43
- <TouchEventCapture>
46
+ <SessionRecorderContext.Provider value={{ instance: sessionRecorder }}>
47
+ <GestureEventCapture>
44
48
  {children}
45
49
  <Pressable onPress={onToggleSession}>
46
50
  <View
@@ -60,82 +64,73 @@ export const SessionRecorderProvider: React.FC<SessionRecorderProviderProps> = (
60
64
  <Text style={{ color: 'white' }}>{sessionState === SessionState.started ? 'Stop' : 'Start'}</Text>
61
65
  </View>
62
66
  </Pressable>
63
- </TouchEventCapture>
67
+ </GestureEventCapture>
64
68
  </SessionRecorderContext.Provider>
65
69
  )
66
70
  }
67
71
 
68
- // Touch event capture component
69
- const TouchEventCapture: React.FC<{ children: ReactNode }> = ({ children }) => {
70
- const context = useContext(SessionRecorderContext)
71
- const viewShotRef = useRef<View>(null)
72
-
73
- // Set the viewshot ref in the session recorder when component mounts
74
- useEffect(() => {
75
- if (context?.client && viewShotRef.current) {
76
- context.client.setViewShotRef?.(viewShotRef.current)
77
- }
78
- }, [context?.client])
79
-
80
- // Callback ref to set the viewshot ref immediately when available
81
- const setViewShotRef = (ref: View | null) => {
82
- if (ref && context?.client) {
83
- context.client.setViewShotRef?.(ref)
84
- }
85
- }
86
-
87
- const handleTouchStart = (event: any) => {
88
- if (!context?.client || context.client.sessionState !== SessionState.started) return // SessionState.started
89
-
90
- try {
91
- const { pageX, pageY, target } = event.nativeEvent
92
- const pressure = event.nativeEvent.force || 1.0
93
-
94
- // Record touch start event automatically
95
- context.client.recordTouchStart?.(pageX, pageY, target?.toString(), pressure)
96
- } catch (error) {
97
- console.warn('Failed to record touch start event:', error)
72
+ // Gesture-based event capture component
73
+ const GestureEventCapture: React.FC<{ children: ReactNode }> = ({ children }) => {
74
+ // Set up gesture recording callback
75
+ const handleGestureRecord = useCallback((gestureType: string, data: any) => {
76
+ if (SessionRecorder.sessionState !== SessionState.started) {
77
+ logger.debug('SessionRecorderContext', 'Gesture recording skipped', {
78
+ client: !!SessionRecorder.sessionState,
79
+ sessionState: SessionRecorder.sessionState
80
+ })
81
+ return
98
82
  }
99
- }
100
-
101
- const handleTouchMove = (event: any) => {
102
- if (!context?.client || context.client.sessionState !== SessionState.started) return // SessionState.started
103
-
83
+ logger.debug('SessionRecorderContext', 'Gesture recorded', { gestureType, data })
104
84
  try {
105
- const { pageX, pageY, target } = event.nativeEvent
106
- const pressure = event.nativeEvent.force || 1.0
107
-
108
- // Record touch move event automatically
109
- context.client.recordTouchMove?.(pageX, pageY, target?.toString(), pressure)
85
+ // Record gesture as appropriate touch events
86
+ switch (gestureType) {
87
+ case 'tap':
88
+ // For tap, record both touch start and end
89
+ logger.debug('SessionRecorderContext', 'Recording tap as touch start + end')
90
+ SessionRecorder.recordTouchStart?.(data.x, data.y, undefined, 1.0)
91
+ SessionRecorder.recordTouchEnd?.(data.x, data.y, undefined, 1.0)
92
+ break
93
+
94
+ case 'pan_start':
95
+ logger.debug('SessionRecorderContext', 'Recording pan_start as touch start')
96
+ SessionRecorder.recordTouchStart?.(data.x, data.y, undefined, 1.0)
97
+ break
98
+
99
+ case 'pan_update':
100
+ logger.debug('SessionRecorderContext', 'Recording pan_update as touch move')
101
+ SessionRecorder.recordTouchMove?.(data.x, data.y, undefined, 1.0)
102
+ break
103
+
104
+ case 'pan_end':
105
+ logger.debug('SessionRecorderContext', 'Recording pan_end as touch end')
106
+ SessionRecorder.recordTouchEnd?.(data.x, data.y, undefined, 1.0)
107
+ break
108
+
109
+ case 'long_press':
110
+ logger.debug('SessionRecorderContext', 'Recording long_press as touch start + end')
111
+ SessionRecorder.recordTouchStart?.(data.x, data.y, undefined, 1.0)
112
+ SessionRecorder.recordTouchEnd?.(data.x, data.y, undefined, 1.0)
113
+ break
114
+ default:
115
+ }
110
116
  } catch (error) {
111
- console.warn('Failed to record touch move event:', error)
117
+ logger.error('SessionRecorderContext', 'Failed to record gesture event', error)
112
118
  }
113
- }
114
-
115
- const handleTouchEnd = (event: any) => {
116
- if (!context?.client || context.client.sessionState !== SessionState.started) return // SessionState.started
117
-
118
- try {
119
- const { pageX, pageY, target } = event.nativeEvent
120
- const pressure = event.nativeEvent.force || 1.0
119
+ }, [])
121
120
 
122
- // Record touch end event automatically
123
- context.client.recordTouchEnd?.(pageX, pageY, target?.toString(), pressure)
124
- } catch (error) {
125
- console.warn('Failed to record touch end event:', error)
121
+ // Callback ref to set the viewshot ref immediately when available
122
+ const setViewShotRef = (ref: View | null) => {
123
+ if (ref) {
124
+ SessionRecorder.setViewShotRef?.(ref)
126
125
  }
127
126
  }
128
127
 
129
128
  return (
130
- <View
131
- ref={setViewShotRef}
132
- style={{ flex: 1 }}
133
- onTouchStart={handleTouchStart}
134
- onTouchMove={handleTouchMove}
135
- onTouchEnd={handleTouchEnd}
136
- >
137
- {children}
138
- </View>
129
+ <GestureCaptureWrapper onGestureRecord={handleGestureRecord}>
130
+ <View ref={setViewShotRef} style={{ flex: 1 }}>
131
+ {children}
132
+ </View>
133
+ </GestureCaptureWrapper>
139
134
  )
140
135
  }
141
136
 
@@ -7,6 +7,7 @@ import {
7
7
  ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,
8
8
  ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,
9
9
  } from '@multiplayer-app/session-recorder-common'
10
+ import { logger } from '../utils'
10
11
  import { SessionRecorderSdk } from '@multiplayer-app/session-recorder-common'
11
12
  import { TracerReactNativeConfig } from '../types'
12
13
 
@@ -249,7 +250,7 @@ export async function extractResponseBody(response: Response): Promise<string |
249
250
  } catch (error) {
250
251
  // If cloning fails (body already consumed), return null
251
252
  // eslint-disable-next-line no-console
252
- console.warn('[DEBUGGER_LIB] Failed to extract response body:', error)
253
+ logger.warn('DEBUGGER_LIB', 'Failed to extract response body', error)
253
254
  return null
254
255
  }
255
256
  }
@@ -4,6 +4,7 @@ import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xm
4
4
  import { OTEL_IGNORE_URLS } from '../../config'
5
5
  import { TracerReactNativeConfig } from '../../types'
6
6
  import { extractResponseBody, headersToObject, processHttpPayload } from '../helpers'
7
+ import { logger } from '../../utils'
7
8
 
8
9
  export function getInstrumentations(config: TracerReactNativeConfig) {
9
10
 
@@ -47,13 +48,13 @@ export function getInstrumentations(config: TracerReactNativeConfig) {
47
48
  processHttpPayload(payload, config, span)
48
49
  } catch (error) {
49
50
  // eslint-disable-next-line
50
- console.error('[DEBUGGER_LIB] Failed to capture fetch payload', error)
51
+ logger.error('DEBUGGER_LIB', 'Failed to capture fetch payload', error)
51
52
  }
52
53
  },
53
54
  })
54
55
  )
55
56
  } catch (error) {
56
- console.warn('Fetch instrumentation not available:', error)
57
+ logger.warn('DEBUGGER_LIB', 'Fetch instrumentation not available', error)
57
58
  }
58
59
 
59
60
  // XMLHttpRequest instrumentation
@@ -94,13 +95,13 @@ export function getInstrumentations(config: TracerReactNativeConfig) {
94
95
  processHttpPayload(payload, config, span)
95
96
  } catch (error) {
96
97
  // eslint-disable-next-line
97
- console.error('[DEBUGGER_LIB] Failed to capture xml-http payload', error)
98
+ logger.error('DEBUGGER_LIB', 'Failed to capture xml-http payload', error)
98
99
  }
99
100
  },
100
101
  })
101
102
  )
102
103
  } catch (error) {
103
- console.warn('XMLHttpRequest instrumentation not available:', error)
104
+ logger.warn('DEBUGGER_LIB', 'XMLHttpRequest instrumentation not available', error)
104
105
  }
105
106
 
106
107
  // Custom React Native instrumentations