core-outline 1.1.4 → 1.1.6

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