From 637d147ac019950e9f98c8ace35de6f96ddb2b3c Mon Sep 17 00:00:00 2001 From: Mauricio Lauffer <443888+mauriciolauffer@users.noreply.github.com> Date: Wed, 15 Mar 2023 17:43:59 +1100 Subject: [PATCH] feat: Set last syncronization time --- dist/ui5ErrorCollector.min.js | 3 +- dist/ui5ErrorCollector.min.js.map | 1 + package-lock.json | 170 ++++++++++++++++-------------- package.json | 6 +- src/ui5ErrorCollector.js | 17 ++- test/index.html | 13 +++ vite.config.ts | 1 + 7 files changed, 124 insertions(+), 87 deletions(-) create mode 100644 dist/ui5ErrorCollector.min.js.map diff --git a/dist/ui5ErrorCollector.min.js b/dist/ui5ErrorCollector.min.js index 0de0b61..0c3489b 100644 --- a/dist/ui5ErrorCollector.min.js +++ b/dist/ui5ErrorCollector.min.js @@ -1 +1,2 @@ -(function(){"use strict";(function(){if(window.ui5ErrorCollector)return;function s(){window.sap&&sap.ui&&sap.ui.require?(sap.ui.require(["sap/base/Log"],u),clearInterval(c)):Date.now()-L>6e4&&clearInterval(c)}function u(e){const n={onLogEntry:function(i){t.push(p(i))}};e.addLogListener(n)}function p(e){const n=new Error(e.message);return Object.assign({},r,{type:"ui5",timestamp:new Date(e.timestamp||Date.now()).toJSON(),uri:window.location.href,stack:n.stack,message:e.message,component:e.component,level:e.level})}function m(e){return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:window.location.href,stack:e.error.stack,message:e.message,elapsedTimestamp:e.timeStamp,filename:e.filename,level:1})}function f(e){return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:window.location.href,message:e.reason,elapsedTimestamp:e.timeStamp,level:1})}function d(e){const n=e.body||{};return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:e.url,message:n.message||n.reason,component:n.id,level:1,filename:n.sourceFile})}function g(){return t.filter(function(e){return new Date(e.timestamp)>new Date(o.lastSync)})}function a(){const e=g();if(!o.serverUrl||e.length===0)return;const n=JSON.stringify(e);o.onSyncHook?o.onSyncHook(o.serverUrl,t):(navigator.sendBeacon(o.serverUrl,n),o.lastSync=Date.now())}function y(e){const n=e||{};o.serverUrl=n.serverUrl,typeof n.onSyncHook=="function"&&(o.onSyncHook=n.onSyncHook)}function w(){return t}function E(){if(window.ReportingObserver){const e={types:["deprecation","intervention","crash"],buffered:!0};new ReportingObserver(function(l){l.forEach(function(i){t.push(d(i))})},e).observe()}}const t=[],o={lastSync:0,serverUrl:"",onSyncHook:null},r={type:"",timestamp:"",uri:"",stack:null,message:"",component:null,level:0,elapsedTimestamp:null,filename:null},L=Date.now(),c=setInterval(s,300);s(),E(),window.addEventListener("error",function(n){t.push(m(n))}),window.addEventListener("unhandledrejection",function(n){t.push(f(n))}),window.addEventListener("beforeunload",function(){a()}),document.addEventListener("visibilitychange",function(){document.visibilityState==="hidden"&&a()}),window.ui5ErrorCollector={getErrors:w,setConfiguration:y}})()})(); +(function(){"use strict";(function(){if(window.ui5ErrorCollector)return;function i(){window.sap&&sap.ui&&sap.ui.require?(sap.ui.require(["sap/base/Log"],u),clearInterval(c)):Date.now()-E>6e4&&clearInterval(c)}function u(e){const n={onLogEntry:function(s){o.push(p(s))}};e.addLogListener(n)}function p(e){const n=new Error(e.message);return Object.assign({},r,{type:"ui5",timestamp:new Date(e.timestamp||Date.now()).toJSON(),uri:window.location.href,stack:n.stack,message:e.message,component:e.component,level:e.level})}function m(e){return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:window.location.href,stack:e.error.stack,message:e.message,elapsedTimestamp:e.timeStamp,filename:e.filename,level:1})}function f(e){return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:window.location.href,message:e.reason,elapsedTimestamp:e.timeStamp,level:1})}function g(e){const n=e.body||{};return Object.assign({},r,{type:e.type,timestamp:new Date().toJSON(),uri:e.url,message:n.message||n.reason,component:n.id,level:1,filename:n.sourceFile})}function d(){return o.filter(function(e){return new Date(e.timestamp)>new Date(t.lastSync)})}function y(){const e=d();if(!t.serverUrl||e.length===0)return;const n=JSON.stringify(e);t.onSyncHook?t.onSyncHook(t.serverUrl,o):(navigator.sendBeacon(t.serverUrl,n),a(Date.now()),t.lastSync=Date.now())}function w(e){const n=e||{};t.serverUrl=n.serverUrl,typeof n.onSyncHook=="function"&&(t.onSyncHook=n.onSyncHook)}function a(e){t.lastSync=e}function L(){return o}function S(){if(window.ReportingObserver){const e={types:["deprecation","intervention","crash"],buffered:!0};new ReportingObserver(function(l){l.forEach(function(s){o.push(g(s))})},e).observe()}}const o=[],t={lastSync:0,serverUrl:"",onSyncHook:null},r={type:"",timestamp:"",uri:"",stack:null,message:"",component:null,level:0,elapsedTimestamp:null,filename:null},E=Date.now(),c=setInterval(i,300);i(),S(),window.addEventListener("error",function(n){o.push(m(n))}),window.addEventListener("unhandledrejection",function(n){o.push(f(n))}),document.addEventListener("visibilitychange",function(){document.visibilityState==="hidden"&&y()}),window.ui5ErrorCollector={getErrors:L,setConfiguration:w,setLastSync:a}})()})(); +//# sourceMappingURL=ui5ErrorCollector.min.js.map diff --git a/dist/ui5ErrorCollector.min.js.map b/dist/ui5ErrorCollector.min.js.map new file mode 100644 index 0000000..dd5ef39 --- /dev/null +++ b/dist/ui5ErrorCollector.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ui5ErrorCollector.min.js","sources":["../src/ui5ErrorCollector.js"],"sourcesContent":["'use strict';\n\n(function() {\n if (window.ui5ErrorCollector) return;\n\n /**\n * @typedef UI5ErrorLogEvent\n * @type {object}\n * @property {string} type - Log event type\n * @property {string} timestamp - When event was logged\n * @property {string} uri - Where event was logged\n * @property {?string} stack - Error stack\n * @property {string} message - Error message\n * @property {?string} component - UI5 Log component\n * @property {number} level - Log level\n * @property {?number} elapsedTimestamp - Elapsed time since page load\n * @property {?string} filename - File which triggered the error\n */\n\n /**\n * @typedef UI5ErrorUi5BaseLogEntry\n * @type {object}\n * @property {number} timestamp - When event was logged\n * @property {string} message - Error message\n * @property {?string} component - UI5 Log component\n * @property {number} level - Log level\n */\n\n /**\n * @typedef UI5ErrorConfiguration\n * @type {object}\n * @property {number} lastSync - Last time sync has occured\n * @property {string} serverUrl - Server URL\n * @property {?UI5ErroronSyncHookCallback} onSyncHook - On sync hook\n */\n\n /**\n * Callback provided to replace default sync with backend server\n *\n * @callback UI5ErroronSyncHookCallback\n * @param {string} serverUrl - Server URL\n * @param {UI5ErrorLogEvent[]} errors - List of captured errors\n */\n\n /**\n * Check whether UI5 library has been loaded\n */\n function checkUi5IsLoaded() {\n if (window.sap && sap.ui && sap.ui.require) {\n sap.ui.require(['sap/base/Log'], addUI5LogListener);\n clearInterval(CHECK_UI5_INTERVAL_ID);\n } else if (Date.now() - START_TIME > 60000) { // Await UI5 for 1 minute max\n clearInterval(CHECK_UI5_INTERVAL_ID);\n }\n }\n\n /**\n * Add custom UI5 log listener to capture all UI5 log events\n *\n * @param {module:sap/base/Log} Log UI5 Log module\n */\n function addUI5LogListener(Log) {\n const customLogListener = {\n /**\n * Handler for sap/base/Log onLogEntry\n *\n * @param {UI5ErrorUi5BaseLogEntry} evt - UI5 log event\n */\n onLogEntry: function logUi5LogEntry(evt) {\n logEvents.push(mapUi5LogEntry(evt));\n }\n };\n Log.addLogListener(customLogListener);\n }\n\n /**\n * Map UI5 log events\n *\n * @param {UI5ErrorUi5BaseLogEntry} evt - UI5 log event\n * @returns {UI5ErrorLogEvent} Mapped error, type = 'ui5'\n */\n function mapUi5LogEntry(evt) {\n const err = new Error(evt.message);\n return Object.assign({}, LOG_TEMPLATE, {\n type: 'ui5',\n timestamp: new Date(evt.timestamp || Date.now()).toJSON(),\n uri: window.location.href,\n stack: err.stack,\n message: evt.message,\n component: evt.component,\n level: evt.level\n });\n }\n\n /**\n * Map js error events\n *\n * @param {ErrorEvent} evt - Error event\n * @returns {UI5ErrorLogEvent} Mapped error, type = 'error'\n */\n function mapJsLogEntry(evt) {\n return Object.assign({}, LOG_TEMPLATE, {\n type: evt.type,\n timestamp: new Date().toJSON(),\n uri: window.location.href,\n stack: evt.error.stack,\n message: evt.message,\n elapsedTimestamp: evt.timeStamp,\n filename: evt.filename,\n level: 1\n });\n }\n\n /**\n * Map Promise unhandledrejection events\n *\n * @param {PromiseRejectionEvent} evt - Error event\n * @returns {UI5ErrorLogEvent} Mapped error, type = 'unhandledrejection'\n */\n function mapPromiseLogEntry(evt) {\n return Object.assign({}, LOG_TEMPLATE, {\n type: evt.type,\n timestamp: new Date().toJSON(),\n uri: window.location.href,\n message: evt.reason,\n elapsedTimestamp: evt.timeStamp,\n level: 1\n });\n }\n\n /**\n * Map Report API error events\n *\n * @param {Report} evt - Report API event\n * @returns {UI5ErrorLogEvent} Mapped error, type = [deprecation, intervention, crash]\n */\n function mapReportApiLogEntry(evt) {\n const body = evt.body || {};\n return Object.assign({}, LOG_TEMPLATE, {\n type: evt.type,\n timestamp: new Date().toJSON(),\n uri: evt.url,\n message: body.message || body.reason,\n component: body.id,\n level: 1,\n filename: body.sourceFile\n });\n }\n\n /**\n * Get all log entries to be synced\n *\n * @returns {UI5ErrorLogEvent[]} Log entries\n */\n function getLogsToSync() {\n return logEvents.filter(function(log) {\n return new Date(log.timestamp) > new Date(CONFIG.lastSync);\n });\n }\n\n /**\n * Send errors to the server\n *\n */\n function sendLogsToServer() {\n const logsToSync = getLogsToSync();\n if (!CONFIG.serverUrl || logsToSync.length === 0) {\n return;\n }\n const payload = JSON.stringify(logsToSync);\n if (CONFIG.onSyncHook) {\n CONFIG.onSyncHook(CONFIG.serverUrl, logEvents);\n } else {\n navigator.sendBeacon(CONFIG.serverUrl, payload);\n setLastSync(Date.now());\n CONFIG.lastSync = Date.now();\n }\n }\n\n /**\n * Set configuration\n *\n * @param {object} opt - Config options\n * @param {string} opt.serverUrl - Server URL\n * @param {?UI5ErroronSyncHookCallback} opt.onSyncHook - On sync hook callback\n */\n function setConfiguration(opt) {\n const params = opt || {};\n CONFIG.serverUrl = params.serverUrl;\n if (typeof params.onSyncHook === 'function') {\n CONFIG.onSyncHook = params.onSyncHook;\n }\n }\n\n /**\n * Set last syncronization itme\n *\n * @param {number} timestamp - Last syncronization date time\n */\n function setLastSync(timestamp) {\n CONFIG.lastSync = timestamp;\n }\n\n /**\n * Get all captured errors\n *\n * @returns {UI5ErrorLogEvent[]} Captured errors\n */\n function getErrors() {\n return logEvents;\n }\n\n /**\n * Set ReportingObserver to collect and access reports from Reporting API\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API}\n */\n function setReportingObserver() {\n if (window.ReportingObserver) {\n const options = {\n types: ['deprecation', 'intervention', 'crash'],\n buffered: true\n };\n const observer = new ReportingObserver(function(reports) {\n reports.forEach(function(report) {\n logEvents.push(mapReportApiLogEntry(report));\n });\n }, options);\n observer.observe();\n }\n }\n\n /**\n * @type {UI5ErrorLogEvent[]}\n */\n const logEvents = [];\n /**\n * @type {UI5ErrorConfiguration}\n */\n const CONFIG = {\n lastSync: 0,\n serverUrl: '',\n onSyncHook: null\n };\n /**\n * @type {UI5ErrorLogEvent}\n */\n const LOG_TEMPLATE = {\n type: '',\n timestamp: '',\n uri: '',\n stack: null,\n message: '',\n component: null,\n level: 0,\n elapsedTimestamp: null,\n filename: null\n };\n const START_TIME = Date.now();\n const CHECK_UI5_INTERVAL_ID = setInterval(checkUi5IsLoaded, 300);\n checkUi5IsLoaded();\n setReportingObserver();\n\n window.addEventListener('error', function logError(evt) {\n logEvents.push(mapJsLogEntry(evt));\n });\n window.addEventListener('unhandledrejection', function logUnhandledRejection(evt) {\n logEvents.push(mapPromiseLogEntry(evt));\n });\n /* window.addEventListener('beforeunload', function onBeforeUnload() {\n sendLogsToServer();\n }); */\n document.addEventListener('visibilitychange', function onVisibilityChange() {\n if (document.visibilityState === 'hidden') {\n sendLogsToServer();\n }\n });\n\n window.ui5ErrorCollector = {\n getErrors: getErrors,\n setConfiguration: setConfiguration,\n setLastSync: setLastSync\n };\n}());\n"],"names":["checkUi5IsLoaded","addUI5LogListener","CHECK_UI5_INTERVAL_ID","START_TIME","Log","customLogListener","evt","logEvents","mapUi5LogEntry","err","LOG_TEMPLATE","mapJsLogEntry","mapPromiseLogEntry","mapReportApiLogEntry","body","getLogsToSync","log","CONFIG","sendLogsToServer","logsToSync","payload","setLastSync","setConfiguration","opt","params","timestamp","getErrors","setReportingObserver","options","reports","report"],"mappings":"0BAEC,UAAW,CACV,GAAI,OAAO,kBAAmB,OA4C9B,SAASA,GAAmB,CACtB,OAAO,KAAO,IAAI,IAAM,IAAI,GAAG,SACjC,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAGC,CAAiB,EAClD,cAAcC,CAAqB,GAC1B,KAAK,MAAQC,EAAa,KACnC,cAAcD,CAAqB,CAEtC,CAOD,SAASD,EAAkBG,EAAK,CAC9B,MAAMC,EAAoB,CAMxB,WAAY,SAAwBC,EAAK,CACvCC,EAAU,KAAKC,EAAeF,CAAG,CAAC,CACnC,CACP,EACIF,EAAI,eAAeC,CAAiB,CACrC,CAQD,SAASG,EAAeF,EAAK,CAC3B,MAAMG,EAAM,IAAI,MAAMH,EAAI,OAAO,EACjC,OAAO,OAAO,OAAO,CAAE,EAAEI,EAAc,CACrC,KAAM,MACN,UAAW,IAAI,KAAKJ,EAAI,WAAa,KAAK,IAAG,CAAE,EAAE,OAAQ,EACzD,IAAK,OAAO,SAAS,KACrB,MAAOG,EAAI,MACX,QAASH,EAAI,QACb,UAAWA,EAAI,UACf,MAAOA,EAAI,KACjB,CAAK,CACF,CAQD,SAASK,EAAcL,EAAK,CAC1B,OAAO,OAAO,OAAO,CAAE,EAAEI,EAAc,CACrC,KAAMJ,EAAI,KACV,UAAW,IAAI,KAAM,EAAC,OAAQ,EAC9B,IAAK,OAAO,SAAS,KACrB,MAAOA,EAAI,MAAM,MACjB,QAASA,EAAI,QACb,iBAAkBA,EAAI,UACtB,SAAUA,EAAI,SACd,MAAO,CACb,CAAK,CACF,CAQD,SAASM,EAAmBN,EAAK,CAC/B,OAAO,OAAO,OAAO,CAAE,EAAEI,EAAc,CACrC,KAAMJ,EAAI,KACV,UAAW,IAAI,KAAM,EAAC,OAAQ,EAC9B,IAAK,OAAO,SAAS,KACrB,QAASA,EAAI,OACb,iBAAkBA,EAAI,UACtB,MAAO,CACb,CAAK,CACF,CAQD,SAASO,EAAqBP,EAAK,CACjC,MAAMQ,EAAOR,EAAI,MAAQ,GACzB,OAAO,OAAO,OAAO,CAAE,EAAEI,EAAc,CACrC,KAAMJ,EAAI,KACV,UAAW,IAAI,KAAM,EAAC,OAAQ,EAC9B,IAAKA,EAAI,IACT,QAASQ,EAAK,SAAWA,EAAK,OAC9B,UAAWA,EAAK,GAChB,MAAO,EACP,SAAUA,EAAK,UACrB,CAAK,CACF,CAOD,SAASC,GAAgB,CACvB,OAAOR,EAAU,OAAO,SAASS,EAAK,CACpC,OAAO,IAAI,KAAKA,EAAI,SAAS,EAAI,IAAI,KAAKC,EAAO,QAAQ,CAC/D,CAAK,CACF,CAMD,SAASC,GAAmB,CAC1B,MAAMC,EAAaJ,IACnB,GAAI,CAACE,EAAO,WAAaE,EAAW,SAAW,EAC7C,OAEF,MAAMC,EAAU,KAAK,UAAUD,CAAU,EACrCF,EAAO,WACTA,EAAO,WAAWA,EAAO,UAAWV,CAAS,GAE7C,UAAU,WAAWU,EAAO,UAAWG,CAAO,EAC9CC,EAAY,KAAK,IAAG,CAAE,EACtBJ,EAAO,SAAW,KAAK,MAE1B,CASD,SAASK,EAAiBC,EAAK,CAC7B,MAAMC,EAASD,GAAO,GACtBN,EAAO,UAAYO,EAAO,UACtB,OAAOA,EAAO,YAAe,aAC/BP,EAAO,WAAaO,EAAO,WAE9B,CAOD,SAASH,EAAYI,EAAW,CAC9BR,EAAO,SAAWQ,CACnB,CAOD,SAASC,GAAY,CACnB,OAAOnB,CACR,CAOD,SAASoB,GAAuB,CAC9B,GAAI,OAAO,kBAAmB,CAC5B,MAAMC,EAAU,CACd,MAAO,CAAC,cAAe,eAAgB,OAAO,EAC9C,SAAU,EAClB,EACuB,IAAI,kBAAkB,SAASC,EAAS,CACvDA,EAAQ,QAAQ,SAASC,EAAQ,CAC/BvB,EAAU,KAAKM,EAAqBiB,CAAM,CAAC,CACrD,CAAS,CACF,EAAEF,CAAO,EACD,QAAO,CACjB,CACF,CAKD,MAAMrB,EAAY,CAAA,EAIZU,EAAS,CACb,SAAU,EACV,UAAW,GACX,WAAY,IAChB,EAIQP,EAAe,CACnB,KAAM,GACN,UAAW,GACX,IAAK,GACL,MAAO,KACP,QAAS,GACT,UAAW,KACX,MAAO,EACP,iBAAkB,KAClB,SAAU,IACd,EACQP,EAAa,KAAK,MAClBD,EAAwB,YAAYF,EAAkB,GAAG,EAC/DA,IACA2B,IAEA,OAAO,iBAAiB,QAAS,SAAkBrB,EAAK,CACtDC,EAAU,KAAKI,EAAcL,CAAG,CAAC,CACrC,CAAG,EACD,OAAO,iBAAiB,qBAAsB,SAA+BA,EAAK,CAChFC,EAAU,KAAKK,EAAmBN,CAAG,CAAC,CAC1C,CAAG,EAID,SAAS,iBAAiB,mBAAoB,UAA8B,CACtE,SAAS,kBAAoB,UAC/BY,GAEN,CAAG,EAED,OAAO,kBAAoB,CACzB,UAAWQ,EACX,iBAAkBJ,EAClB,YAAaD,CACjB,CACA,GAAG"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6d7704d..ee7f27c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,10 @@ "license": "MIT", "devDependencies": { "@microsoft/eslint-formatter-sarif": "^3.0.0", - "@openui5/ts-types": "^1.111.0", + "@openui5/ts-types": "^1.111.1", "@playwright/test": "^1.31.2", - "@types/node": "^18.14.2", - "eslint": "^8.35.0", + "@types/node": "^18.15.3", + "eslint": "^8.36.0", "eslint-config-mlauffer-ui5": "^0.3.3", "gremlins.js": "^2.2.0", "vite": "^4.1.4", @@ -144,14 +144,39 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", + "integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -167,9 +192,10 @@ } }, "node_modules/@eslint/js": { - "version": "8.35.0", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -251,9 +277,10 @@ } }, "node_modules/@openui5/ts-types": { - "version": "1.111.0", - "dev": true, - "license": "Apache-2.0" + "version": "1.111.1", + "resolved": "https://registry.npmjs.org/@openui5/ts-types/-/ts-types-1.111.1.tgz", + "integrity": "sha512-YL7vGVogGMnDgrSzNSWxXKLbkVkyhyi6Vfe0LFgs0iJ3l9086SckFJQ79xSsyTln6rTVxQ0df3NmKUDTA66PNQ==", + "dev": true }, "node_modules/@playwright/test": { "version": "1.31.2", @@ -303,9 +330,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "18.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", - "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==", + "version": "18.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz", + "integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -412,8 +439,9 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -429,8 +457,9 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -481,8 +510,9 @@ }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-union": { "version": "3.0.1", @@ -548,8 +578,9 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -884,12 +915,15 @@ } }, "node_modules/eslint": { - "version": "8.35.0", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, - "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^2.0.0", - "@eslint/js": "8.35.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -900,9 +934,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", + "espree": "^9.5.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -924,7 +957,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -1032,43 +1064,20 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/espree": { - "version": "9.4.1", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -1121,8 +1130,9 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-glob": { "version": "3.2.12", @@ -1152,8 +1162,9 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -1288,8 +1299,9 @@ }, "node_modules/globals": { "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -1382,8 +1394,9 @@ }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1520,8 +1533,9 @@ }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -1553,8 +1567,9 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -1859,8 +1874,9 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -2035,8 +2051,9 @@ }, "node_modules/punycode": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2155,17 +2172,6 @@ "regexp-tree": "bin/regexp-tree" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/resolve": { "version": "1.22.1", "dev": true, @@ -2184,8 +2190,9 @@ }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -2480,8 +2487,9 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -2607,8 +2615,9 @@ }, "node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2624,8 +2633,9 @@ }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 1bb2bd5..2c16d89 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,10 @@ ], "devDependencies": { "@microsoft/eslint-formatter-sarif": "^3.0.0", - "@openui5/ts-types": "^1.111.0", + "@openui5/ts-types": "^1.111.1", "@playwright/test": "^1.31.2", - "@types/node": "^18.14.2", - "eslint": "^8.35.0", + "@types/node": "^18.15.3", + "eslint": "^8.36.0", "eslint-config-mlauffer-ui5": "^0.3.3", "gremlins.js": "^2.2.0", "vite": "^4.1.4", diff --git a/src/ui5ErrorCollector.js b/src/ui5ErrorCollector.js index 81857f2..3596683 100644 --- a/src/ui5ErrorCollector.js +++ b/src/ui5ErrorCollector.js @@ -172,6 +172,7 @@ CONFIG.onSyncHook(CONFIG.serverUrl, logEvents); } else { navigator.sendBeacon(CONFIG.serverUrl, payload); + setLastSync(Date.now()); CONFIG.lastSync = Date.now(); } } @@ -191,6 +192,15 @@ } } + /** + * Set last syncronization itme + * + * @param {number} timestamp - Last syncronization date time + */ + function setLastSync(timestamp) { + CONFIG.lastSync = timestamp; + } + /** * Get all captured errors * @@ -257,9 +267,9 @@ window.addEventListener('unhandledrejection', function logUnhandledRejection(evt) { logEvents.push(mapPromiseLogEntry(evt)); }); - window.addEventListener('beforeunload', function onBeforeUnload() { + /* window.addEventListener('beforeunload', function onBeforeUnload() { sendLogsToServer(); - }); + }); */ document.addEventListener('visibilitychange', function onVisibilityChange() { if (document.visibilityState === 'hidden') { sendLogsToServer(); @@ -268,6 +278,7 @@ window.ui5ErrorCollector = { getErrors: getErrors, - setConfiguration: setConfiguration + setConfiguration: setConfiguration, + setLastSync: setLastSync }; }()); diff --git a/test/index.html b/test/index.html index 14de2ee..7cc6a5b 100644 --- a/test/index.html +++ b/test/index.html @@ -42,6 +42,19 @@ document.getElementById('captureErrors').textContent = JSON.stringify(window.ui5ErrorCollector.getErrors(), null, 4); }, 200); + diff --git a/vite.config.ts b/vite.config.ts index 3f70777..32374ae 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,6 +3,7 @@ import { defineConfig } from 'vite'; export default defineConfig({ build: { + sourcemap: true, lib: { formats: ['iife'], entry: path.resolve(__dirname, 'src/ui5ErrorCollector.js'),