core-outline 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var React = require('react');
4
6
  var uuid = require('uuid');
5
7
  var engine_ioClient = require('engine.io-client');
@@ -5966,12 +5968,15 @@ Object.assign(lookup, {
5966
5968
  connect: lookup,
5967
5969
  });
5968
5970
 
5969
- const socket = lookup("http://localhost:4000");
5971
+ const socket = lookup('http://localhost:8000');
5972
+
5970
5973
  const CoreOutline = ({
5971
5974
  children,
5972
- data_source_id
5975
+ data_source_id,
5976
+ data_source_secret
5973
5977
  }) => {
5974
5978
  const [events, setEvents] = React.useState([]);
5979
+ const [replayEvents, setReplayEvents] = React.useState([]);
5975
5980
  const recorderActive = React.useRef(false);
5976
5981
  const [currentPage, setCurrentPage] = React.useState(window.location.href);
5977
5982
  const [location, setLocation] = React.useState({
@@ -5979,36 +5984,87 @@ const CoreOutline = ({
5979
5984
  longitude: null
5980
5985
  });
5981
5986
  const [browser, setBrowser] = React.useState(getBrowserInfo());
5982
- const sessionId = uuid.v4();
5983
- React.useEffect(() => {
5984
- socket.emit("dataEvent", {
5985
- topic: "session-data",
5987
+ const [appToken, setAppToken] = React.useState('');
5988
+ const [sessionId, setSessionId] = React.useState('');
5989
+ async function authorizeApp(data_source_id, data_source_secret) {
5990
+ const requestOptions = {
5991
+ method: 'POST',
5992
+ headers: {
5993
+ 'Content-Type': 'application/json'
5994
+ },
5995
+ body: JSON.stringify({
5996
+ data_source_id: data_source_id,
5997
+ data_source_secret: data_source_secret
5998
+ })
5999
+ };
6000
+ const response = fetch(`http://localhost:4000/data-source/authorize`, requestOptions).then(response => response.json()).then(data => {
6001
+ setAppToken(data.app_token);
6002
+ return data;
6003
+ }).catch(error => {
6004
+ console.error('Error:', error);
6005
+ return error;
6006
+ });
6007
+ return response;
6008
+ }
6009
+ React.useEffect(async () => {
6010
+ await authorizeApp(data_source_id, data_source_secret);
6011
+ setSessionId(uuid.v4());
6012
+ localStorage.setItem('coreOutlineSessionId', sessionId);
6013
+ localStorage.setItem('coreOutlineDataSourceIdId', data_source_id);
6014
+ console.log('Session', sessionId);
6015
+ socket.send({
6016
+ topic: 'session-data',
5986
6017
  data_source_id: data_source_id,
5987
6018
  session_id: sessionId,
5988
6019
  start_date: new Date().toLocaleString(),
5989
6020
  latitude: location.latitude,
5990
6021
  longitude: location.longitude,
5991
6022
  browser: browser,
5992
- event_id: "SESSION_START"
6023
+ event_id: 'SESSION_START'
5993
6024
  });
5994
6025
  return () => {
5995
- socket.emit("dataEvent", {
5996
- topic: "session-data",
6026
+ socket.send({
6027
+ topic: 'session-data',
5997
6028
  data_source_id: data_source_id,
5998
6029
  session_id: sessionId,
5999
6030
  start_date: new Date().toLocaleString(),
6000
6031
  latitude: location.latitude,
6001
6032
  longitude: location.longitude,
6002
6033
  browser: browser,
6003
- event_id: "SESSION_END"
6034
+ event_id: 'SESSION_END'
6004
6035
  });
6005
6036
  };
6006
6037
  }, []);
6007
6038
  React.useEffect(() => {
6039
+ const navigationEvent = {
6040
+ type: 4,
6041
+ data: {
6042
+ href: window.location.href,
6043
+ width: 1536,
6044
+ height: 730
6045
+ },
6046
+ timestamp: Date.now()
6047
+ };
6048
+ const startTime = performance.now();
6049
+ const observer = new MutationObserver(() => {
6050
+ const endTime = performance.now();
6051
+ const loadTime = endTime - startTime;
6052
+ navigationEvent.data.loadTime = loadTime;
6053
+ const hours = Math.floor(loadTime / 3600000);
6054
+ const minutes = Math.floor(loadTime % 3600000 / 60000);
6055
+ const seconds = Math.floor(loadTime % 60000 / 1000);
6056
+ navigationEvent.data.loadTimeFormatted = `${hours} hours ${minutes} minutes ${seconds} seconds`;
6057
+ observer.disconnect();
6058
+ });
6059
+ observer.observe(document, {
6060
+ childList: true,
6061
+ subtree: true
6062
+ });
6063
+ setEvents(prevEvents => [...prevEvents, navigationEvent]);
6008
6064
  const handleNavigation = () => {
6009
6065
  setCurrentPage(window.location.href);
6010
- socket.emit("dataEvent", {
6011
- topic: "session-data",
6066
+ socket.send({
6067
+ topic: 'session-data',
6012
6068
  data_source_id: data_source_id,
6013
6069
  session_id: sessionId,
6014
6070
  start_date: new Date().toLocaleString(),
@@ -6016,23 +6072,23 @@ const CoreOutline = ({
6016
6072
  longitude: location.longitude,
6017
6073
  browser: browser,
6018
6074
  page_name: window.location.href,
6019
- event_id: "PAGE_NAVIGATION"
6075
+ event_id: 'PAGE_NAVIGATION'
6020
6076
  });
6021
6077
  saveEvents(events);
6022
6078
  };
6023
- window.addEventListener("popstate", handleNavigation);
6079
+ window.addEventListener('popstate', handleNavigation);
6024
6080
  const originalPushState = window.history.pushState;
6025
6081
  window.history.pushState = function (...args) {
6026
6082
  originalPushState.apply(this, args);
6027
6083
  handleNavigation();
6028
6084
  };
6029
6085
  return () => {
6030
- window.removeEventListener("popstate", handleNavigation);
6086
+ window.removeEventListener('popstate', handleNavigation);
6031
6087
  window.history.pushState = originalPushState;
6032
6088
  };
6033
6089
  }, [currentPage]);
6034
6090
  React.useEffect(() => {
6035
- console.log("Location", location);
6091
+ console.log('Location', location);
6036
6092
  getLocation();
6037
6093
  }, []);
6038
6094
  React.useEffect(() => {
@@ -6040,8 +6096,46 @@ const CoreOutline = ({
6040
6096
  if (!recorderActive.current) {
6041
6097
  stopFn = record({
6042
6098
  emit(event) {
6099
+ setReplayEvents(prevEvents => [...prevEvents, event]);
6100
+ },
6101
+ maskAllInputs: false,
6102
+ maskTextSelector: null
6103
+ });
6104
+ recorderActive.current = true;
6105
+ }
6106
+ return () => {
6107
+ if (stopFn) {
6108
+ stopFn();
6109
+ saveEvents(events);
6110
+ recorderActive.current = false;
6111
+ }
6112
+ };
6113
+ }, []);
6114
+ React.useEffect(() => {
6115
+ let stopFn;
6116
+ if (!recorderActive.current) {
6117
+ stopFn = record({
6118
+ emit(event) {
6119
+ console.log('Event:', event);
6120
+ if (event.type == 3 && event.data.type == 2) {
6121
+ return;
6122
+ }
6123
+ if (event.type == 4) {
6124
+ return;
6125
+ }
6126
+ if (event.type == 3 && event.data.source == 0) {
6127
+ return;
6128
+ }
6129
+ if (event.type == 3 && event.data.source == 1) {
6130
+ return;
6131
+ }
6132
+ if (event.type == 3 && event.data.type == 3) {
6133
+ console.log('Contextmenu Event:', event);
6134
+ }
6043
6135
  setEvents(prevEvents => [...prevEvents, event]);
6044
- }
6136
+ },
6137
+ maskAllInputs: false,
6138
+ maskTextSelector: null
6045
6139
  });
6046
6140
  recorderActive.current = true;
6047
6141
  }
@@ -6055,62 +6149,96 @@ const CoreOutline = ({
6055
6149
  }, []);
6056
6150
  React.useEffect(() => {
6057
6151
  const handleClick = event => {
6058
- console.log("Button clicked:", event.target.id);
6059
- // const itemId = event.target.id;
6060
- socket.emit("dataEvent", {
6061
- topic: "session-data",
6152
+ console.log('Inner text:', event.target.innerText);
6153
+ const clickEvent = {
6154
+ type: EventType.IncrementalSnapshot,
6155
+ data: {
6156
+ source: IncrementalSource.MouseInteraction,
6157
+ type: MouseInteractions.Click,
6158
+ id: event.target.id,
6159
+ x: event.clientX,
6160
+ y: event.clientY
6161
+ },
6162
+ timestamp: Date.now()
6163
+ };
6164
+ const clickedElement = document.elementFromPoint(clickEvent.data.x, clickEvent.data.y);
6165
+ if (clickedElement) {
6166
+ clickEvent.data.metadata = {
6167
+ label: clickedElement.getAttribute('data-label') || clickedElement.innerText || null,
6168
+ value: clickedElement.getAttribute('value') || clickedElement.innerText || null,
6169
+ id: clickedElement.getAttribute('id') || clickedElement.innerText || null,
6170
+ name: clickedElement.getAttribute('name') || clickedElement.innerText || null,
6171
+ class: clickedElement.getAttribute('class') || clickedElement.innerText || null,
6172
+ tag: clickedElement.tagName,
6173
+ html: String(clickedElement.getHTML()),
6174
+ innerText: event.target.innerText
6175
+ };
6176
+ }
6177
+ setEvents(prevEvents => [...prevEvents, clickEvent]);
6178
+ socket.send({
6179
+ topic: 'session-data',
6062
6180
  data_source_id: data_source_id,
6063
6181
  session_id: sessionId,
6064
6182
  start_date: new Date().toLocaleString(),
6065
6183
  latitude: location.latitude,
6066
6184
  longitude: location.longitude,
6067
6185
  browser: browser,
6068
- event_id: "ITEM_CLICKED",
6069
- item_clicked: event.target
6186
+ event_id: 'ITEM_CLICKED'
6187
+ // item_clicked: event.target,
6070
6188
  });
6071
6189
  };
6072
- document.addEventListener("click", handleClick);
6190
+ document.addEventListener('click', handleClick);
6073
6191
  return () => {
6074
- document.removeEventListener("click", handleClick);
6192
+ document.removeEventListener('click', handleClick);
6075
6193
  };
6076
6194
  }, []);
6077
6195
  function saveEvents(events) {
6078
6196
  const requestOptions = {
6079
- method: "PUT",
6197
+ method: 'PUT',
6080
6198
  headers: {
6081
- "Content-Type": "application/json"
6199
+ 'Content-Type': 'application/json'
6082
6200
  },
6083
6201
  body: JSON.stringify(events)
6084
6202
  };
6085
- fetch(`http://localhost:8000/generate-s3-url/${data_source_id}/${sessionId}`).then(response => response.json()).then(data => {
6203
+ fetch(`http://localhost:5000/generate-s3-url/${data_source_id}/${sessionId}`).then(response => response.json()).then(data => {
6086
6204
  const uploadURL = data.signed_url;
6087
6205
  return fetch(uploadURL, requestOptions);
6088
6206
  });
6089
6207
  }
6208
+ function saveEventsLocally(type = 'formatted' ) {
6209
+ let blob = '';
6210
+ if (type === 'formatted') {
6211
+ blob = new Blob([JSON.stringify(events, null, 2)], {
6212
+ type: 'application/json'
6213
+ });
6214
+ } else if (type === 'raw') {
6215
+ blob = new Blob([JSON.stringify(replayEvents, null, 2)], {
6216
+ type: 'application/json'
6217
+ });
6218
+ }
6219
+ const url = URL.createObjectURL(blob);
6220
+ const a = document.createElement('a');
6221
+ a.href = url;
6222
+ a.download = `${type}_events.json`;
6223
+ a.click();
6224
+ URL.revokeObjectURL(url);
6225
+ }
6090
6226
  function getBrowserInfo() {
6091
6227
  const userAgent = navigator.userAgent;
6092
- let browserName = "Unknown";
6093
- if (userAgent.indexOf("Firefox") > -1) {
6094
- browserName = "Firefox";
6095
- } else if (userAgent.indexOf("Opera") > -1 || userAgent.indexOf("OPR") > -1) {
6096
- browserName = "Opera";
6097
- } else if (userAgent.indexOf("Chrome") > -1) {
6098
- browserName = "Chrome";
6099
- } else if (userAgent.indexOf("Safari") > -1) {
6100
- browserName = "Safari";
6101
- } else if (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident/") > -1) {
6102
- browserName = "Internet Explorer";
6228
+ let browserName = 'Unknown';
6229
+ if (userAgent.indexOf('Firefox') > -1) {
6230
+ browserName = 'Firefox';
6231
+ } else if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) {
6232
+ browserName = 'Opera';
6233
+ } else if (userAgent.indexOf('Chrome') > -1) {
6234
+ browserName = 'Chrome';
6235
+ } else if (userAgent.indexOf('Safari') > -1) {
6236
+ browserName = 'Safari';
6237
+ } else if (userAgent.indexOf('MSIE') > -1 || userAgent.indexOf('Trident/') > -1) {
6238
+ browserName = 'Internet Explorer';
6103
6239
  }
6104
6240
  return browserName;
6105
6241
  }
6106
- React.useEffect(() => {
6107
- if (events.length > 0) {
6108
- socket.emit("record-event", {
6109
- sessionId,
6110
- events
6111
- });
6112
- }
6113
- }, [events]);
6114
6242
  function getLocation() {
6115
6243
  if (navigator.geolocation) {
6116
6244
  navigator.geolocation.getCurrentPosition(position => {
@@ -6119,13 +6247,56 @@ const CoreOutline = ({
6119
6247
  longitude: position.coords.longitude
6120
6248
  });
6121
6249
  }, error => {
6122
- console.error("Error getting location:", error);
6250
+ console.error('Error getting location:', error);
6123
6251
  });
6124
6252
  } else {
6125
- console.error("Geolocation is not supported by this browser.");
6253
+ console.error('Geolocation is not supported by this browser.');
6126
6254
  }
6127
6255
  }
6128
- return /*#__PURE__*/React__default["default"].createElement("div", null, children);
6256
+ return /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("button", {
6257
+ onClick: () => {
6258
+ saveEventsLocally('formatted');
6259
+ saveEventsLocally('raw');
6260
+ }
6261
+ }, "Save Events Locally"), children);
6262
+ };
6263
+ const flag_item_clicked = item_id => {
6264
+ const sessionId = localStorage.getItem('coreOutlineSessionId');
6265
+ const dataSourceId = localStorage.getItem('coreOutlineDataSourceIdId');
6266
+ console.log('Session', sessionId);
6267
+ console.log('Data Source', dataSourceId);
6268
+ socket.send({
6269
+ topic: 'session-data',
6270
+ data_source_id: dataSourceId,
6271
+ session_id: sessionId,
6272
+ start_date: new Date().toLocaleString(),
6273
+ event_id: 'PRODUCT_CLICKED',
6274
+ item_clicked: item_id
6275
+ });
6276
+ return {
6277
+ status: 'success',
6278
+ message: 'Item click flagged successfully.'
6279
+ };
6280
+ };
6281
+ const flag_item_purchased = item_id => {
6282
+ const sessionId = localStorage.getItem('coreOutlineSessionId');
6283
+ const dataSourceId = localStorage.getItem('coreOutlineDataSourceIdId');
6284
+ console.log('Session', sessionId);
6285
+ console.log('Data Source', dataSourceId);
6286
+ socket.send({
6287
+ topic: 'session-data',
6288
+ data_source_id: dataSourceId,
6289
+ session_id: sessionId,
6290
+ start_date: new Date().toLocaleString(),
6291
+ event_id: 'PRODUCT_PURCHASED',
6292
+ item_clicked: item_id
6293
+ });
6294
+ return {
6295
+ status: 'success',
6296
+ message: 'Item purchase flagged successfully.'
6297
+ };
6129
6298
  };
6130
6299
 
6131
- module.exports = CoreOutline;
6300
+ exports["default"] = CoreOutline;
6301
+ exports.flag_item_clicked = flag_item_clicked;
6302
+ exports.flag_item_purchased = flag_item_purchased;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-outline",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "A React component for Core&Outline",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es.js",