@microsoft/applicationinsights-offlinechannel-js 0.3.5-nightly3.2411-13 → 0.3.5-nightly3.2412-01
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/es5/applicationinsights-offlinechannel-js.js +3 -3
- package/dist/es5/applicationinsights-offlinechannel-js.js.map +1 -1
- package/dist/es5/applicationinsights-offlinechannel-js.min.js +2 -2
- package/dist/es5/applicationinsights-offlinechannel-js.min.js.map +1 -1
- package/dist-es5/Helpers/Utils.js +7 -7
- package/dist-es5/Helpers/Utils.js.map +1 -1
- package/dist-es5/InMemoryBatch.js +1 -1
- package/dist-es5/InMemoryBatch.js.map +1 -1
- package/dist-es5/Interfaces/IInMemoryBatch.js +1 -1
- package/dist-es5/Interfaces/IOfflineBatch.js +1 -1
- package/dist-es5/Interfaces/IOfflineIndexDb.js +1 -1
- package/dist-es5/Interfaces/IOfflineProvider.js +1 -1
- package/dist-es5/Interfaces/ISender.js +1 -1
- package/dist-es5/OfflineBatchHandler.js +2 -3
- package/dist-es5/OfflineBatchHandler.js.map +1 -1
- package/dist-es5/OfflineChannel.js +2 -2
- package/dist-es5/OfflineChannel.js.map +1 -1
- package/dist-es5/PayloadHelper.js +1 -1
- package/dist-es5/Providers/IndexDbHelper.js +6 -5
- package/dist-es5/Providers/IndexDbHelper.js.map +1 -1
- package/dist-es5/Providers/IndexDbProvider.js +2 -3
- package/dist-es5/Providers/IndexDbProvider.js.map +1 -1
- package/dist-es5/Providers/WebStorageProvider.js +4 -4
- package/dist-es5/Providers/WebStorageProvider.js.map +1 -1
- package/dist-es5/Sender.js +1 -1
- package/dist-es5/__DynamicConstants.js +1 -1
- package/dist-es5/applicationinsights-offlinechannel-js.js +1 -1
- package/package.json +3 -3
- package/types/applicationinsights-offlinechannel-js.d.ts +17 -15
- package/types/applicationinsights-offlinechannel-js.namespaced.d.ts +37 -41
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.
|
|
2
|
+
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.2412-01
|
|
3
3
|
* Copyright (c) Microsoft and contributors. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -32,8 +32,9 @@ var ErrorMessageFailedToOpenCursor = "DBError: Failed to Open Cursor";
|
|
|
32
32
|
var _dbContext = [];
|
|
33
33
|
/**
|
|
34
34
|
* Constructs the IDbContext instance
|
|
35
|
-
* @param dbName The current database name
|
|
36
|
-
|
|
35
|
+
* @param dbName - The current database name
|
|
36
|
+
|
|
37
|
+
* @param diagLog - The diagnostics logger to use
|
|
37
38
|
*/
|
|
38
39
|
function _getDbContext(dbName, diagLog) {
|
|
39
40
|
var _a;
|
|
@@ -81,8 +82,8 @@ function _getDbContext(dbName, diagLog) {
|
|
|
81
82
|
* rejectEvent will be executed. This is used to ensure that we don't attempt to execute events out of order such as attempting to removed
|
|
82
83
|
* an event from the indexedDb before the insertion of the event has completed. Only one of the startEvent or unableToStateEvent callbacks
|
|
83
84
|
* functions will be called.
|
|
84
|
-
* @param startEvent The event to execute after all outstanding events are complete, may be called synchronously or asynchronously.
|
|
85
|
-
* @param actionName The name of the action being performed
|
|
85
|
+
* @param startEvent - The event to execute after all outstanding events are complete, may be called synchronously or asynchronously.
|
|
86
|
+
* @param actionName - The name of the action being performed
|
|
86
87
|
*/
|
|
87
88
|
function _scheduleEvent(dbName, actionName, startEvent, evtTimeOut) {
|
|
88
89
|
// Create or fetch the current scheduler for this dbName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexDbHelper.js.map","sources":["IndexDbHelper.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { getGlobalInst } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncPromise, createAsyncRejectedPromise, createAsyncResolvedPromise, createTaskScheduler, doAwait, doAwaitResponse } from \"@nevware21/ts-async\";\r\nimport { getGlobal, isFunction, isPromiseLike, isString } from \"@nevware21/ts-utils\";\r\nimport { _DYN_CONTINUE, _DYN_DB_HDL, _DYN_DB_NAME, _DYN_INDEX_OF, _DYN_IS_AVAILABLE, _DYN_KEY_RANGE, _DYN_LENGTH, _DYN_NAME, _DYN_ONERROR, _DYN_ONSUCCESS, _DYN_OPEN_CURSOR, _DYN_OPEN_STORE, _DYN_PUSH, _DYN_REJECTED, _DYN_REMOVE, _DYN_SPLICE, _DYN_SPLIT, _DYN_SUBSTRING, _DYN_THEN, _DYN_TRANSACTION, _DYN_VALUE } from \"../__DynamicConstants\";\r\n//TODO: move all const to one file\r\n//TODO: handle db names\r\nvar IndexedDBNames = [\"indexedDB\" /*, 'mozIndexedDB', 'webkitIndexedDB', 'msIndexedDb'*/];\r\nvar DbReadWrite = \"readwrite\";\r\nvar Result = \"result\";\r\nvar ErrorMessageUnableToOpenDb = \"DBError: Unable to open database\";\r\nvar ErrorMessageDbUpgradeRequired = \"DBError: Database upgrade required\";\r\nvar ErrorMessageDbNotOpen = \"Database is not open\";\r\nvar ErrorMessageDbDoesNotExist = \"DBError: Database does not exist\";\r\nvar ErrorMessageFailedToDeleteDatabase = \"DBError: Failed to delete the database\";\r\nvar ErrorMessageDbNotSupported = \"DBError: Feature not supported\";\r\nvar ErrorMessageFailedToOpenCursor = \"DBError: Failed to Open Cursor\";\r\n//window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;\r\n//window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;\r\n// By placing this variable here it becomes a global hidden static\r\n/**\r\n * This is used to enforce sequential access to the IndexedDb, so that all operations don't interfere\r\n * with each other, this is REALLY useful to ensure that any previous operation has completed before\r\n * subsequent operations are completed -- especially for testing using different IndexedDbHelper instances.\r\n */\r\nvar _dbContext = [];\r\n/**\r\n * Constructs the IDbContext instance\r\n * @param dbName The current database name\r\n * @param diagLog The diagnostics logger to use\r\n */\r\nfunction _getDbContext(dbName, diagLog) {\r\n var _a;\r\n var dbCtx = null;\r\n for (var lp = 0; lp < _dbContext[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n dbCtx = _dbContext[lp];\r\n if (dbCtx[_DYN_NAME /* @min:%2ename */] === dbName) {\r\n return dbCtx;\r\n }\r\n }\r\n // Create the global handle for the database\r\n dbCtx = (_a = {},\r\n _a[_DYN_NAME /* @min:name */] = dbName,\r\n _a.sch = createTaskScheduler(createAsyncPromise, \"IndexedDbHelper[\" + dbName + \"]\"),\r\n _a.dbHdl = [],\r\n _a.add = function (db) {\r\n dbCtx.dbHdl[_DYN_PUSH /* @min:%2epush */](db);\r\n _debugLog(dbName, \"- dbOpened (add) -- hdls [\" + dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] + \"]\");\r\n },\r\n _a[_DYN_REMOVE /* @min:remove */] = function (db) {\r\n var hdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n for (var lp = 0; lp < hdls[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n if (hdls[lp] === db) {\r\n hdls[_DYN_SPLICE /* @min:%2esplice */](lp, 1);\r\n break;\r\n }\r\n }\r\n _debugLog(dbName, \"- dbClosed (remove) -- hdls [\" + dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] + \"]\");\r\n },\r\n _a.isOpen = function () {\r\n return dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0;\r\n },\r\n _a.openHdl = function () {\r\n if (dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0) {\r\n return dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */][0];\r\n }\r\n return null;\r\n },\r\n _a);\r\n _dbContext[_DYN_PUSH /* @min:%2epush */](dbCtx);\r\n return dbCtx;\r\n}\r\n/**\r\n * Schedule an event that will execute the startEvent after all outstanding events are resolved or if any event rejects the optional\r\n * rejectEvent will be executed. This is used to ensure that we don't attempt to execute events out of order such as attempting to removed\r\n * an event from the indexedDb before the insertion of the event has completed. Only one of the startEvent or unableToStateEvent callbacks\r\n * functions will be called.\r\n * @param startEvent The event to execute after all outstanding events are complete, may be called synchronously or asynchronously.\r\n * @param actionName The name of the action being performed\r\n */\r\nfunction _scheduleEvent(dbName, actionName, startEvent, evtTimeOut) {\r\n // Create or fetch the current scheduler for this dbName\r\n var dbCtx = _getDbContext(dbName);\r\n return dbCtx.sch.queue(startEvent, actionName, evtTimeOut);\r\n}\r\n// TODO: move to common to be able to used by lds\r\nexport function getDbFactory() {\r\n var global = getGlobal() || {};\r\n var dbFactory = null;\r\n if (global) {\r\n try {\r\n for (var lp = 0; lp < IndexedDBNames[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n dbFactory = global[IndexedDBNames[lp]];\r\n if (dbFactory && isFunction(dbFactory.open)) {\r\n return dbFactory;\r\n }\r\n }\r\n }\r\n catch (e) {\r\n dbFactory = null;\r\n }\r\n }\r\n return dbFactory;\r\n}\r\nfunction _debugLog(dbName, message) {\r\n // Only log if running within test harness\r\n if (getGlobalInst(\"QUnit\")) {\r\n // tslint:disable-next-line:no-console\r\n console && console.log(\"IndexedDbHelper [\" + dbName + \"] \" + message);\r\n }\r\n}\r\n/**\r\n * Helper method to map an Event rejection to a reject with a message, this is mainly for terminal errors where the\r\n * IndexedDb API returns an event which we are going to ignore\r\n * @param rejectMessage\r\n * @param rejectFunc\r\n */\r\nfunction _eventReject(dbName, rejectMessage, rejectFunc, evtName) {\r\n return function (evt) {\r\n rejectFunc(new Error(rejectMessage));\r\n _debugLog(dbName, \"[\" + evtName + \"] event rejected\");\r\n };\r\n}\r\n// This helper is designed to allow multiple database implementation\r\n// The IndexedDB provider will be using only one database with different stores.\r\n// for each transaction, will open a new connection\r\nvar IndexedDbHelper = /** @class */ (function () {\r\n function IndexedDbHelper(diagLog) {\r\n var _dbFactory = getDbFactory() || null;\r\n dynamicProto(IndexedDbHelper, this, function (_this) {\r\n _this[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */] = function () {\r\n return !!_dbFactory;\r\n };\r\n /**\r\n * Schedules the opening of the database if not already open\r\n */\r\n _this.openDb = function (dbName, dbVersion, processFunc, versionChangeFunc) {\r\n // Schedule the database to be opened\r\n return _scheduleEvent(dbName, \"openDb\", function (evtName) {\r\n return createAsyncPromise(function (openResolve, openReject) {\r\n var createdNewDb = false;\r\n function _createDbCtx(dbContext, db, dbOpenRequest, isNew, isUpgrade) {\r\n var _a;\r\n var crDbCtx = (_a = {\r\n db: db\r\n },\r\n _a[_DYN_DB_NAME /* @min:dbName */] = dbName,\r\n _a.dbVersion = dbVersion,\r\n _a.ctx = null,\r\n _a.isNew = isNew,\r\n _a.txn = dbOpenRequest ? dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] : null // Special case see the versionChangeFunc usage below\r\n ,\r\n _a);\r\n if (!isUpgrade) {\r\n crDbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */] = function (eventTable, doAction) {\r\n return _openStore(crDbCtx, eventTable, doAction);\r\n };\r\n crDbCtx[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */] = function (eventTable, query, cursorFunc) {\r\n return _openCursor(crDbCtx, eventTable, query, cursorFunc);\r\n };\r\n }\r\n return crDbCtx;\r\n }\r\n // TODO: add function to handle version change\r\n function _databaseUpgrade(db, dbOpenRequest, ev) {\r\n _debugLog(dbName, \"db upgrade called\");\r\n var upgDbCtx = _createDbCtx(null, db, dbOpenRequest, true, true);\r\n if (!versionChangeFunc) {\r\n try {\r\n dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] && dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */].abort();\r\n dbOpenRequest.result && dbOpenRequest.result.close(); // close database to unblock others\r\n }\r\n finally {\r\n openReject(new Error(ErrorMessageDbUpgradeRequired));\r\n }\r\n return;\r\n }\r\n createdNewDb = true;\r\n doAwaitResponse(versionChangeFunc(upgDbCtx), function (response) {\r\n if (!response[_DYN_REJECTED /* @min:%2erejected */]) {\r\n // Special case handling, when a DB is first created calling createObjectStore() will\r\n // automatically start a version change transaction which will block all other transactions\r\n // from getting created, so we save the auto opened on here for reuse as part of opening the store\r\n _debugLog(upgDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"on version change success\");\r\n if (!upgDbCtx.txn) {\r\n upgDbCtx.txn = dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */];\r\n _debugLog(upgDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"added open request\");\r\n }\r\n }\r\n else {\r\n // Abort the upgrade event\r\n try {\r\n dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] && dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */].abort();\r\n }\r\n finally {\r\n openReject(response.reason);\r\n }\r\n }\r\n });\r\n }\r\n function _databaseOpen(db, dbOpenRequest) {\r\n // Save the IDBDatabase handle to the global reference (so we can make sure we can close/delete the Db)\r\n // Also used to track the number of times the DB has been opened\r\n var opDbCtx = _getDbContext(dbName);\r\n opDbCtx.add(db);\r\n db.onabort = function (evt) {\r\n _debugLog(dbName, \"onabort -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n _debugLog(dbName, \"onerror -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db.onclose = function (evt) {\r\n _debugLog(dbName, \"onclose -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db.onversionchange = function (evt) {\r\n _debugLog(dbName, \"onversionchange -- force closing the Db\");\r\n db.close();\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n var openDbCtx = null;\r\n var dbHdl = null;\r\n if (opDbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0) {\r\n dbHdl = opDbCtx[_DYN_DB_HDL /* @min:%2edbHdl */][0];\r\n }\r\n openDbCtx = _createDbCtx(opDbCtx, dbHdl, dbOpenRequest, createdNewDb);\r\n try {\r\n // Database has been opened\r\n doAwait(processFunc(openDbCtx), openResolve, openReject);\r\n }\r\n catch (e) {\r\n openReject(e);\r\n }\r\n }\r\n var dbCtx = _getDbContext(dbName);\r\n if (_dbFactory == null) {\r\n openReject(new Error(\"No available storage factory\"));\r\n }\r\n else if (dbCtx.isOpen()) {\r\n // Database is already open\r\n var openDbCtx = _createDbCtx(dbCtx, dbCtx.openHdl(), null, false);\r\n doAwait(processFunc(openDbCtx), openResolve, openReject);\r\n }\r\n else {\r\n var dbOpenRequest_1 = _dbFactory.open(dbName, dbVersion);\r\n if (!dbOpenRequest_1) {\r\n throw new Error(\"missing API\"); // in case, some corners case (such as private mode for certain browsers) does not support open db\r\n }\r\n // We can't open the database, possible issues are\r\n // - We are attempting to open the db as a different version but it's already open\r\n dbOpenRequest_1.onblocked = function (evt) {\r\n _debugLog(dbName, \"Db Open Blocked event [\" + evtName + \"] - \" + (dbOpenRequest_1.error || \"\"));\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n };\r\n dbOpenRequest_1[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n _debugLog(dbName, \"Db Open Error event [\" + evtName + \"] - \" + (dbOpenRequest_1.error || \"\"));\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n };\r\n dbOpenRequest_1.onupgradeneeded = function (evt) {\r\n _debugLog(dbName, \"Db Open Create/Upgrade needed event [\" + evtName + \"]\");\r\n try {\r\n var db = evt.target[Result] || dbOpenRequest_1.result;\r\n if (!db) {\r\n _debugLog(dbName, \"no db\");\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n return;\r\n }\r\n _databaseUpgrade(db, dbOpenRequest_1, evt);\r\n }\r\n catch (e) {\r\n _eventReject(dbName, ErrorMessageUnableToOpenDb, openReject, evtName)(e);\r\n }\r\n };\r\n dbOpenRequest_1[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n _debugLog(dbName, \"Db Open sucess [\" + evtName + \"]\");\r\n var db = evt.target[Result];\r\n if (!db) {\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n return;\r\n }\r\n _databaseOpen(db, dbOpenRequest_1);\r\n };\r\n }\r\n });\r\n });\r\n };\r\n _this.closeDb = function (dbName) {\r\n // Schedule the close so we don't interrupt an previous scheduled operations\r\n _debugLog(dbName, \"close db\");\r\n _scheduleEvent(dbName, \"closeDb\", function (evtName) {\r\n var dbCtx = _getDbContext(dbName);\r\n var dbHdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n var len = dbHdls[_DYN_LENGTH /* @min:%2elength */];\r\n if (len > 0) {\r\n for (var lp = 0; lp < len; lp++) {\r\n // Just call close the db.onclose() event should take care of decrementing and removing the references\r\n dbHdls[lp].close();\r\n }\r\n dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */] = [];\r\n }\r\n return 1;\r\n }).catch(function (reason) {\r\n // Handle promise rejection to avoid an unhandled rejection event\r\n });\r\n };\r\n _this.deleteDb = function (dbName) {\r\n if (_dbFactory == null) {\r\n return false;\r\n }\r\n return _scheduleEvent(dbName, \"deleteDb\", function (evtName) {\r\n // Implicitly close any open db first as this WILL block the deleting\r\n var dbCtx = _getDbContext(dbName);\r\n var dbHdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n var len = dbHdls[_DYN_LENGTH /* @min:%2elength */];\r\n if (len > 0) {\r\n _debugLog(dbName, \"Db is open [\" + len + \"] force closing\");\r\n for (var lp = 0; lp < len; lp++) {\r\n // Just call close the db.onclose() event should take care of decrementing and removing the references\r\n dbHdls[lp].close();\r\n }\r\n // Clear all of the existing handles as we have forced closed them and for compatibility we can't\r\n // rely on the db onclose event\r\n dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */] = [];\r\n }\r\n return createAsyncPromise(function (deleteResolve, deleteReject) {\r\n // Attempting to delete the Db, only after we wait so that any outstanding operations can finish\r\n setTimeout(function () {\r\n try {\r\n _debugLog(dbName, \"[\" + evtName + \"] starting\");\r\n var dbRequest = _dbFactory.deleteDatabase(dbName);\r\n dbRequest[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest.onblocked = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest.onupgradeneeded = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n _debugLog(dbName, \"[\" + evtName + \"] complete\");\r\n deleteResolve(true);\r\n };\r\n _debugLog(dbName, \"[\" + evtName + \"] started\");\r\n }\r\n catch (e) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase + \" - \" + e));\r\n }\r\n }, 0);\r\n });\r\n });\r\n };\r\n _this.getDbDetails = function (dbName) {\r\n return _scheduleEvent(dbName, \"getDbDetails\", function (evtName) {\r\n if (_dbFactory == null || !_dbFactory.databases) {\r\n // Either IndexedDb is not supported or databases is not supported\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotSupported));\r\n }\r\n return createAsyncPromise(function (databasesResolve, databasesReject) {\r\n // databases() is still experimental, so it's not fully available\r\n // The promise will reject if there is a JS error\r\n var dbPromise = _dbFactory.databases();\r\n dbPromise[_DYN_THEN /* @min:%2ethen */](function (databases) {\r\n for (var lp = 0; lp < databases[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n if (databases[lp][_DYN_NAME /* @min:%2ename */] === dbName) {\r\n databasesResolve(databases[lp]);\r\n return;\r\n }\r\n }\r\n databasesReject(new Error(ErrorMessageDbDoesNotExist));\r\n }, databasesReject);\r\n });\r\n }, 2000);\r\n };\r\n function _createStoreContext(openDbCtx, eventTable) {\r\n // Save the current handle so we close the correct one during the transaction events\r\n var dbHdl = openDbCtx.db || null;\r\n // Check if the openDb event created a transaction that we should reuse\r\n var tx = dbHdl && dbHdl[_DYN_TRANSACTION /* @min:%2etransaction */](eventTable, DbReadWrite);\r\n if (tx) {\r\n // The transaction was aborted and therefore the adding of the event failed\r\n tx.onabort = function () {\r\n // add log\r\n };\r\n tx[_DYN_ONERROR /* @min:%2eonerror */] = function () {\r\n // add log\r\n };\r\n // Note we don't listen for the transaction onComplete event as we don't have any value\r\n // to resolve the promise with, we are relying on the doAction() to resolve and the exception\r\n // handling below to ensure we don't deadlock.\r\n tx.oncomplete = function () {\r\n // We need to capture the transaction close event as not all browsers are triggering the db onclose event\r\n _debugLog(openDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"txn.oncomplete\");\r\n };\r\n // Ok, so now we have the transaction handling setup lets try and store the event\r\n return {\r\n db: openDbCtx,\r\n store: tx.objectStore(eventTable),\r\n tx: tx,\r\n tbl: eventTable,\r\n openCursor: function (query, processFunc) {\r\n return _openCursor(openDbCtx, eventTable, query, processFunc);\r\n },\r\n newTransaction: function (doAction) {\r\n return _openStore(openDbCtx, eventTable, doAction);\r\n }\r\n };\r\n }\r\n return null;\r\n }\r\n /**\r\n * Opens the specific store for the database\r\n * @param openDbCtx\r\n * @param eventTable\r\n * @param doAction\r\n */\r\n function _openStore(openDbCtx, eventTable, doAction) {\r\n // While the open DB promise may have been resolved we still might not have opened the DB (This is to ensure that\r\n // non-critical failures don't cause event execution out of order)\r\n if (!openDbCtx || !openDbCtx.db) {\r\n // Database is not open so pass the only option is to resolve the event so it's passed onto the next on the event to the next chain\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotOpen));\r\n }\r\n try {\r\n // Perform the transaction action\r\n var result = doAction(_createStoreContext(openDbCtx, eventTable));\r\n if (isPromiseLike(result)) {\r\n return result;\r\n }\r\n return createAsyncResolvedPromise(result);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n }\r\n function _openCursor(openDbCtx, eventTable, query, processFunc) {\r\n // While the open DB promise may have been resolved we still might not have opened the DB (This is to ensure that\r\n // non-critical failures don't cause event execution out of order)\r\n if (!openDbCtx || !openDbCtx.db) {\r\n // Database is not open so pass the only option is to resolve the event so it's passed onto the next on the event to the next chain\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotOpen));\r\n }\r\n var simpleQuery = null;\r\n if (query && isString(query)) {\r\n simpleQuery = new SimpleQuery(query);\r\n }\r\n else if (query && query.isMatch) { // simple check to make sure this is a IIndexedDbSimpleQuery\r\n simpleQuery = query;\r\n }\r\n return createAsyncPromise(function (openCursorResolve, openCursorReject) {\r\n var values = [];\r\n var cursorRequest = null;\r\n var queryKeyRange = null;\r\n if (simpleQuery && simpleQuery[_DYN_KEY_RANGE /* @min:%2ekeyRange */]) {\r\n queryKeyRange = simpleQuery[_DYN_KEY_RANGE /* @min:%2ekeyRange */]();\r\n }\r\n var storeCtx = _createStoreContext(openDbCtx, eventTable);\r\n if (queryKeyRange) {\r\n cursorRequest = storeCtx.store[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */](queryKeyRange);\r\n }\r\n else {\r\n cursorRequest = storeCtx.store[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */]();\r\n }\r\n cursorRequest.onerror = _eventReject(storeCtx.db[_DYN_DB_NAME /* @min:%2edbName */], ErrorMessageFailedToOpenCursor, openCursorReject, \"openCursor\");\r\n cursorRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n var _a;\r\n // Cursor was open/next iteration\r\n var cursor = evt.target[Result];\r\n if (!cursor) {\r\n // This occurs when we get to the end of the cursor iteration\r\n openCursorResolve(values);\r\n return;\r\n }\r\n var processCursorState = (_a = {\r\n store: storeCtx,\r\n cursor: cursor\r\n },\r\n _a[_DYN_CONTINUE /* @min:continue */] = function () {\r\n cursor[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n },\r\n _a.done = function () {\r\n openCursorResolve(values);\r\n } // Stops the cursor processing\r\n ,\r\n _a);\r\n var value = cursor[_DYN_VALUE /* @min:%2evalue */];\r\n if (simpleQuery && !simpleQuery.isMatch(value)) {\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n return;\r\n }\r\n if (processFunc) {\r\n try {\r\n switch (processFunc(processCursorState, value, values)) {\r\n case 2 /* CursorProcessResult.Complete */:\r\n openCursorResolve(values);\r\n break;\r\n case 1 /* CursorProcessResult.Waiting */:\r\n // The process method now controls whether th\r\n break;\r\n case 0 /* CursorProcessResult.Continue */:\r\n default:\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n break;\r\n }\r\n }\r\n catch (ex) {\r\n // Make sure the reject the promise if the processFunc callback throws unexpectable\r\n openCursorReject(ex);\r\n }\r\n }\r\n else {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n }\r\n };\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * Identifies whether an IndexedDb api is available\r\n */\r\n IndexedDbHelper.prototype.isAvailable = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n IndexedDbHelper.prototype.openDb = function (dbName, dbVersion, processFunc, versionChangeFunc) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Request that any open database handles for the named database be closed.\r\n * This method will return immediately, however, the scheduled event to close the open Db handles will not occur until all outstanding database operations\r\n * (openDb, deleteDb, getDbDetails) started by IndexedDbHelper for the named db have completed. This will NOT affect or wait for any open database handles\r\n * which have been directly opened by the IndexedDB Api.\r\n * @param dbName The name of the database to close, no error will be returned if the database does not exist or was not opened.\r\n */\r\n IndexedDbHelper.prototype.closeDb = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n /**\r\n * Request that the named database should be deleted, this implicitly closes any previously opened database that was opened via IndexedDBHelper.\r\n * It will also wait for all Promise objects from previous openDb, closeDb, getDbDetails to complete (resolve or reject) before attempting to\r\n * perform the delete operation. This operation may block or fail if the database is opened outstide of the IndexedDbHelper\r\n * The returned promise will be resolved or rejected depending on the outcome of the delete operation.\r\n * @param dbName The name of the database to delete\r\n */\r\n IndexedDbHelper.prototype.deleteDb = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Attempt to return the details (version) of the named database if possible.\r\n * This method requires that the underlying browser support draft specification for IDBFactory.databases, if this is not supported then the returned\r\n * Promise will be rejected with an error message stating that the feature is not supported.\r\n * The returned Promise will be resolved with the details if available or rejected on error.\r\n * @param dbName The name of the database to request the details for\r\n */\r\n IndexedDbHelper.prototype.getDbDetails = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n return IndexedDbHelper;\r\n}());\r\nexport { IndexedDbHelper };\r\n/**\r\n * A simple query interface to provide a simple cursor query (IDBKeyRange) key range and matching.\r\n * Used by the openCursor() method.\r\n */\r\nvar SimpleQuery = /** @class */ (function () {\r\n function SimpleQuery(theQuery) {\r\n var _queryCols = [];\r\n var _keyRange = null;\r\n dynamicProto(SimpleQuery, this, function (_this) {\r\n _this[_DYN_KEY_RANGE /* @min:%2ekeyRange */] = function () {\r\n return _keyRange;\r\n };\r\n _this.parseQuery = function (query) {\r\n _queryCols = [];\r\n if (query) {\r\n var items = query[_DYN_SPLIT /* @min:%2esplit */](\";\");\r\n for (var lp = 0; lp < items[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var item = items[lp];\r\n var idx = item[_DYN_INDEX_OF /* @min:%2eindexOf */](\"=\");\r\n if (idx !== -1) {\r\n var key = item[_DYN_SUBSTRING /* @min:%2esubstring */](0, idx);\r\n var value = item[_DYN_SUBSTRING /* @min:%2esubstring */](idx + 1);\r\n if (key[_DYN_INDEX_OF /* @min:%2eindexOf */](\"#\") === 0) {\r\n key = key[_DYN_SUBSTRING /* @min:%2esubstring */](1);\r\n if (!_keyRange) {\r\n _keyRange = IDBKeyRange.bound(value, value + \"\\uffff\");\r\n }\r\n }\r\n _this.startsWith(key, value);\r\n }\r\n }\r\n }\r\n };\r\n _this.startsWith = function (columnName, value) {\r\n var _a;\r\n _queryCols[_DYN_PUSH /* @min:%2epush */]((_a = {},\r\n _a[_DYN_NAME /* @min:name */] = columnName,\r\n _a[_DYN_VALUE /* @min:value */] = value,\r\n _a.type = 0 /* ValueQueryType.StartsWith */,\r\n _a));\r\n };\r\n _this.contains = function (columnName, value) {\r\n var _a;\r\n _queryCols[_DYN_PUSH /* @min:%2epush */]((_a = {},\r\n _a[_DYN_NAME /* @min:name */] = columnName,\r\n _a[_DYN_VALUE /* @min:value */] = value,\r\n _a.type = 1 /* ValueQueryType.Contains */,\r\n _a));\r\n };\r\n _this.isMatch = function (value) {\r\n // No query restriction so everything matches\r\n if (!_queryCols || _queryCols[_DYN_LENGTH /* @min:%2elength */] === 0) {\r\n return true;\r\n }\r\n if (!value) {\r\n return false;\r\n }\r\n for (var lp = 0; lp < _queryCols[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var query = _queryCols[lp];\r\n var chkValue = value[query.name];\r\n if (chkValue) {\r\n if (query.type === 0 /* ValueQueryType.StartsWith */) {\r\n if (chkValue.indexOf(query[_DYN_VALUE /* @min:%2evalue */]) !== 0) {\r\n return false;\r\n }\r\n }\r\n else if (query.type === 1 /* ValueQueryType.Contains */) {\r\n if (chkValue.indexOf(query[_DYN_VALUE /* @min:%2evalue */]) === -1) {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n if (theQuery) {\r\n _this.parseQuery(theQuery);\r\n }\r\n });\r\n }\r\n return SimpleQuery;\r\n}());\r\n//# sourceMappingURL=IndexDbHelper.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;2DA0CM,CAAC;;;;;2BACoB;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;;;;uBACiB;AACvB;AACA"}
|
|
1
|
+
{"version":3,"file":"IndexDbHelper.js.map","sources":["IndexDbHelper.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { getGlobalInst } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncPromise, createAsyncRejectedPromise, createAsyncResolvedPromise, createTaskScheduler, doAwait, doAwaitResponse } from \"@nevware21/ts-async\";\r\nimport { getGlobal, isFunction, isPromiseLike, isString } from \"@nevware21/ts-utils\";\r\nimport { _DYN_CONTINUE, _DYN_DB_HDL, _DYN_DB_NAME, _DYN_INDEX_OF, _DYN_IS_AVAILABLE, _DYN_KEY_RANGE, _DYN_LENGTH, _DYN_NAME, _DYN_ONERROR, _DYN_ONSUCCESS, _DYN_OPEN_CURSOR, _DYN_OPEN_STORE, _DYN_PUSH, _DYN_REJECTED, _DYN_REMOVE, _DYN_SPLICE, _DYN_SPLIT, _DYN_SUBSTRING, _DYN_THEN, _DYN_TRANSACTION, _DYN_VALUE } from \"../__DynamicConstants\";\r\n//TODO: move all const to one file\r\n//TODO: handle db names\r\nvar IndexedDBNames = [\"indexedDB\" /*, 'mozIndexedDB', 'webkitIndexedDB', 'msIndexedDb'*/];\r\nvar DbReadWrite = \"readwrite\";\r\nvar Result = \"result\";\r\nvar ErrorMessageUnableToOpenDb = \"DBError: Unable to open database\";\r\nvar ErrorMessageDbUpgradeRequired = \"DBError: Database upgrade required\";\r\nvar ErrorMessageDbNotOpen = \"Database is not open\";\r\nvar ErrorMessageDbDoesNotExist = \"DBError: Database does not exist\";\r\nvar ErrorMessageFailedToDeleteDatabase = \"DBError: Failed to delete the database\";\r\nvar ErrorMessageDbNotSupported = \"DBError: Feature not supported\";\r\nvar ErrorMessageFailedToOpenCursor = \"DBError: Failed to Open Cursor\";\r\n//window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;\r\n//window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;\r\n// By placing this variable here it becomes a global hidden static\r\n/**\r\n * This is used to enforce sequential access to the IndexedDb, so that all operations don't interfere\r\n * with each other, this is REALLY useful to ensure that any previous operation has completed before\r\n * subsequent operations are completed -- especially for testing using different IndexedDbHelper instances.\r\n */\r\nvar _dbContext = [];\r\n/**\r\n * Constructs the IDbContext instance\r\n * @param dbName - The current database name\r\n\r\n * @param diagLog - The diagnostics logger to use\r\n */\r\nfunction _getDbContext(dbName, diagLog) {\r\n var _a;\r\n var dbCtx = null;\r\n for (var lp = 0; lp < _dbContext[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n dbCtx = _dbContext[lp];\r\n if (dbCtx[_DYN_NAME /* @min:%2ename */] === dbName) {\r\n return dbCtx;\r\n }\r\n }\r\n // Create the global handle for the database\r\n dbCtx = (_a = {},\r\n _a[_DYN_NAME /* @min:name */] = dbName,\r\n _a.sch = createTaskScheduler(createAsyncPromise, \"IndexedDbHelper[\" + dbName + \"]\"),\r\n _a.dbHdl = [],\r\n _a.add = function (db) {\r\n dbCtx.dbHdl[_DYN_PUSH /* @min:%2epush */](db);\r\n _debugLog(dbName, \"- dbOpened (add) -- hdls [\" + dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] + \"]\");\r\n },\r\n _a[_DYN_REMOVE /* @min:remove */] = function (db) {\r\n var hdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n for (var lp = 0; lp < hdls[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n if (hdls[lp] === db) {\r\n hdls[_DYN_SPLICE /* @min:%2esplice */](lp, 1);\r\n break;\r\n }\r\n }\r\n _debugLog(dbName, \"- dbClosed (remove) -- hdls [\" + dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] + \"]\");\r\n },\r\n _a.isOpen = function () {\r\n return dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0;\r\n },\r\n _a.openHdl = function () {\r\n if (dbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0) {\r\n return dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */][0];\r\n }\r\n return null;\r\n },\r\n _a);\r\n _dbContext[_DYN_PUSH /* @min:%2epush */](dbCtx);\r\n return dbCtx;\r\n}\r\n/**\r\n * Schedule an event that will execute the startEvent after all outstanding events are resolved or if any event rejects the optional\r\n * rejectEvent will be executed. This is used to ensure that we don't attempt to execute events out of order such as attempting to removed\r\n * an event from the indexedDb before the insertion of the event has completed. Only one of the startEvent or unableToStateEvent callbacks\r\n * functions will be called.\r\n * @param startEvent - The event to execute after all outstanding events are complete, may be called synchronously or asynchronously.\r\n * @param actionName - The name of the action being performed\r\n */\r\nfunction _scheduleEvent(dbName, actionName, startEvent, evtTimeOut) {\r\n // Create or fetch the current scheduler for this dbName\r\n var dbCtx = _getDbContext(dbName);\r\n return dbCtx.sch.queue(startEvent, actionName, evtTimeOut);\r\n}\r\n// TODO: move to common to be able to used by lds\r\nexport function getDbFactory() {\r\n var global = getGlobal() || {};\r\n var dbFactory = null;\r\n if (global) {\r\n try {\r\n for (var lp = 0; lp < IndexedDBNames[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n dbFactory = global[IndexedDBNames[lp]];\r\n if (dbFactory && isFunction(dbFactory.open)) {\r\n return dbFactory;\r\n }\r\n }\r\n }\r\n catch (e) {\r\n dbFactory = null;\r\n }\r\n }\r\n return dbFactory;\r\n}\r\nfunction _debugLog(dbName, message) {\r\n // Only log if running within test harness\r\n if (getGlobalInst(\"QUnit\")) {\r\n // tslint:disable-next-line:no-console\r\n console && console.log(\"IndexedDbHelper [\" + dbName + \"] \" + message);\r\n }\r\n}\r\n/**\r\n * Helper method to map an Event rejection to a reject with a message, this is mainly for terminal errors where the\r\n * IndexedDb API returns an event which we are going to ignore\r\n * @param rejectMessage\r\n * @param rejectFunc\r\n */\r\nfunction _eventReject(dbName, rejectMessage, rejectFunc, evtName) {\r\n return function (evt) {\r\n rejectFunc(new Error(rejectMessage));\r\n _debugLog(dbName, \"[\" + evtName + \"] event rejected\");\r\n };\r\n}\r\n// This helper is designed to allow multiple database implementation\r\n// The IndexedDB provider will be using only one database with different stores.\r\n// for each transaction, will open a new connection\r\nvar IndexedDbHelper = /** @class */ (function () {\r\n function IndexedDbHelper(diagLog) {\r\n var _dbFactory = getDbFactory() || null;\r\n dynamicProto(IndexedDbHelper, this, function (_this) {\r\n _this[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */] = function () {\r\n return !!_dbFactory;\r\n };\r\n /**\r\n * Schedules the opening of the database if not already open\r\n */\r\n _this.openDb = function (dbName, dbVersion, processFunc, versionChangeFunc) {\r\n // Schedule the database to be opened\r\n return _scheduleEvent(dbName, \"openDb\", function (evtName) {\r\n return createAsyncPromise(function (openResolve, openReject) {\r\n var createdNewDb = false;\r\n function _createDbCtx(dbContext, db, dbOpenRequest, isNew, isUpgrade) {\r\n var _a;\r\n var crDbCtx = (_a = {\r\n db: db\r\n },\r\n _a[_DYN_DB_NAME /* @min:dbName */] = dbName,\r\n _a.dbVersion = dbVersion,\r\n _a.ctx = null,\r\n _a.isNew = isNew,\r\n _a.txn = dbOpenRequest ? dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] : null // Special case see the versionChangeFunc usage below\r\n ,\r\n _a);\r\n if (!isUpgrade) {\r\n crDbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */] = function (eventTable, doAction) {\r\n return _openStore(crDbCtx, eventTable, doAction);\r\n };\r\n crDbCtx[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */] = function (eventTable, query, cursorFunc) {\r\n return _openCursor(crDbCtx, eventTable, query, cursorFunc);\r\n };\r\n }\r\n return crDbCtx;\r\n }\r\n // TODO: add function to handle version change\r\n function _databaseUpgrade(db, dbOpenRequest, ev) {\r\n _debugLog(dbName, \"db upgrade called\");\r\n var upgDbCtx = _createDbCtx(null, db, dbOpenRequest, true, true);\r\n if (!versionChangeFunc) {\r\n try {\r\n dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] && dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */].abort();\r\n dbOpenRequest.result && dbOpenRequest.result.close(); // close database to unblock others\r\n }\r\n finally {\r\n openReject(new Error(ErrorMessageDbUpgradeRequired));\r\n }\r\n return;\r\n }\r\n createdNewDb = true;\r\n doAwaitResponse(versionChangeFunc(upgDbCtx), function (response) {\r\n if (!response[_DYN_REJECTED /* @min:%2erejected */]) {\r\n // Special case handling, when a DB is first created calling createObjectStore() will\r\n // automatically start a version change transaction which will block all other transactions\r\n // from getting created, so we save the auto opened on here for reuse as part of opening the store\r\n _debugLog(upgDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"on version change success\");\r\n if (!upgDbCtx.txn) {\r\n upgDbCtx.txn = dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */];\r\n _debugLog(upgDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"added open request\");\r\n }\r\n }\r\n else {\r\n // Abort the upgrade event\r\n try {\r\n dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */] && dbOpenRequest[_DYN_TRANSACTION /* @min:%2etransaction */].abort();\r\n }\r\n finally {\r\n openReject(response.reason);\r\n }\r\n }\r\n });\r\n }\r\n function _databaseOpen(db, dbOpenRequest) {\r\n // Save the IDBDatabase handle to the global reference (so we can make sure we can close/delete the Db)\r\n // Also used to track the number of times the DB has been opened\r\n var opDbCtx = _getDbContext(dbName);\r\n opDbCtx.add(db);\r\n db.onabort = function (evt) {\r\n _debugLog(dbName, \"onabort -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n _debugLog(dbName, \"onerror -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db.onclose = function (evt) {\r\n _debugLog(dbName, \"onclose -- closing the Db\");\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n db.onversionchange = function (evt) {\r\n _debugLog(dbName, \"onversionchange -- force closing the Db\");\r\n db.close();\r\n opDbCtx[_DYN_REMOVE /* @min:%2eremove */](db);\r\n };\r\n var openDbCtx = null;\r\n var dbHdl = null;\r\n if (opDbCtx.dbHdl[_DYN_LENGTH /* @min:%2elength */] > 0) {\r\n dbHdl = opDbCtx[_DYN_DB_HDL /* @min:%2edbHdl */][0];\r\n }\r\n openDbCtx = _createDbCtx(opDbCtx, dbHdl, dbOpenRequest, createdNewDb);\r\n try {\r\n // Database has been opened\r\n doAwait(processFunc(openDbCtx), openResolve, openReject);\r\n }\r\n catch (e) {\r\n openReject(e);\r\n }\r\n }\r\n var dbCtx = _getDbContext(dbName);\r\n if (_dbFactory == null) {\r\n openReject(new Error(\"No available storage factory\"));\r\n }\r\n else if (dbCtx.isOpen()) {\r\n // Database is already open\r\n var openDbCtx = _createDbCtx(dbCtx, dbCtx.openHdl(), null, false);\r\n doAwait(processFunc(openDbCtx), openResolve, openReject);\r\n }\r\n else {\r\n var dbOpenRequest_1 = _dbFactory.open(dbName, dbVersion);\r\n if (!dbOpenRequest_1) {\r\n throw new Error(\"missing API\"); // in case, some corners case (such as private mode for certain browsers) does not support open db\r\n }\r\n // We can't open the database, possible issues are\r\n // - We are attempting to open the db as a different version but it's already open\r\n dbOpenRequest_1.onblocked = function (evt) {\r\n _debugLog(dbName, \"Db Open Blocked event [\" + evtName + \"] - \" + (dbOpenRequest_1.error || \"\"));\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n };\r\n dbOpenRequest_1[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n _debugLog(dbName, \"Db Open Error event [\" + evtName + \"] - \" + (dbOpenRequest_1.error || \"\"));\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n };\r\n dbOpenRequest_1.onupgradeneeded = function (evt) {\r\n _debugLog(dbName, \"Db Open Create/Upgrade needed event [\" + evtName + \"]\");\r\n try {\r\n var db = evt.target[Result] || dbOpenRequest_1.result;\r\n if (!db) {\r\n _debugLog(dbName, \"no db\");\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n return;\r\n }\r\n _databaseUpgrade(db, dbOpenRequest_1, evt);\r\n }\r\n catch (e) {\r\n _eventReject(dbName, ErrorMessageUnableToOpenDb, openReject, evtName)(e);\r\n }\r\n };\r\n dbOpenRequest_1[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n _debugLog(dbName, \"Db Open sucess [\" + evtName + \"]\");\r\n var db = evt.target[Result];\r\n if (!db) {\r\n openReject(new Error(ErrorMessageUnableToOpenDb));\r\n return;\r\n }\r\n _databaseOpen(db, dbOpenRequest_1);\r\n };\r\n }\r\n });\r\n });\r\n };\r\n _this.closeDb = function (dbName) {\r\n // Schedule the close so we don't interrupt an previous scheduled operations\r\n _debugLog(dbName, \"close db\");\r\n _scheduleEvent(dbName, \"closeDb\", function (evtName) {\r\n var dbCtx = _getDbContext(dbName);\r\n var dbHdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n var len = dbHdls[_DYN_LENGTH /* @min:%2elength */];\r\n if (len > 0) {\r\n for (var lp = 0; lp < len; lp++) {\r\n // Just call close the db.onclose() event should take care of decrementing and removing the references\r\n dbHdls[lp].close();\r\n }\r\n dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */] = [];\r\n }\r\n return 1;\r\n }).catch(function (reason) {\r\n // Handle promise rejection to avoid an unhandled rejection event\r\n });\r\n };\r\n _this.deleteDb = function (dbName) {\r\n if (_dbFactory == null) {\r\n return false;\r\n }\r\n return _scheduleEvent(dbName, \"deleteDb\", function (evtName) {\r\n // Implicitly close any open db first as this WILL block the deleting\r\n var dbCtx = _getDbContext(dbName);\r\n var dbHdls = dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */];\r\n var len = dbHdls[_DYN_LENGTH /* @min:%2elength */];\r\n if (len > 0) {\r\n _debugLog(dbName, \"Db is open [\" + len + \"] force closing\");\r\n for (var lp = 0; lp < len; lp++) {\r\n // Just call close the db.onclose() event should take care of decrementing and removing the references\r\n dbHdls[lp].close();\r\n }\r\n // Clear all of the existing handles as we have forced closed them and for compatibility we can't\r\n // rely on the db onclose event\r\n dbCtx[_DYN_DB_HDL /* @min:%2edbHdl */] = [];\r\n }\r\n return createAsyncPromise(function (deleteResolve, deleteReject) {\r\n // Attempting to delete the Db, only after we wait so that any outstanding operations can finish\r\n setTimeout(function () {\r\n try {\r\n _debugLog(dbName, \"[\" + evtName + \"] starting\");\r\n var dbRequest = _dbFactory.deleteDatabase(dbName);\r\n dbRequest[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest.onblocked = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest.onupgradeneeded = function (evt) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase));\r\n };\r\n dbRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n _debugLog(dbName, \"[\" + evtName + \"] complete\");\r\n deleteResolve(true);\r\n };\r\n _debugLog(dbName, \"[\" + evtName + \"] started\");\r\n }\r\n catch (e) {\r\n deleteReject(new Error(ErrorMessageFailedToDeleteDatabase + \" - \" + e));\r\n }\r\n }, 0);\r\n });\r\n });\r\n };\r\n _this.getDbDetails = function (dbName) {\r\n return _scheduleEvent(dbName, \"getDbDetails\", function (evtName) {\r\n if (_dbFactory == null || !_dbFactory.databases) {\r\n // Either IndexedDb is not supported or databases is not supported\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotSupported));\r\n }\r\n return createAsyncPromise(function (databasesResolve, databasesReject) {\r\n // databases() is still experimental, so it's not fully available\r\n // The promise will reject if there is a JS error\r\n var dbPromise = _dbFactory.databases();\r\n dbPromise[_DYN_THEN /* @min:%2ethen */](function (databases) {\r\n for (var lp = 0; lp < databases[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n if (databases[lp][_DYN_NAME /* @min:%2ename */] === dbName) {\r\n databasesResolve(databases[lp]);\r\n return;\r\n }\r\n }\r\n databasesReject(new Error(ErrorMessageDbDoesNotExist));\r\n }, databasesReject);\r\n });\r\n }, 2000);\r\n };\r\n function _createStoreContext(openDbCtx, eventTable) {\r\n // Save the current handle so we close the correct one during the transaction events\r\n var dbHdl = openDbCtx.db || null;\r\n // Check if the openDb event created a transaction that we should reuse\r\n var tx = dbHdl && dbHdl[_DYN_TRANSACTION /* @min:%2etransaction */](eventTable, DbReadWrite);\r\n if (tx) {\r\n // The transaction was aborted and therefore the adding of the event failed\r\n tx.onabort = function () {\r\n // add log\r\n };\r\n tx[_DYN_ONERROR /* @min:%2eonerror */] = function () {\r\n // add log\r\n };\r\n // Note we don't listen for the transaction onComplete event as we don't have any value\r\n // to resolve the promise with, we are relying on the doAction() to resolve and the exception\r\n // handling below to ensure we don't deadlock.\r\n tx.oncomplete = function () {\r\n // We need to capture the transaction close event as not all browsers are triggering the db onclose event\r\n _debugLog(openDbCtx[_DYN_DB_NAME /* @min:%2edbName */], \"txn.oncomplete\");\r\n };\r\n // Ok, so now we have the transaction handling setup lets try and store the event\r\n return {\r\n db: openDbCtx,\r\n store: tx.objectStore(eventTable),\r\n tx: tx,\r\n tbl: eventTable,\r\n openCursor: function (query, processFunc) {\r\n return _openCursor(openDbCtx, eventTable, query, processFunc);\r\n },\r\n newTransaction: function (doAction) {\r\n return _openStore(openDbCtx, eventTable, doAction);\r\n }\r\n };\r\n }\r\n return null;\r\n }\r\n /**\r\n * Opens the specific store for the database\r\n * @param openDbCtx\r\n * @param eventTable\r\n * @param doAction\r\n */\r\n function _openStore(openDbCtx, eventTable, doAction) {\r\n // While the open DB promise may have been resolved we still might not have opened the DB (This is to ensure that\r\n // non-critical failures don't cause event execution out of order)\r\n if (!openDbCtx || !openDbCtx.db) {\r\n // Database is not open so pass the only option is to resolve the event so it's passed onto the next on the event to the next chain\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotOpen));\r\n }\r\n try {\r\n // Perform the transaction action\r\n var result = doAction(_createStoreContext(openDbCtx, eventTable));\r\n if (isPromiseLike(result)) {\r\n return result;\r\n }\r\n return createAsyncResolvedPromise(result);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n }\r\n function _openCursor(openDbCtx, eventTable, query, processFunc) {\r\n // While the open DB promise may have been resolved we still might not have opened the DB (This is to ensure that\r\n // non-critical failures don't cause event execution out of order)\r\n if (!openDbCtx || !openDbCtx.db) {\r\n // Database is not open so pass the only option is to resolve the event so it's passed onto the next on the event to the next chain\r\n return createAsyncRejectedPromise(new Error(ErrorMessageDbNotOpen));\r\n }\r\n var simpleQuery = null;\r\n if (query && isString(query)) {\r\n simpleQuery = new SimpleQuery(query);\r\n }\r\n else if (query && query.isMatch) { // simple check to make sure this is a IIndexedDbSimpleQuery\r\n simpleQuery = query;\r\n }\r\n return createAsyncPromise(function (openCursorResolve, openCursorReject) {\r\n var values = [];\r\n var cursorRequest = null;\r\n var queryKeyRange = null;\r\n if (simpleQuery && simpleQuery[_DYN_KEY_RANGE /* @min:%2ekeyRange */]) {\r\n queryKeyRange = simpleQuery[_DYN_KEY_RANGE /* @min:%2ekeyRange */]();\r\n }\r\n var storeCtx = _createStoreContext(openDbCtx, eventTable);\r\n if (queryKeyRange) {\r\n cursorRequest = storeCtx.store[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */](queryKeyRange);\r\n }\r\n else {\r\n cursorRequest = storeCtx.store[_DYN_OPEN_CURSOR /* @min:%2eopenCursor */]();\r\n }\r\n cursorRequest.onerror = _eventReject(storeCtx.db[_DYN_DB_NAME /* @min:%2edbName */], ErrorMessageFailedToOpenCursor, openCursorReject, \"openCursor\");\r\n cursorRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n var _a;\r\n // Cursor was open/next iteration\r\n var cursor = evt.target[Result];\r\n if (!cursor) {\r\n // This occurs when we get to the end of the cursor iteration\r\n openCursorResolve(values);\r\n return;\r\n }\r\n var processCursorState = (_a = {\r\n store: storeCtx,\r\n cursor: cursor\r\n },\r\n _a[_DYN_CONTINUE /* @min:continue */] = function () {\r\n cursor[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n },\r\n _a.done = function () {\r\n openCursorResolve(values);\r\n } // Stops the cursor processing\r\n ,\r\n _a);\r\n var value = cursor[_DYN_VALUE /* @min:%2evalue */];\r\n if (simpleQuery && !simpleQuery.isMatch(value)) {\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n return;\r\n }\r\n if (processFunc) {\r\n try {\r\n switch (processFunc(processCursorState, value, values)) {\r\n case 2 /* CursorProcessResult.Complete */:\r\n openCursorResolve(values);\r\n break;\r\n case 1 /* CursorProcessResult.Waiting */:\r\n // The process method now controls whether th\r\n break;\r\n case 0 /* CursorProcessResult.Continue */:\r\n default:\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n break;\r\n }\r\n }\r\n catch (ex) {\r\n // Make sure the reject the promise if the processFunc callback throws unexpectable\r\n openCursorReject(ex);\r\n }\r\n }\r\n else {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n processCursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n }\r\n };\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * Identifies whether an IndexedDb api is available\r\n */\r\n IndexedDbHelper.prototype.isAvailable = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n IndexedDbHelper.prototype.openDb = function (dbName, dbVersion, processFunc, versionChangeFunc) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Request that any open database handles for the named database be closed.\r\n * This method will return immediately, however, the scheduled event to close the open Db handles will not occur until all outstanding database operations\r\n * (openDb, deleteDb, getDbDetails) started by IndexedDbHelper for the named db have completed. This will NOT affect or wait for any open database handles\r\n * which have been directly opened by the IndexedDB Api.\r\n * @param dbName - The name of the database to close, no error will be returned if the database does not exist or was not opened.\r\n */\r\n IndexedDbHelper.prototype.closeDb = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n /**\r\n * Request that the named database should be deleted, this implicitly closes any previously opened database that was opened via IndexedDBHelper.\r\n * It will also wait for all Promise objects from previous openDb, closeDb, getDbDetails to complete (resolve or reject) before attempting to\r\n * perform the delete operation. This operation may block or fail if the database is opened outstide of the IndexedDbHelper\r\n * The returned promise will be resolved or rejected depending on the outcome of the delete operation.\r\n * @param dbName - The name of the database to delete\r\n */\r\n IndexedDbHelper.prototype.deleteDb = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Attempt to return the details (version) of the named database if possible.\r\n * This method requires that the underlying browser support draft specification for IDBFactory.databases, if this is not supported then the returned\r\n * Promise will be rejected with an error message stating that the feature is not supported.\r\n * The returned Promise will be resolved with the details if available or rejected on error.\r\n * @param dbName - The name of the database to request the details for\r\n */\r\n IndexedDbHelper.prototype.getDbDetails = function (dbName) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n return IndexedDbHelper;\r\n}());\r\nexport { IndexedDbHelper };\r\n/**\r\n * A simple query interface to provide a simple cursor query (IDBKeyRange) key range and matching.\r\n * Used by the openCursor() method.\r\n */\r\nvar SimpleQuery = /** @class */ (function () {\r\n function SimpleQuery(theQuery) {\r\n var _queryCols = [];\r\n var _keyRange = null;\r\n dynamicProto(SimpleQuery, this, function (_this) {\r\n _this[_DYN_KEY_RANGE /* @min:%2ekeyRange */] = function () {\r\n return _keyRange;\r\n };\r\n _this.parseQuery = function (query) {\r\n _queryCols = [];\r\n if (query) {\r\n var items = query[_DYN_SPLIT /* @min:%2esplit */](\";\");\r\n for (var lp = 0; lp < items[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var item = items[lp];\r\n var idx = item[_DYN_INDEX_OF /* @min:%2eindexOf */](\"=\");\r\n if (idx !== -1) {\r\n var key = item[_DYN_SUBSTRING /* @min:%2esubstring */](0, idx);\r\n var value = item[_DYN_SUBSTRING /* @min:%2esubstring */](idx + 1);\r\n if (key[_DYN_INDEX_OF /* @min:%2eindexOf */](\"#\") === 0) {\r\n key = key[_DYN_SUBSTRING /* @min:%2esubstring */](1);\r\n if (!_keyRange) {\r\n _keyRange = IDBKeyRange.bound(value, value + \"\\uffff\");\r\n }\r\n }\r\n _this.startsWith(key, value);\r\n }\r\n }\r\n }\r\n };\r\n _this.startsWith = function (columnName, value) {\r\n var _a;\r\n _queryCols[_DYN_PUSH /* @min:%2epush */]((_a = {},\r\n _a[_DYN_NAME /* @min:name */] = columnName,\r\n _a[_DYN_VALUE /* @min:value */] = value,\r\n _a.type = 0 /* ValueQueryType.StartsWith */,\r\n _a));\r\n };\r\n _this.contains = function (columnName, value) {\r\n var _a;\r\n _queryCols[_DYN_PUSH /* @min:%2epush */]((_a = {},\r\n _a[_DYN_NAME /* @min:name */] = columnName,\r\n _a[_DYN_VALUE /* @min:value */] = value,\r\n _a.type = 1 /* ValueQueryType.Contains */,\r\n _a));\r\n };\r\n _this.isMatch = function (value) {\r\n // No query restriction so everything matches\r\n if (!_queryCols || _queryCols[_DYN_LENGTH /* @min:%2elength */] === 0) {\r\n return true;\r\n }\r\n if (!value) {\r\n return false;\r\n }\r\n for (var lp = 0; lp < _queryCols[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var query = _queryCols[lp];\r\n var chkValue = value[query.name];\r\n if (chkValue) {\r\n if (query.type === 0 /* ValueQueryType.StartsWith */) {\r\n if (chkValue.indexOf(query[_DYN_VALUE /* @min:%2evalue */]) !== 0) {\r\n return false;\r\n }\r\n }\r\n else if (query.type === 1 /* ValueQueryType.Contains */) {\r\n if (chkValue.indexOf(query[_DYN_VALUE /* @min:%2evalue */]) === -1) {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n if (theQuery) {\r\n _this.parseQuery(theQuery);\r\n }\r\n });\r\n }\r\n return SimpleQuery;\r\n}());\r\n//# sourceMappingURL=IndexDbHelper.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;2DA0CM,CAAC;;;;;2BACoB;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;;;;uBACiB;AACvB;AACA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.
|
|
2
|
+
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.2412-01
|
|
3
3
|
* Copyright (c) Microsoft and contributors. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -287,8 +287,7 @@ var IndexedDbProvider = /** @class */ (function () {
|
|
|
287
287
|
};
|
|
288
288
|
/**
|
|
289
289
|
* Removes the values
|
|
290
|
-
* @param evts
|
|
291
|
-
*/
|
|
290
|
+
* @param evts - */
|
|
292
291
|
_this[_DYN_REMOVE_EVENTS /* @min:%2eremoveEvents */] = function (evts) {
|
|
293
292
|
if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {
|
|
294
293
|
return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndexDbProvider.js.map","sources":["IndexDbProvider.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { isNotNullOrUndefined, isString, newGuid, onConfigChange } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncAllPromise, createAsyncPromise, doAwait, doAwaitResponse } from \"@nevware21/ts-async\";\r\nimport { batchDropNotification, getEndpointDomain, getTimeFromId, getTimeId } from \"../Helpers/Utils\";\r\nimport { _DYN_ADD_EVENT, _DYN_CLEAR, _DYN_CONTINUE, _DYN_CRITICAL_CNT, _DYN_DIAG_LOG, _DYN_ENDPOINT, _DYN_GET_NEXT_BATCH, _DYN_GET_TIME, _DYN_INITIALIZE, _DYN_INSTRUMENTATION_KEY, _DYN_IN_STORAGE_MAX_TIME, _DYN_IS_AVAILABLE, _DYN_ITEM_CTX, _DYN_LENGTH, _DYN_MAX_CRITICAL_EVTS_DR3, _DYN_NOTIFICATION_MGR, _DYN_ONERROR, _DYN_ONSUCCESS, _DYN_OPEN_STORE, _DYN_PUSH, _DYN_REMOVE_EVENTS, _DYN_SPLICE, _DYN_STORAGE_CONFIG, _DYN_STORAGE_KEY_PREFIX, _DYN_SUPPORTS_SYNC_REQUES4, _DYN_TEARDOWN, _DYN_THEN, _DYN__EVENTS_TO_DROP_PER_2 } from \"../__DynamicConstants\";\r\nimport { IndexedDbHelper } from \"./IndexDbHelper\";\r\n//TODO: move all const to one file\r\nvar EventsToDropAtOneTime = 10; // If we fail to add a new event this is the max number of events we will attempt to remove to make space\r\nvar StoreVersion = 1; // The Current version for the stored items, this will be used in the future for versioning\r\nvar OrhpanedEventThresholdInMs = 604800000; // 7 days\r\nvar UnknowniKey = \"Unknown\";\r\nvar ErrorMessageUnableToAddEvent = \"DBError: Unable to add event\";\r\nvar MaxCriticalEvtsDropCnt = 2;\r\nexport var DefaultDbName = \"AIOffline\"; // Db Name including the version number on the end so that if we ever have to upgrade old and new code can co-exist\r\nexport var DbVersion = 1; // The Current version of the database (Used to trigger upgrades)\r\nexport var EventObjectStoreName = \"Evts\";\r\nfunction _getTime() {\r\n return new Date()[_DYN_GET_TIME /* @min:%2egetTime */]();\r\n}\r\nfunction _createDb(db) {\r\n // data in the same db must have same endpoint url\r\n if (!db.objectStoreNames.contains(EventObjectStoreName)) {\r\n var evtStore = db.createObjectStore(EventObjectStoreName, { keyPath: \"id\" });\r\n evtStore.createIndex(\"criticalCnt\", \"criticalCnt\", { unique: false });\r\n }\r\n}\r\nfunction _getEvents(values) {\r\n var events = [];\r\n for (var lp = 0; lp < values[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var item = values[lp];\r\n if (item && item.evt) {\r\n events[_DYN_PUSH /* @min:%2epush */](item.evt);\r\n }\r\n }\r\n return events;\r\n}\r\nfunction _addEventByTime(values, newValue) {\r\n for (var idx = 0; idx < values[_DYN_LENGTH /* @min:%2elength */]; idx++) {\r\n if (newValue.tm < values[idx].tm) {\r\n values[_DYN_SPLICE /* @min:%2esplice */](idx, 0, newValue);\r\n return;\r\n }\r\n }\r\n values[_DYN_PUSH /* @min:%2epush */](newValue);\r\n}\r\nfunction _getId(key, values) {\r\n var len = values[_DYN_LENGTH /* @min:%2elength */];\r\n for (var lp = 0; lp < len; lp++) {\r\n if (key === values[lp].id) {\r\n return lp;\r\n }\r\n }\r\n return -1;\r\n}\r\nfunction _cursorContinueEvent(cursorState, value) {\r\n return function (evt) {\r\n return cursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n };\r\n}\r\nfunction _cursorDeleteAndContinue(cursorState, value) {\r\n var deleteRequest = cursorState.cursor.delete();\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = _cursorContinueEvent(cursorState);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = _cursorContinueEvent(cursorState);\r\n return 1 /* CursorProcessResult.Waiting */;\r\n}\r\nfunction _getAllEvents(dbCtx, cursorQuery, cnt) {\r\n // Open the Db store returning the embedded promise for handling resolving and rejecting the request chain\r\n return dbCtx.openCursor(EventObjectStoreName, cursorQuery, function (cursorState, value, values) {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n if (cnt && values && values[_DYN_LENGTH /* @min:%2elength */] == cnt) {\r\n return 2 /* CursorProcessResult.Complete */;\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n}\r\nfunction _deleteEvents(dbCtx, eventPrefixQuery, shouldDelete) {\r\n // Open the Event object store\r\n return dbCtx.openCursor(EventObjectStoreName, eventPrefixQuery, function (deleteCursorState, value, values) {\r\n if (shouldDelete(value)) {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n return _cursorDeleteAndContinue(deleteCursorState, value);\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n}\r\nfunction _dropMaxTimeEvents(dbCtx, maxTime) {\r\n return createAsyncPromise(function (deleteEvtsResolve, deleteEvtsReject) {\r\n return _deleteEvents(dbCtx, null, function (value) {\r\n if (!value || !value.evt) {\r\n return true;\r\n }\r\n var addedTime = getTimeFromId(value.id);\r\n var minStartTime = _getTime() + 1 - maxTime;\r\n if (addedTime <= minStartTime) {\r\n return true;\r\n }\r\n return false;\r\n })[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n deleteEvtsResolve(values);\r\n }, deleteEvtsReject);\r\n });\r\n}\r\nfunction _dropEventsUpToPersistence(dbCtx, maxpriorityCnt, maxDropCnt) {\r\n return createAsyncPromise(function (dropEventsResolve, dropEventsReject) {\r\n var droppedEvents = 0;\r\n function _resolveWithDroppedEvents() {\r\n dropEventsResolve(droppedEvents);\r\n }\r\n function _dropEvent(deleteStoreCtx, dropItem) {\r\n return createAsyncPromise(function (deleteResolve) {\r\n var deleteRequest = deleteStoreCtx.store.delete(dropItem.key);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n droppedEvents++;\r\n deleteResolve();\r\n };\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n deleteResolve();\r\n };\r\n });\r\n }\r\n function _processCandidates(dropCandidates) {\r\n if (dropCandidates[_DYN_LENGTH /* @min:%2elength */] === 0) {\r\n _resolveWithDroppedEvents();\r\n return;\r\n }\r\n dbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */](EventObjectStoreName, function (deleteStoreCtx) {\r\n var deleteEvts = [];\r\n for (var lp = 0; lp < dropCandidates[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n deleteEvts[_DYN_PUSH /* @min:%2epush */](_dropEvent(deleteStoreCtx, dropCandidates[lp]));\r\n }\r\n return createAsyncAllPromise(deleteEvts)[_DYN_THEN /* @min:%2ethen */](_resolveWithDroppedEvents, _resolveWithDroppedEvents);\r\n });\r\n }\r\n // Get all of the candidates that we may delete\r\n var cursorPromise = dbCtx.openCursor(EventObjectStoreName, null, function (cursorState, value, values) {\r\n if (value.evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] <= maxpriorityCnt) {\r\n _addEventByTime(values, value);\r\n if (values[_DYN_LENGTH /* @min:%2elength */] > maxDropCnt) {\r\n values.splice(values[_DYN_LENGTH /* @min:%2elength */] - 1, 1);\r\n }\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n cursorPromise[_DYN_THEN /* @min:%2ethen */](_processCandidates, function () {\r\n dropEventsResolve(0);\r\n });\r\n });\r\n}\r\n/**\r\n * Class that implements storing of events using the WebStorage Api ((window||globalThis||self).localstorage, (window||globalThis||self).sessionStorage).\r\n */\r\nvar IndexedDbProvider = /** @class */ (function () {\r\n /**\r\n * Creates a WebStorageProvider using the provider storageType\r\n */\r\n function IndexedDbProvider(id, unloadHookContainer) {\r\n dynamicProto(IndexedDbProvider, this, function (_this) {\r\n var _indexedDb = null;\r\n var _dbName = null;\r\n var _iKey = UnknowniKey;\r\n var _storageId = null; // Used as a unique id so that when active on multiple tabs (threads) the apps don't corrupts each other\r\n var _autoClean = null;\r\n var _endpoint = null;\r\n var _storageKeyPrefix = null;\r\n var _maxStorageTime = null;\r\n var _eventDropPerTime = null;\r\n var _maxCriticalCnt = null;\r\n var _notificationManager = null;\r\n _this.id = id;\r\n _this[_DYN_INITIALIZE /* @min:%2einitialize */] = function (providerContext) {\r\n var diagLog = providerContext.itemCtx[_DYN_DIAG_LOG /* @min:%2ediagLog */]();\r\n _indexedDb = new IndexedDbHelper(diagLog);\r\n if (!_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n _indexedDb = null;\r\n return false;\r\n }\r\n var coreConfig = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */].getCfg();\r\n var itemCtx = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */];\r\n var ikey = itemCtx.getCfg()[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */] || coreConfig[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */];\r\n if (!isString(ikey)) {\r\n //_iKey = ikey\r\n return;\r\n }\r\n _iKey = ikey;\r\n var storageConfig = providerContext[_DYN_STORAGE_CONFIG /* @min:%2estorageConfig */];\r\n _storageId = _this.id || providerContext.id || newGuid();\r\n _notificationManager = providerContext[_DYN_NOTIFICATION_MGR /* @min:%2enotificationMgr */];\r\n _endpoint = getEndpointDomain(providerContext[_DYN_ENDPOINT /* @min:%2eendpoint */]);\r\n _autoClean = !!storageConfig.autoClean;\r\n _storageKeyPrefix = storageConfig[_DYN_STORAGE_KEY_PREFIX /* @min:%2estorageKeyPrefix */] || DefaultDbName;\r\n _dbName = _storageKeyPrefix + \"_\" + DbVersion + \"_\" + _endpoint;\r\n // currently, won't handle endpoint change\r\n // new endpoint will open a new db\r\n // endpoint change will be handled at offline batch lavel\r\n // namePrefix should not contain any \"_\"\r\n var unloadHook = onConfigChange(storageConfig, function () {\r\n _maxStorageTime = storageConfig[_DYN_IN_STORAGE_MAX_TIME /* @min:%2einStorageMaxTime */] || OrhpanedEventThresholdInMs; // TODO: handle 0\r\n var dropNum = storageConfig[_DYN__EVENTS_TO_DROP_PER_2 /* @min:%2eEventsToDropPerTime */];\r\n _eventDropPerTime = isNotNullOrUndefined(dropNum) ? dropNum : EventsToDropAtOneTime;\r\n _maxCriticalCnt = storageConfig[_DYN_MAX_CRITICAL_EVTS_DR3 /* @min:%2emaxCriticalEvtsDropCnt */] || MaxCriticalEvtsDropCnt;\r\n });\r\n unloadHookContainer && unloadHookContainer.add(unloadHook);\r\n if (_dbName) {\r\n doAwaitResponse(_this.clean(!_autoClean), function (response) {\r\n _openDb(function (dbCtx) {\r\n return true;\r\n })[_DYN_THEN /* @min:%2ethen */](function (value) {\r\n // All done, but as initialize isn't waiting just ignore\r\n }, function (reason) {\r\n // clear and stop using indexedDb\r\n diagLog.warnToConsole(\"IndexedDbProvider failed to initialize - \" + (reason || \"<unknown>\"));\r\n _indexedDb = null;\r\n });\r\n });\r\n }\r\n return true;\r\n };\r\n _this[\"_getDbgPlgTargets\"] = function () {\r\n return [_dbName, _endpoint, _maxStorageTime, _indexedDb];\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronious requests\r\n */\r\n _this[_DYN_SUPPORTS_SYNC_REQUES4 /* @min:%2esupportsSyncRequests */] = function () {\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events( with given number) from the storage mechanism\r\n */\r\n _this.getAllEvents = function (cnt) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n return _openDb(function (dbCtx) {\r\n return createAsyncPromise(function (allEventsResolve, allEventsReject) {\r\n _getAllEvents(dbCtx, null, cnt)[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n //TODO: orderEvents By CriticalCnt\r\n allEventsResolve(_getEvents(values));\r\n }, allEventsReject);\r\n });\r\n });\r\n };\r\n /**\r\n * Get all of the currently cached events( with given number) from the storage mechanism\r\n */\r\n _this[_DYN_GET_NEXT_BATCH /* @min:%2egetNextBatch */] = function () {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n // Start an asynchronous set of events to access the Db, this first one will wait until all current outstanding\r\n // events are completed or rejected\r\n return _openDb(function (dbCtx) {\r\n return createAsyncPromise(function (allEventsResolve, allEventsReject) {\r\n _getAllEvents(dbCtx, null, 1)[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n allEventsResolve(_getEvents(values));\r\n }, allEventsReject);\r\n });\r\n });\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param value - The actual value of the request\r\n */\r\n _this[_DYN_ADD_EVENT /* @min:%2eaddEvent */] = function (key, item, itemCtx) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return item;\r\n }\r\n item.id = item.id || getTimeId();\r\n item[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] = item[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] || 0;\r\n return _openDb(function (dbCtx) {\r\n var eventKey = key || item.id;\r\n var dbItem = {\r\n id: eventKey,\r\n evt: item,\r\n tm: _getTime(),\r\n v: StoreVersion\r\n };\r\n return _addDbEvent(dbCtx, dbItem, true);\r\n });\r\n };\r\n /**\r\n * Removes the values\r\n * @param evts\r\n */\r\n _this[_DYN_REMOVE_EVENTS /* @min:%2eremoveEvents */] = function (evts) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n var removedEvents = [];\r\n return createAsyncPromise(function (removeEventsResolve, removeEventsReject) {\r\n // Open the Db store, this will handling resolving and rejecting this promise via the passed resolve/reject functions\r\n _openDb(function (dbCtx) {\r\n return dbCtx.openCursor(EventObjectStoreName, null, function (cursorState, value, values) {\r\n if (_getId(value.id, evts) !== -1) {\r\n var deleteRequest = cursorState.cursor.delete();\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = _cursorContinueEvent(cursorState);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function () {\r\n removedEvents[_DYN_PUSH /* @min:%2epush */](value.evt);\r\n cursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n };\r\n return 1 /* CursorProcessResult.Waiting */;\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n })[_DYN_THEN /* @min:%2ethen */](function () {\r\n removeEventsResolve(removedEvents); // Resolve the RemoveEvents call promise\r\n }, function (reason) {\r\n removeEventsResolve(removedEvents); // Resolve the RemoveEvents call promise\r\n });\r\n });\r\n };\r\n /**\r\n * Removes all entries from the storage provider and returns them as part of the response, if there are any.\r\n */\r\n _this[_DYN_CLEAR /* @min:%2eclear */] = function (disable) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]() || !!disable) {\r\n return [];\r\n }\r\n return createAsyncPromise(function (clearResolve, clearReject) {\r\n _openDb(function (dbCtx) {\r\n //delete all evts\r\n return _deleteEvents(dbCtx, null, function (value) {\r\n return true;\r\n });\r\n })[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n clearResolve(_getEvents(values));\r\n }, function (reason) {\r\n clearResolve([]);\r\n });\r\n });\r\n };\r\n _this.clean = function (disable) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]() || !!disable) {\r\n return false;\r\n }\r\n return createAsyncPromise(function (cleanResolve, cleanReject) {\r\n _openDb(function (dbCtx) {\r\n if (dbCtx.isNew) {\r\n return [];\r\n }\r\n return _dropMaxTimeEvents(dbCtx, _maxStorageTime);\r\n })[_DYN_THEN /* @min:%2ethen */](function (value) {\r\n var cnt = value && value[_DYN_LENGTH /* @min:%2elength */];\r\n if (_notificationManager && cnt) {\r\n batchDropNotification(_notificationManager, cnt, 3 /* eBatchDiscardedReason.MaxInStorageTimeExceeded */);\r\n }\r\n cleanResolve(cnt && cnt > 0);\r\n }, function (reason) {\r\n cleanResolve(false);\r\n });\r\n });\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n * This attempts to update the lastAccessTime for any storedDb\r\n */\r\n _this[_DYN_TEARDOWN /* @min:%2eteardown */] = function () {\r\n if (_indexedDb) {\r\n _indexedDb.closeDb(_dbName);\r\n }\r\n };\r\n /**\r\n * Schedules the opening of the database if not already open\r\n */\r\n function _openDb(processFunc) {\r\n function _handleDbUpgrade(dbCtx) {\r\n return createAsyncPromise(function (createResolve, createReject) {\r\n try {\r\n _createDb(dbCtx.db);\r\n }\r\n catch (e) {\r\n createReject(e);\r\n }\r\n createResolve();\r\n });\r\n }\r\n function _handleDbOpen(dbCtx) {\r\n return createAsyncPromise(function (openResolve, openReject) {\r\n var providerCtx = {\r\n iKey: _iKey,\r\n id: _endpoint,\r\n storageId: _storageId\r\n };\r\n dbCtx.ctx = providerCtx;\r\n doAwait(processFunc(dbCtx), openResolve, openReject);\r\n });\r\n }\r\n return _indexedDb.openDb(_dbName, DbVersion, _handleDbOpen, _handleDbUpgrade);\r\n }\r\n function _addDbEvent(dbCtx, dbItem, doRetry) {\r\n return createAsyncPromise(function (addEventResolve, addEventReject) {\r\n function dropEvents(droppedFunc) {\r\n // Try and clear space by dropping the Normal level events, note dropEvents promise never rejects\r\n _dropEventsUpToPersistence(dbCtx, _maxCriticalCnt, _eventDropPerTime)[_DYN_THEN /* @min:%2ethen */](function (droppedCount) {\r\n if (_notificationManager && droppedCount) {\r\n batchDropNotification(_notificationManager, droppedCount, 2 /* eBatchDiscardedReason.CleanStorage */);\r\n }\r\n droppedFunc(droppedCount);\r\n }, function (reason) {\r\n // won't throw errors here, unblock following process\r\n droppedFunc(0);\r\n });\r\n }\r\n function _insertNewEvent() {\r\n dbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */](EventObjectStoreName, function (storeCtx) {\r\n var request = storeCtx.store.put(dbItem);\r\n request[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n addEventResolve(dbItem.evt);\r\n };\r\n request[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n if (!doRetry) {\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n return;\r\n }\r\n function _retryAddEvent(dropCount) {\r\n if (dropCount === 0) {\r\n // We failed to free up space so just reject\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n }\r\n // Retry sending the event\r\n _addDbEvent(dbCtx, dbItem, false)[_DYN_THEN /* @min:%2ethen */](function (theItem) {\r\n addEventResolve(dbItem.evt); // Resolve the calling add Event promise\r\n }, function () {\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n });\r\n }\r\n dropEvents(function (droppedCount) {\r\n if (droppedCount > 0) {\r\n // We dropped some events so lets try adding the item again\r\n _retryAddEvent(droppedCount);\r\n }\r\n else {\r\n // We have already tried to remove all we can\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n }\r\n });\r\n };\r\n }).catch(function (e) {\r\n addEventReject(e);\r\n });\r\n }\r\n _insertNewEvent();\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * Initializes the provider using the config\r\n * @param providerContext The provider context that should be used to initialize the provider\r\n * @returns True if the provider is initialized and available for use otherwise false\r\n */\r\n IndexedDbProvider.prototype.initialize = function (providerContext) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n IndexedDbProvider.prototype.supportsSyncRequests = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n IndexedDbProvider.prototype.getNextBatch = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n IndexedDbProvider.prototype.getAllEvents = function (cnt) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param evt - The actual event of the request\r\n * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances\r\n * can optionally use this to access the current core instance or define / pass additional information\r\n * to later plugins (vs appending items to the telemetry item)\r\n */\r\n IndexedDbProvider.prototype.addEvent = function (key, evt, itemCtx) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n IndexedDbProvider.prototype.removeEvents = function (evts) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries from the storage provider, if there are any.\r\n */\r\n IndexedDbProvider.prototype.clear = function (disable) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries with stroage time longer than inStorageMaxTime from the storage provider\r\n */\r\n IndexedDbProvider.prototype.clean = function (disable) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n */\r\n IndexedDbProvider.prototype.teardown = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n return IndexedDbProvider;\r\n}());\r\nexport { IndexedDbProvider };\r\n//# sourceMappingURL=IndexDbProvider.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;yDAqEM,CAAC;;;;;6BACsB;AAC7B;AACA;AACA"}
|
|
1
|
+
{"version":3,"file":"IndexDbProvider.js.map","sources":["IndexDbProvider.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { isNotNullOrUndefined, isString, newGuid, onConfigChange } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncAllPromise, createAsyncPromise, doAwait, doAwaitResponse } from \"@nevware21/ts-async\";\r\nimport { batchDropNotification, getEndpointDomain, getTimeFromId, getTimeId } from \"../Helpers/Utils\";\r\nimport { _DYN_ADD_EVENT, _DYN_CLEAR, _DYN_CONTINUE, _DYN_CRITICAL_CNT, _DYN_DIAG_LOG, _DYN_ENDPOINT, _DYN_GET_NEXT_BATCH, _DYN_GET_TIME, _DYN_INITIALIZE, _DYN_INSTRUMENTATION_KEY, _DYN_IN_STORAGE_MAX_TIME, _DYN_IS_AVAILABLE, _DYN_ITEM_CTX, _DYN_LENGTH, _DYN_MAX_CRITICAL_EVTS_DR3, _DYN_NOTIFICATION_MGR, _DYN_ONERROR, _DYN_ONSUCCESS, _DYN_OPEN_STORE, _DYN_PUSH, _DYN_REMOVE_EVENTS, _DYN_SPLICE, _DYN_STORAGE_CONFIG, _DYN_STORAGE_KEY_PREFIX, _DYN_SUPPORTS_SYNC_REQUES4, _DYN_TEARDOWN, _DYN_THEN, _DYN__EVENTS_TO_DROP_PER_2 } from \"../__DynamicConstants\";\r\nimport { IndexedDbHelper } from \"./IndexDbHelper\";\r\n//TODO: move all const to one file\r\nvar EventsToDropAtOneTime = 10; // If we fail to add a new event this is the max number of events we will attempt to remove to make space\r\nvar StoreVersion = 1; // The Current version for the stored items, this will be used in the future for versioning\r\nvar OrhpanedEventThresholdInMs = 604800000; // 7 days\r\nvar UnknowniKey = \"Unknown\";\r\nvar ErrorMessageUnableToAddEvent = \"DBError: Unable to add event\";\r\nvar MaxCriticalEvtsDropCnt = 2;\r\nexport var DefaultDbName = \"AIOffline\"; // Db Name including the version number on the end so that if we ever have to upgrade old and new code can co-exist\r\nexport var DbVersion = 1; // The Current version of the database (Used to trigger upgrades)\r\nexport var EventObjectStoreName = \"Evts\";\r\nfunction _getTime() {\r\n return new Date()[_DYN_GET_TIME /* @min:%2egetTime */]();\r\n}\r\nfunction _createDb(db) {\r\n // data in the same db must have same endpoint url\r\n if (!db.objectStoreNames.contains(EventObjectStoreName)) {\r\n var evtStore = db.createObjectStore(EventObjectStoreName, { keyPath: \"id\" });\r\n evtStore.createIndex(\"criticalCnt\", \"criticalCnt\", { unique: false });\r\n }\r\n}\r\nfunction _getEvents(values) {\r\n var events = [];\r\n for (var lp = 0; lp < values[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n var item = values[lp];\r\n if (item && item.evt) {\r\n events[_DYN_PUSH /* @min:%2epush */](item.evt);\r\n }\r\n }\r\n return events;\r\n}\r\nfunction _addEventByTime(values, newValue) {\r\n for (var idx = 0; idx < values[_DYN_LENGTH /* @min:%2elength */]; idx++) {\r\n if (newValue.tm < values[idx].tm) {\r\n values[_DYN_SPLICE /* @min:%2esplice */](idx, 0, newValue);\r\n return;\r\n }\r\n }\r\n values[_DYN_PUSH /* @min:%2epush */](newValue);\r\n}\r\nfunction _getId(key, values) {\r\n var len = values[_DYN_LENGTH /* @min:%2elength */];\r\n for (var lp = 0; lp < len; lp++) {\r\n if (key === values[lp].id) {\r\n return lp;\r\n }\r\n }\r\n return -1;\r\n}\r\nfunction _cursorContinueEvent(cursorState, value) {\r\n return function (evt) {\r\n return cursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n };\r\n}\r\nfunction _cursorDeleteAndContinue(cursorState, value) {\r\n var deleteRequest = cursorState.cursor.delete();\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = _cursorContinueEvent(cursorState);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = _cursorContinueEvent(cursorState);\r\n return 1 /* CursorProcessResult.Waiting */;\r\n}\r\nfunction _getAllEvents(dbCtx, cursorQuery, cnt) {\r\n // Open the Db store returning the embedded promise for handling resolving and rejecting the request chain\r\n return dbCtx.openCursor(EventObjectStoreName, cursorQuery, function (cursorState, value, values) {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n if (cnt && values && values[_DYN_LENGTH /* @min:%2elength */] == cnt) {\r\n return 2 /* CursorProcessResult.Complete */;\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n}\r\nfunction _deleteEvents(dbCtx, eventPrefixQuery, shouldDelete) {\r\n // Open the Event object store\r\n return dbCtx.openCursor(EventObjectStoreName, eventPrefixQuery, function (deleteCursorState, value, values) {\r\n if (shouldDelete(value)) {\r\n values[_DYN_PUSH /* @min:%2epush */](value);\r\n return _cursorDeleteAndContinue(deleteCursorState, value);\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n}\r\nfunction _dropMaxTimeEvents(dbCtx, maxTime) {\r\n return createAsyncPromise(function (deleteEvtsResolve, deleteEvtsReject) {\r\n return _deleteEvents(dbCtx, null, function (value) {\r\n if (!value || !value.evt) {\r\n return true;\r\n }\r\n var addedTime = getTimeFromId(value.id);\r\n var minStartTime = _getTime() + 1 - maxTime;\r\n if (addedTime <= minStartTime) {\r\n return true;\r\n }\r\n return false;\r\n })[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n deleteEvtsResolve(values);\r\n }, deleteEvtsReject);\r\n });\r\n}\r\nfunction _dropEventsUpToPersistence(dbCtx, maxpriorityCnt, maxDropCnt) {\r\n return createAsyncPromise(function (dropEventsResolve, dropEventsReject) {\r\n var droppedEvents = 0;\r\n function _resolveWithDroppedEvents() {\r\n dropEventsResolve(droppedEvents);\r\n }\r\n function _dropEvent(deleteStoreCtx, dropItem) {\r\n return createAsyncPromise(function (deleteResolve) {\r\n var deleteRequest = deleteStoreCtx.store.delete(dropItem.key);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n droppedEvents++;\r\n deleteResolve();\r\n };\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n deleteResolve();\r\n };\r\n });\r\n }\r\n function _processCandidates(dropCandidates) {\r\n if (dropCandidates[_DYN_LENGTH /* @min:%2elength */] === 0) {\r\n _resolveWithDroppedEvents();\r\n return;\r\n }\r\n dbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */](EventObjectStoreName, function (deleteStoreCtx) {\r\n var deleteEvts = [];\r\n for (var lp = 0; lp < dropCandidates[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n deleteEvts[_DYN_PUSH /* @min:%2epush */](_dropEvent(deleteStoreCtx, dropCandidates[lp]));\r\n }\r\n return createAsyncAllPromise(deleteEvts)[_DYN_THEN /* @min:%2ethen */](_resolveWithDroppedEvents, _resolveWithDroppedEvents);\r\n });\r\n }\r\n // Get all of the candidates that we may delete\r\n var cursorPromise = dbCtx.openCursor(EventObjectStoreName, null, function (cursorState, value, values) {\r\n if (value.evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] <= maxpriorityCnt) {\r\n _addEventByTime(values, value);\r\n if (values[_DYN_LENGTH /* @min:%2elength */] > maxDropCnt) {\r\n values.splice(values[_DYN_LENGTH /* @min:%2elength */] - 1, 1);\r\n }\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n cursorPromise[_DYN_THEN /* @min:%2ethen */](_processCandidates, function () {\r\n dropEventsResolve(0);\r\n });\r\n });\r\n}\r\n/**\r\n * Class that implements storing of events using the WebStorage Api ((window||globalThis||self).localstorage, (window||globalThis||self).sessionStorage).\r\n */\r\nvar IndexedDbProvider = /** @class */ (function () {\r\n /**\r\n * Creates a WebStorageProvider using the provider storageType\r\n */\r\n function IndexedDbProvider(id, unloadHookContainer) {\r\n dynamicProto(IndexedDbProvider, this, function (_this) {\r\n var _indexedDb = null;\r\n var _dbName = null;\r\n var _iKey = UnknowniKey;\r\n var _storageId = null; // Used as a unique id so that when active on multiple tabs (threads) the apps don't corrupts each other\r\n var _autoClean = null;\r\n var _endpoint = null;\r\n var _storageKeyPrefix = null;\r\n var _maxStorageTime = null;\r\n var _eventDropPerTime = null;\r\n var _maxCriticalCnt = null;\r\n var _notificationManager = null;\r\n _this.id = id;\r\n _this[_DYN_INITIALIZE /* @min:%2einitialize */] = function (providerContext) {\r\n var diagLog = providerContext.itemCtx[_DYN_DIAG_LOG /* @min:%2ediagLog */]();\r\n _indexedDb = new IndexedDbHelper(diagLog);\r\n if (!_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n _indexedDb = null;\r\n return false;\r\n }\r\n var coreConfig = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */].getCfg();\r\n var itemCtx = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */];\r\n var ikey = itemCtx.getCfg()[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */] || coreConfig[_DYN_INSTRUMENTATION_KEY /* @min:%2einstrumentationKey */];\r\n if (!isString(ikey)) {\r\n //_iKey = ikey\r\n return;\r\n }\r\n _iKey = ikey;\r\n var storageConfig = providerContext[_DYN_STORAGE_CONFIG /* @min:%2estorageConfig */];\r\n _storageId = _this.id || providerContext.id || newGuid();\r\n _notificationManager = providerContext[_DYN_NOTIFICATION_MGR /* @min:%2enotificationMgr */];\r\n _endpoint = getEndpointDomain(providerContext[_DYN_ENDPOINT /* @min:%2eendpoint */]);\r\n _autoClean = !!storageConfig.autoClean;\r\n _storageKeyPrefix = storageConfig[_DYN_STORAGE_KEY_PREFIX /* @min:%2estorageKeyPrefix */] || DefaultDbName;\r\n _dbName = _storageKeyPrefix + \"_\" + DbVersion + \"_\" + _endpoint;\r\n // currently, won't handle endpoint change\r\n // new endpoint will open a new db\r\n // endpoint change will be handled at offline batch lavel\r\n // namePrefix should not contain any \"_\"\r\n var unloadHook = onConfigChange(storageConfig, function () {\r\n _maxStorageTime = storageConfig[_DYN_IN_STORAGE_MAX_TIME /* @min:%2einStorageMaxTime */] || OrhpanedEventThresholdInMs; // TODO: handle 0\r\n var dropNum = storageConfig[_DYN__EVENTS_TO_DROP_PER_2 /* @min:%2eEventsToDropPerTime */];\r\n _eventDropPerTime = isNotNullOrUndefined(dropNum) ? dropNum : EventsToDropAtOneTime;\r\n _maxCriticalCnt = storageConfig[_DYN_MAX_CRITICAL_EVTS_DR3 /* @min:%2emaxCriticalEvtsDropCnt */] || MaxCriticalEvtsDropCnt;\r\n });\r\n unloadHookContainer && unloadHookContainer.add(unloadHook);\r\n if (_dbName) {\r\n doAwaitResponse(_this.clean(!_autoClean), function (response) {\r\n _openDb(function (dbCtx) {\r\n return true;\r\n })[_DYN_THEN /* @min:%2ethen */](function (value) {\r\n // All done, but as initialize isn't waiting just ignore\r\n }, function (reason) {\r\n // clear and stop using indexedDb\r\n diagLog.warnToConsole(\"IndexedDbProvider failed to initialize - \" + (reason || \"<unknown>\"));\r\n _indexedDb = null;\r\n });\r\n });\r\n }\r\n return true;\r\n };\r\n _this[\"_getDbgPlgTargets\"] = function () {\r\n return [_dbName, _endpoint, _maxStorageTime, _indexedDb];\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronious requests\r\n */\r\n _this[_DYN_SUPPORTS_SYNC_REQUES4 /* @min:%2esupportsSyncRequests */] = function () {\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events( with given number) from the storage mechanism\r\n */\r\n _this.getAllEvents = function (cnt) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n return _openDb(function (dbCtx) {\r\n return createAsyncPromise(function (allEventsResolve, allEventsReject) {\r\n _getAllEvents(dbCtx, null, cnt)[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n //TODO: orderEvents By CriticalCnt\r\n allEventsResolve(_getEvents(values));\r\n }, allEventsReject);\r\n });\r\n });\r\n };\r\n /**\r\n * Get all of the currently cached events( with given number) from the storage mechanism\r\n */\r\n _this[_DYN_GET_NEXT_BATCH /* @min:%2egetNextBatch */] = function () {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n // Start an asynchronous set of events to access the Db, this first one will wait until all current outstanding\r\n // events are completed or rejected\r\n return _openDb(function (dbCtx) {\r\n return createAsyncPromise(function (allEventsResolve, allEventsReject) {\r\n _getAllEvents(dbCtx, null, 1)[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n allEventsResolve(_getEvents(values));\r\n }, allEventsReject);\r\n });\r\n });\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param value - The actual value of the request\r\n */\r\n _this[_DYN_ADD_EVENT /* @min:%2eaddEvent */] = function (key, item, itemCtx) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return item;\r\n }\r\n item.id = item.id || getTimeId();\r\n item[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] = item[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] || 0;\r\n return _openDb(function (dbCtx) {\r\n var eventKey = key || item.id;\r\n var dbItem = {\r\n id: eventKey,\r\n evt: item,\r\n tm: _getTime(),\r\n v: StoreVersion\r\n };\r\n return _addDbEvent(dbCtx, dbItem, true);\r\n });\r\n };\r\n /**\r\n * Removes the values\r\n * @param evts - */\r\n _this[_DYN_REMOVE_EVENTS /* @min:%2eremoveEvents */] = function (evts) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]()) {\r\n return [];\r\n }\r\n var removedEvents = [];\r\n return createAsyncPromise(function (removeEventsResolve, removeEventsReject) {\r\n // Open the Db store, this will handling resolving and rejecting this promise via the passed resolve/reject functions\r\n _openDb(function (dbCtx) {\r\n return dbCtx.openCursor(EventObjectStoreName, null, function (cursorState, value, values) {\r\n if (_getId(value.id, evts) !== -1) {\r\n var deleteRequest = cursorState.cursor.delete();\r\n deleteRequest[_DYN_ONERROR /* @min:%2eonerror */] = _cursorContinueEvent(cursorState);\r\n deleteRequest[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function () {\r\n removedEvents[_DYN_PUSH /* @min:%2epush */](value.evt);\r\n cursorState[_DYN_CONTINUE /* @min:%2econtinue */]();\r\n };\r\n return 1 /* CursorProcessResult.Waiting */;\r\n }\r\n return 0 /* CursorProcessResult.Continue */;\r\n });\r\n })[_DYN_THEN /* @min:%2ethen */](function () {\r\n removeEventsResolve(removedEvents); // Resolve the RemoveEvents call promise\r\n }, function (reason) {\r\n removeEventsResolve(removedEvents); // Resolve the RemoveEvents call promise\r\n });\r\n });\r\n };\r\n /**\r\n * Removes all entries from the storage provider and returns them as part of the response, if there are any.\r\n */\r\n _this[_DYN_CLEAR /* @min:%2eclear */] = function (disable) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]() || !!disable) {\r\n return [];\r\n }\r\n return createAsyncPromise(function (clearResolve, clearReject) {\r\n _openDb(function (dbCtx) {\r\n //delete all evts\r\n return _deleteEvents(dbCtx, null, function (value) {\r\n return true;\r\n });\r\n })[_DYN_THEN /* @min:%2ethen */](function (values) {\r\n clearResolve(_getEvents(values));\r\n }, function (reason) {\r\n clearResolve([]);\r\n });\r\n });\r\n };\r\n _this.clean = function (disable) {\r\n if (_indexedDb == null || !_indexedDb[_DYN_IS_AVAILABLE /* @min:%2eisAvailable */]() || !!disable) {\r\n return false;\r\n }\r\n return createAsyncPromise(function (cleanResolve, cleanReject) {\r\n _openDb(function (dbCtx) {\r\n if (dbCtx.isNew) {\r\n return [];\r\n }\r\n return _dropMaxTimeEvents(dbCtx, _maxStorageTime);\r\n })[_DYN_THEN /* @min:%2ethen */](function (value) {\r\n var cnt = value && value[_DYN_LENGTH /* @min:%2elength */];\r\n if (_notificationManager && cnt) {\r\n batchDropNotification(_notificationManager, cnt, 3 /* eBatchDiscardedReason.MaxInStorageTimeExceeded */);\r\n }\r\n cleanResolve(cnt && cnt > 0);\r\n }, function (reason) {\r\n cleanResolve(false);\r\n });\r\n });\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n * This attempts to update the lastAccessTime for any storedDb\r\n */\r\n _this[_DYN_TEARDOWN /* @min:%2eteardown */] = function () {\r\n if (_indexedDb) {\r\n _indexedDb.closeDb(_dbName);\r\n }\r\n };\r\n /**\r\n * Schedules the opening of the database if not already open\r\n */\r\n function _openDb(processFunc) {\r\n function _handleDbUpgrade(dbCtx) {\r\n return createAsyncPromise(function (createResolve, createReject) {\r\n try {\r\n _createDb(dbCtx.db);\r\n }\r\n catch (e) {\r\n createReject(e);\r\n }\r\n createResolve();\r\n });\r\n }\r\n function _handleDbOpen(dbCtx) {\r\n return createAsyncPromise(function (openResolve, openReject) {\r\n var providerCtx = {\r\n iKey: _iKey,\r\n id: _endpoint,\r\n storageId: _storageId\r\n };\r\n dbCtx.ctx = providerCtx;\r\n doAwait(processFunc(dbCtx), openResolve, openReject);\r\n });\r\n }\r\n return _indexedDb.openDb(_dbName, DbVersion, _handleDbOpen, _handleDbUpgrade);\r\n }\r\n function _addDbEvent(dbCtx, dbItem, doRetry) {\r\n return createAsyncPromise(function (addEventResolve, addEventReject) {\r\n function dropEvents(droppedFunc) {\r\n // Try and clear space by dropping the Normal level events, note dropEvents promise never rejects\r\n _dropEventsUpToPersistence(dbCtx, _maxCriticalCnt, _eventDropPerTime)[_DYN_THEN /* @min:%2ethen */](function (droppedCount) {\r\n if (_notificationManager && droppedCount) {\r\n batchDropNotification(_notificationManager, droppedCount, 2 /* eBatchDiscardedReason.CleanStorage */);\r\n }\r\n droppedFunc(droppedCount);\r\n }, function (reason) {\r\n // won't throw errors here, unblock following process\r\n droppedFunc(0);\r\n });\r\n }\r\n function _insertNewEvent() {\r\n dbCtx[_DYN_OPEN_STORE /* @min:%2eopenStore */](EventObjectStoreName, function (storeCtx) {\r\n var request = storeCtx.store.put(dbItem);\r\n request[_DYN_ONSUCCESS /* @min:%2eonsuccess */] = function (evt) {\r\n addEventResolve(dbItem.evt);\r\n };\r\n request[_DYN_ONERROR /* @min:%2eonerror */] = function (evt) {\r\n if (!doRetry) {\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n return;\r\n }\r\n function _retryAddEvent(dropCount) {\r\n if (dropCount === 0) {\r\n // We failed to free up space so just reject\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n }\r\n // Retry sending the event\r\n _addDbEvent(dbCtx, dbItem, false)[_DYN_THEN /* @min:%2ethen */](function (theItem) {\r\n addEventResolve(dbItem.evt); // Resolve the calling add Event promise\r\n }, function () {\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n });\r\n }\r\n dropEvents(function (droppedCount) {\r\n if (droppedCount > 0) {\r\n // We dropped some events so lets try adding the item again\r\n _retryAddEvent(droppedCount);\r\n }\r\n else {\r\n // We have already tried to remove all we can\r\n addEventReject(new Error(ErrorMessageUnableToAddEvent)); // Reject the calling promise\r\n }\r\n });\r\n };\r\n }).catch(function (e) {\r\n addEventReject(e);\r\n });\r\n }\r\n _insertNewEvent();\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * Initializes the provider using the config\r\n * @param providerContext - The provider context that should be used to initialize the provider\r\n * @returns True if the provider is initialized and available for use otherwise false\r\n */\r\n IndexedDbProvider.prototype.initialize = function (providerContext) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n IndexedDbProvider.prototype.supportsSyncRequests = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n IndexedDbProvider.prototype.getNextBatch = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n IndexedDbProvider.prototype.getAllEvents = function (cnt) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param evt - The actual event of the request\r\n * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances\r\n * can optionally use this to access the current core instance or define / pass additional information\r\n * to later plugins (vs appending items to the telemetry item)\r\n */\r\n IndexedDbProvider.prototype.addEvent = function (key, evt, itemCtx) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n IndexedDbProvider.prototype.removeEvents = function (evts) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries from the storage provider, if there are any.\r\n */\r\n IndexedDbProvider.prototype.clear = function (disable) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries with stroage time longer than inStorageMaxTime from the storage provider\r\n */\r\n IndexedDbProvider.prototype.clean = function (disable) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n */\r\n IndexedDbProvider.prototype.teardown = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n return IndexedDbProvider;\r\n}());\r\nexport { IndexedDbProvider };\r\n//# sourceMappingURL=IndexDbProvider.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;yDAqEM,CAAC;;;;;6BACsB;AAC7B;AACA;AACA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.
|
|
2
|
+
* Application Insights JavaScript SDK - Offline Channel, 0.3.5-nightly3.2412-01
|
|
3
3
|
* Copyright (c) Microsoft and contributors. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -112,7 +112,7 @@ function _dropMaxTimeEvents(maxStorageTime, events, eventsToDropAtOneTime, mgr)
|
|
|
112
112
|
var WebStorageProvider = /** @class */ (function () {
|
|
113
113
|
/**
|
|
114
114
|
* Creates a WebStorageProvider using the provider storageType
|
|
115
|
-
* @param storageType The type of Storage provider, normal values are "localStorage" or "sessionStorage"
|
|
115
|
+
* @param storageType - The type of Storage provider, normal values are "localStorage" or "sessionStorage"
|
|
116
116
|
*/
|
|
117
117
|
function WebStorageProvider(storageType, id, unloadHookContainer) {
|
|
118
118
|
dynamicProto(WebStorageProvider, this, function (_this) {
|
|
@@ -361,8 +361,8 @@ var WebStorageProvider = /** @class */ (function () {
|
|
|
361
361
|
* @ignore
|
|
362
362
|
* Creates a new json store with the StorageJSON (may be null), a null db value indicates that the store
|
|
363
363
|
* associated with the key is empty and should be removed.
|
|
364
|
-
* @param dbKey
|
|
365
|
-
* @param
|
|
364
|
+
* @param dbKey - The key to associate with the database
|
|
365
|
+
* @param db - The database
|
|
366
366
|
*/
|
|
367
367
|
function _newStore(dbKey, db) {
|
|
368
368
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebStorageProvider.js.map","sources":["WebStorageProvider.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { getGlobal, getJSON, isNotNullOrUndefined, onConfigChange } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncRejectedPromise } from \"@nevware21/ts-async\";\r\nimport { batchDropNotification, forEachMap, getEndpointDomain, getTimeFromId, getTimeId } from \"../Helpers/Utils\";\r\nimport { PayloadHelper } from \"../PayloadHelper\";\r\nimport { _DYN_ADD_EVENT, _DYN_CLEAR, _DYN_CRITICAL_CNT, _DYN_DIAG_LOG, _DYN_ENDPOINT, _DYN_EVTS, _DYN_GET_NEXT_BATCH, _DYN_GET_TIME, _DYN_INITIALIZE, _DYN_IN_STORAGE_MAX_TIME, _DYN_IS_ARR, _DYN_ITEM_CTX, _DYN_LAST_ACCESS_TIME, _DYN_LENGTH, _DYN_MAX_CRITICAL_EVTS_DR3, _DYN_NAME, _DYN_NOTIFICATION_MGR, _DYN_PUSH, _DYN_REMOVE_EVENTS, _DYN_REMOVE_ITEM, _DYN_STORAGE_CONFIG, _DYN_STORAGE_KEY_PREFIX, _DYN_SUPPORTS_SYNC_REQUES4, _DYN_TEARDOWN, _DYN__EVENTS_TO_DROP_PER_2 } from \"../__DynamicConstants\";\r\n//TODO: move all const to one file\r\nvar EventsToDropAtOneTime = 10;\r\nvar Version = \"1\";\r\nvar DefaultStorageKey = \"AIOffline\";\r\nvar DefaultMaxStorageSizeInBytes = 5000000;\r\nvar MaxCriticalEvtsDropCnt = 2;\r\nvar DefaultMaxInStorageTime = 604800000; //7*24*60*60*1000 7days\r\n// Private helper methods that are not exposed as class methods\r\nfunction _isQuotaExceeded(storage, e) {\r\n var result = false;\r\n if (e instanceof DOMException) {\r\n // test name field too, because code might not be present\r\n if (e.code === 22 || e[_DYN_NAME /* @min:%2ename */] === \"QuotaExceededError\" || // everything except Firefox\r\n e.code === 1014 || e[_DYN_NAME /* @min:%2ename */] === \"NS_ERROR_DOM_QUOTA_REACHED\") { // Firefox\r\n if (storage && storage[_DYN_LENGTH /* @min:%2elength */] !== 0) {\r\n // acknowledge QuotaExceededError only if there's something already stored\r\n result = true;\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n/**\r\n* Check and return that the storage type exists and has space to use\r\n*/\r\nfunction _getAvailableStorage(type) {\r\n var global = getGlobal() || {};\r\n var storage = null;\r\n try {\r\n storage = (global[type]);\r\n if (storage) {\r\n var x = \"__storage_test__\";\r\n storage.setItem(x, x);\r\n storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](x);\r\n }\r\n }\r\n catch (e) {\r\n if (!_isQuotaExceeded(storage, e)) {\r\n // If not Quota exception then assume not available\r\n storage = null;\r\n }\r\n }\r\n return storage;\r\n}\r\n// will drop batches with no critical evts first\r\nfunction _dropEventsUpToPersistence(maxCnt, events, eventsToDropAtOneTime) {\r\n var dropKeys = [];\r\n var persistenceCnt = 0;\r\n var droppedEvents = 0;\r\n while (persistenceCnt <= maxCnt && droppedEvents < eventsToDropAtOneTime) {\r\n forEachMap(events, function (evt, key) {\r\n if (evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] === persistenceCnt) {\r\n dropKeys[_DYN_PUSH /* @min:%2epush */](key);\r\n droppedEvents++;\r\n }\r\n return (droppedEvents < eventsToDropAtOneTime);\r\n });\r\n if (droppedEvents > 0) {\r\n for (var lp = 0; lp < dropKeys[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n delete events[dropKeys[lp]];\r\n }\r\n return droppedEvents;\r\n }\r\n persistenceCnt++;\r\n }\r\n return droppedEvents;\r\n}\r\nfunction _dropMaxTimeEvents(maxStorageTime, events, eventsToDropAtOneTime, mgr) {\r\n var dropKeys = [];\r\n var droppedEvents = 0;\r\n var currentTime = (new Date())[_DYN_GET_TIME /* @min:%2egetTime */]() + 1; // handle appended random float number\r\n var minStartTime = (currentTime - maxStorageTime);\r\n try {\r\n forEachMap(events, function (evt, key) {\r\n var id = getTimeFromId(key);\r\n if (id <= minStartTime) {\r\n dropKeys[_DYN_PUSH /* @min:%2epush */](key);\r\n droppedEvents++;\r\n }\r\n return (droppedEvents < eventsToDropAtOneTime);\r\n });\r\n if (droppedEvents > 0) {\r\n for (var lp = 0; lp < dropKeys[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n delete events[dropKeys[lp]];\r\n }\r\n if (mgr) {\r\n batchDropNotification(mgr, droppedEvents, 3 /* eBatchDiscardedReason.MaxInStorageTimeExceeded */);\r\n }\r\n return true;\r\n }\r\n }\r\n catch (e) {\r\n // catch drop events error\r\n }\r\n return droppedEvents > 0;\r\n}\r\n/**\r\n * Class that implements storing of events using the WebStorage Api ((window||globalThis||self).localstorage, (window||globalThis||self).sessionStorage).\r\n */\r\nvar WebStorageProvider = /** @class */ (function () {\r\n /**\r\n * Creates a WebStorageProvider using the provider storageType\r\n * @param storageType The type of Storage provider, normal values are \"localStorage\" or \"sessionStorage\"\r\n */\r\n function WebStorageProvider(storageType, id, unloadHookContainer) {\r\n dynamicProto(WebStorageProvider, this, function (_this) {\r\n var _storage = null;\r\n var _storageKeyPrefix = DefaultStorageKey;\r\n var _maxStorageSizeInBytes = DefaultMaxStorageSizeInBytes;\r\n var _payloadHelper = null;\r\n var _storageKey = null;\r\n var _endpoint = null;\r\n var _maxStorageTime = null;\r\n var _eventDropPerTime = null;\r\n var _maxCriticalCnt = null;\r\n var _notificationManager = null;\r\n _this.id = id;\r\n _storage = _getAvailableStorage(storageType) || null;\r\n _this[\"_getDbgPlgTargets\"] = function () {\r\n return [_storageKey, _maxStorageSizeInBytes, _maxStorageTime];\r\n };\r\n _this[_DYN_INITIALIZE /* @min:%2einitialize */] = function (providerContext, endpointUrl) {\r\n if (!_storage) {\r\n return false;\r\n }\r\n var storageConfig = providerContext[_DYN_STORAGE_CONFIG /* @min:%2estorageConfig */];\r\n var itemCtx = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */];\r\n _payloadHelper = new PayloadHelper(itemCtx[_DYN_DIAG_LOG /* @min:%2ediagLog */]());\r\n _endpoint = getEndpointDomain(endpointUrl || providerContext[_DYN_ENDPOINT /* @min:%2eendpoint */]);\r\n var autoClean = !!storageConfig.autoClean;\r\n _notificationManager = providerContext[_DYN_NOTIFICATION_MGR /* @min:%2enotificationMgr */];\r\n var unloadHook = onConfigChange(storageConfig, function () {\r\n _maxStorageSizeInBytes = storageConfig.maxStorageSizeInBytes || DefaultMaxStorageSizeInBytes; // value checks and defaults should be applied during core config\r\n _maxStorageTime = storageConfig[_DYN_IN_STORAGE_MAX_TIME /* @min:%2einStorageMaxTime */] || DefaultMaxInStorageTime; // TODO: handle 0\r\n var dropNum = storageConfig[_DYN__EVENTS_TO_DROP_PER_2 /* @min:%2eEventsToDropPerTime */];\r\n _eventDropPerTime = isNotNullOrUndefined(dropNum) ? dropNum : EventsToDropAtOneTime;\r\n _maxCriticalCnt = storageConfig[_DYN_MAX_CRITICAL_EVTS_DR3 /* @min:%2emaxCriticalEvtsDropCnt */] || MaxCriticalEvtsDropCnt;\r\n });\r\n unloadHookContainer && unloadHookContainer.add(unloadHook);\r\n // currently, won't handle endpoint change here\r\n // new endpoint will open a new db\r\n // endpoint change will be handled at offline batch level\r\n // namePrefix should not contain any \"_\"\r\n _storageKeyPrefix = storageConfig[_DYN_STORAGE_KEY_PREFIX /* @min:%2estorageKeyPrefix */] || DefaultStorageKey;\r\n _storageKey = _storageKeyPrefix + \"_\" + Version + \"_\" + _endpoint;\r\n if (autoClean) {\r\n // won't wait response here\r\n _this.clean();\r\n }\r\n // TODO: handle versoin Upgrade\r\n //_checkVersion();\r\n return true;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n _this[_DYN_SUPPORTS_SYNC_REQUES4 /* @min:%2esupportsSyncRequests */] = function () {\r\n return true;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n _this.getAllEvents = function (cnt) {\r\n try {\r\n if (!_storage) {\r\n // if not init, return null\r\n return;\r\n }\r\n return _getEvts(cnt);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Get Next cached event from the storage mechanism\r\n */\r\n _this[_DYN_GET_NEXT_BATCH /* @min:%2egetNextBatch */] = function () {\r\n try {\r\n if (!_storage) {\r\n // if not init, return null\r\n return;\r\n }\r\n // set ordered to true, to make sure to get earliest events first\r\n return _getEvts(1, true);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n function _getEvts(cnt, ordered) {\r\n var allItems = [];\r\n var theStore = _fetchStoredDb(_storageKey).db;\r\n if (theStore) {\r\n var events = theStore[_DYN_EVTS /* @min:%2eevts */];\r\n forEachMap(events, function (evt) {\r\n if (evt) {\r\n if (evt[_DYN_IS_ARR /* @min:%2eisArr */]) {\r\n evt = _payloadHelper.base64ToArr(evt);\r\n }\r\n allItems[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n if (cnt && allItems && allItems[_DYN_LENGTH /* @min:%2elength */] == cnt) {\r\n return false;\r\n }\r\n return true;\r\n }, ordered);\r\n }\r\n return allItems;\r\n }\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param value - The actual value of the request\r\n */\r\n _this[_DYN_ADD_EVENT /* @min:%2eaddEvent */] = function (key, evt, itemCtx) {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey);\r\n evt.id = evt.id || getTimeId();\r\n evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] = evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] || 0;\r\n var events = theStore.db[_DYN_EVTS /* @min:%2eevts */];\r\n var id_1 = evt.id;\r\n if (evt && evt[_DYN_IS_ARR /* @min:%2eisArr */]) {\r\n evt = _payloadHelper.base64ToStr(evt);\r\n }\r\n var preDroppedCnt = 0;\r\n // eslint-disable-next-line no-constant-condition\r\n while (true && evt) {\r\n events[id_1] = evt;\r\n if (_updateStoredDb(theStore)) {\r\n // Database successfully updated\r\n if (preDroppedCnt && _notificationManager) {\r\n // only send notification when batches are updated successfully in storage\r\n batchDropNotification(_notificationManager, preDroppedCnt, 2 /* eBatchDiscardedReason.CleanStorage */);\r\n }\r\n return evt;\r\n }\r\n // Could not not add events to storage assuming its full, so drop events to make space\r\n // or max size exceeded\r\n delete events[id_1];\r\n var droppedCnt = _dropEventsUpToPersistence(_maxCriticalCnt, events, _eventDropPerTime);\r\n preDroppedCnt += droppedCnt;\r\n if (!droppedCnt) {\r\n // Can't free any space for event\r\n return createAsyncRejectedPromise(new Error(\"Unable to free up event space\"));\r\n }\r\n }\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n _this[_DYN_REMOVE_EVENTS /* @min:%2eremoveEvents */] = function (evts) {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var currentDb = theStore.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n for (var i = 0; i < evts[_DYN_LENGTH /* @min:%2elength */]; ++i) {\r\n var evt = evts[i];\r\n delete events[evt.id];\r\n }\r\n // Update takes care of removing the DB if it's completely empty now\r\n if (_updateStoredDb(theStore)) {\r\n return evts;\r\n }\r\n }\r\n catch (e) {\r\n // Storage corrupted\r\n }\r\n // failure here so try and remove db to unblock following events\r\n evts = _clearDatabase(theStore.key);\r\n }\r\n return evts;\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Removes all entries from the storage provider for the current endpoint and returns them as part of the response, if there are any.\r\n */\r\n _this[_DYN_CLEAR /* @min:%2eclear */] = function () {\r\n try {\r\n var removedItems_1 = [];\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var storedDb = theStore.db;\r\n if (storedDb) {\r\n var events_1 = storedDb[_DYN_EVTS /* @min:%2eevts */];\r\n forEachMap(events_1, function (evt) {\r\n if (evt) {\r\n delete events_1[evt.id];\r\n removedItems_1[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n return true;\r\n });\r\n _updateStoredDb(theStore);\r\n }\r\n return removedItems_1;\r\n }\r\n catch (e) {\r\n // Unable to clear the database\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n _this.clean = function () {\r\n var storeDetails = _fetchStoredDb(_storageKey, false);\r\n var currentDb = storeDetails.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n var isDropped = _dropMaxTimeEvents(_maxStorageTime, events, _eventDropPerTime, _notificationManager);\r\n if (isDropped) {\r\n return _updateStoredDb(storeDetails);\r\n }\r\n return true;\r\n }\r\n catch (e) {\r\n // should not throw errors here\r\n // because we don't want to block following process\r\n }\r\n return false;\r\n }\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n * This attempts to update the lastAccessTime for any storedDb\r\n */\r\n _this[_DYN_TEARDOWN /* @min:%2eteardown */] = function () {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var storedDb = theStore.db;\r\n if (storedDb) {\r\n // reset the last access time\r\n storedDb[_DYN_LAST_ACCESS_TIME /* @min:%2elastAccessTime */] = 0;\r\n _updateStoredDb(theStore, false);\r\n }\r\n }\r\n catch (e) {\r\n // Add diagnostic logging\r\n }\r\n };\r\n /**\r\n * @ignore\r\n * Creates a new json store with the StorageJSON (may be null), a null db value indicates that the store\r\n * associated with the key is empty and should be removed.\r\n * @param dbKey\r\n * @param forceRemove\r\n */\r\n function _newStore(dbKey, db) {\r\n return {\r\n key: dbKey,\r\n db: db\r\n };\r\n }\r\n function _fetchStoredDb(dbKey, returnDefault) {\r\n var _a;\r\n if (returnDefault === void 0) { returnDefault = true; }\r\n var dbToStore = null;\r\n if (_storage) {\r\n var previousDb = _storage.getItem(dbKey);\r\n if (previousDb) {\r\n try {\r\n dbToStore = getJSON().parse(previousDb);\r\n }\r\n catch (e) {\r\n // storage corrupted\r\n _storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](dbKey);\r\n }\r\n }\r\n if (returnDefault && !dbToStore) {\r\n // Create and return a default empty database\r\n dbToStore = (_a = {\r\n evts: {}\r\n },\r\n _a[_DYN_LAST_ACCESS_TIME /* @min:lastAccessTime */] = 0,\r\n _a);\r\n }\r\n }\r\n return _newStore(dbKey, dbToStore);\r\n }\r\n function _updateStoredDb(jsonStore, updateLastAccessTime) {\r\n if (updateLastAccessTime === void 0) { updateLastAccessTime = true; }\r\n //let removeDb = true;\r\n var dbToStore = jsonStore.db;\r\n if (dbToStore) {\r\n if (updateLastAccessTime) {\r\n // Update the last access time\r\n dbToStore.lastAccessTime = (new Date())[_DYN_GET_TIME /* @min:%2egetTime */]();\r\n }\r\n }\r\n try {\r\n var jsonString = getJSON().stringify(dbToStore);\r\n if (jsonString[_DYN_LENGTH /* @min:%2elength */] > _maxStorageSizeInBytes) {\r\n // We can't store the database as it would exceed the configured max size\r\n return false;\r\n }\r\n _storage && _storage.setItem(jsonStore.key, jsonString);\r\n //}\r\n }\r\n catch (e) {\r\n // catch exception due to trying to store or clear JSON\r\n // We could not store the database\r\n return false;\r\n }\r\n return true;\r\n }\r\n function _clearDatabase(dbKey) {\r\n var removedItems = [];\r\n var storeDetails = _fetchStoredDb(dbKey, false);\r\n var currentDb = storeDetails.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n forEachMap(events, function (evt) {\r\n if (evt) {\r\n removedItems[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n return true;\r\n });\r\n }\r\n catch (e) {\r\n // catch exception due to trying to store or clear JSON\r\n }\r\n // Remove the entire stored database\r\n _storage && _storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](storeDetails.key);\r\n }\r\n return removedItems;\r\n }\r\n });\r\n }\r\n /**\r\n * Initializes the provider using the config\r\n * @param providerContext The provider context that should be used to initialize the provider\r\n * @returns True if the provider is initialized and available for use otherwise false\r\n */\r\n WebStorageProvider.prototype.initialize = function (providerContext) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n WebStorageProvider.prototype.supportsSyncRequests = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n WebStorageProvider.prototype.getAllEvents = function (cnt) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Get the Next one cached batch from the storage mechanism\r\n */\r\n WebStorageProvider.prototype.getNextBatch = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param evt - The actual event of the request\r\n * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances\r\n * can optionally use this to access the current core instance or define / pass additional information\r\n * to later plugins (vs appending items to the telemetry item)\r\n */\r\n WebStorageProvider.prototype.addEvent = function (key, evt, itemCtx) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n WebStorageProvider.prototype.removeEvents = function (evts) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries from the storage provider, if there are any.\r\n */\r\n WebStorageProvider.prototype.clear = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries with stroage time longer than inStorageMaxTime from the storage provider\r\n */\r\n WebStorageProvider.prototype.clean = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n */\r\n WebStorageProvider.prototype.teardown = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n return WebStorageProvider;\r\n}());\r\nexport { WebStorageProvider };\r\n//# sourceMappingURL=WebStorageProvider.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;0DAqEM,CAAC;;;;;8BACuB;AAC9B;AACA;AACA"}
|
|
1
|
+
{"version":3,"file":"WebStorageProvider.js.map","sources":["WebStorageProvider.js"],"sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT License.\r\nimport dynamicProto from \"@microsoft/dynamicproto-js\";\r\nimport { getGlobal, getJSON, isNotNullOrUndefined, onConfigChange } from \"@microsoft/applicationinsights-core-js\";\r\nimport { createAsyncRejectedPromise } from \"@nevware21/ts-async\";\r\nimport { batchDropNotification, forEachMap, getEndpointDomain, getTimeFromId, getTimeId } from \"../Helpers/Utils\";\r\nimport { PayloadHelper } from \"../PayloadHelper\";\r\nimport { _DYN_ADD_EVENT, _DYN_CLEAR, _DYN_CRITICAL_CNT, _DYN_DIAG_LOG, _DYN_ENDPOINT, _DYN_EVTS, _DYN_GET_NEXT_BATCH, _DYN_GET_TIME, _DYN_INITIALIZE, _DYN_IN_STORAGE_MAX_TIME, _DYN_IS_ARR, _DYN_ITEM_CTX, _DYN_LAST_ACCESS_TIME, _DYN_LENGTH, _DYN_MAX_CRITICAL_EVTS_DR3, _DYN_NAME, _DYN_NOTIFICATION_MGR, _DYN_PUSH, _DYN_REMOVE_EVENTS, _DYN_REMOVE_ITEM, _DYN_STORAGE_CONFIG, _DYN_STORAGE_KEY_PREFIX, _DYN_SUPPORTS_SYNC_REQUES4, _DYN_TEARDOWN, _DYN__EVENTS_TO_DROP_PER_2 } from \"../__DynamicConstants\";\r\n//TODO: move all const to one file\r\nvar EventsToDropAtOneTime = 10;\r\nvar Version = \"1\";\r\nvar DefaultStorageKey = \"AIOffline\";\r\nvar DefaultMaxStorageSizeInBytes = 5000000;\r\nvar MaxCriticalEvtsDropCnt = 2;\r\nvar DefaultMaxInStorageTime = 604800000; //7*24*60*60*1000 7days\r\n// Private helper methods that are not exposed as class methods\r\nfunction _isQuotaExceeded(storage, e) {\r\n var result = false;\r\n if (e instanceof DOMException) {\r\n // test name field too, because code might not be present\r\n if (e.code === 22 || e[_DYN_NAME /* @min:%2ename */] === \"QuotaExceededError\" || // everything except Firefox\r\n e.code === 1014 || e[_DYN_NAME /* @min:%2ename */] === \"NS_ERROR_DOM_QUOTA_REACHED\") { // Firefox\r\n if (storage && storage[_DYN_LENGTH /* @min:%2elength */] !== 0) {\r\n // acknowledge QuotaExceededError only if there's something already stored\r\n result = true;\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n/**\r\n* Check and return that the storage type exists and has space to use\r\n*/\r\nfunction _getAvailableStorage(type) {\r\n var global = getGlobal() || {};\r\n var storage = null;\r\n try {\r\n storage = (global[type]);\r\n if (storage) {\r\n var x = \"__storage_test__\";\r\n storage.setItem(x, x);\r\n storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](x);\r\n }\r\n }\r\n catch (e) {\r\n if (!_isQuotaExceeded(storage, e)) {\r\n // If not Quota exception then assume not available\r\n storage = null;\r\n }\r\n }\r\n return storage;\r\n}\r\n// will drop batches with no critical evts first\r\nfunction _dropEventsUpToPersistence(maxCnt, events, eventsToDropAtOneTime) {\r\n var dropKeys = [];\r\n var persistenceCnt = 0;\r\n var droppedEvents = 0;\r\n while (persistenceCnt <= maxCnt && droppedEvents < eventsToDropAtOneTime) {\r\n forEachMap(events, function (evt, key) {\r\n if (evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] === persistenceCnt) {\r\n dropKeys[_DYN_PUSH /* @min:%2epush */](key);\r\n droppedEvents++;\r\n }\r\n return (droppedEvents < eventsToDropAtOneTime);\r\n });\r\n if (droppedEvents > 0) {\r\n for (var lp = 0; lp < dropKeys[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n delete events[dropKeys[lp]];\r\n }\r\n return droppedEvents;\r\n }\r\n persistenceCnt++;\r\n }\r\n return droppedEvents;\r\n}\r\nfunction _dropMaxTimeEvents(maxStorageTime, events, eventsToDropAtOneTime, mgr) {\r\n var dropKeys = [];\r\n var droppedEvents = 0;\r\n var currentTime = (new Date())[_DYN_GET_TIME /* @min:%2egetTime */]() + 1; // handle appended random float number\r\n var minStartTime = (currentTime - maxStorageTime);\r\n try {\r\n forEachMap(events, function (evt, key) {\r\n var id = getTimeFromId(key);\r\n if (id <= minStartTime) {\r\n dropKeys[_DYN_PUSH /* @min:%2epush */](key);\r\n droppedEvents++;\r\n }\r\n return (droppedEvents < eventsToDropAtOneTime);\r\n });\r\n if (droppedEvents > 0) {\r\n for (var lp = 0; lp < dropKeys[_DYN_LENGTH /* @min:%2elength */]; lp++) {\r\n delete events[dropKeys[lp]];\r\n }\r\n if (mgr) {\r\n batchDropNotification(mgr, droppedEvents, 3 /* eBatchDiscardedReason.MaxInStorageTimeExceeded */);\r\n }\r\n return true;\r\n }\r\n }\r\n catch (e) {\r\n // catch drop events error\r\n }\r\n return droppedEvents > 0;\r\n}\r\n/**\r\n * Class that implements storing of events using the WebStorage Api ((window||globalThis||self).localstorage, (window||globalThis||self).sessionStorage).\r\n */\r\nvar WebStorageProvider = /** @class */ (function () {\r\n /**\r\n * Creates a WebStorageProvider using the provider storageType\r\n * @param storageType - The type of Storage provider, normal values are \"localStorage\" or \"sessionStorage\"\r\n */\r\n function WebStorageProvider(storageType, id, unloadHookContainer) {\r\n dynamicProto(WebStorageProvider, this, function (_this) {\r\n var _storage = null;\r\n var _storageKeyPrefix = DefaultStorageKey;\r\n var _maxStorageSizeInBytes = DefaultMaxStorageSizeInBytes;\r\n var _payloadHelper = null;\r\n var _storageKey = null;\r\n var _endpoint = null;\r\n var _maxStorageTime = null;\r\n var _eventDropPerTime = null;\r\n var _maxCriticalCnt = null;\r\n var _notificationManager = null;\r\n _this.id = id;\r\n _storage = _getAvailableStorage(storageType) || null;\r\n _this[\"_getDbgPlgTargets\"] = function () {\r\n return [_storageKey, _maxStorageSizeInBytes, _maxStorageTime];\r\n };\r\n _this[_DYN_INITIALIZE /* @min:%2einitialize */] = function (providerContext, endpointUrl) {\r\n if (!_storage) {\r\n return false;\r\n }\r\n var storageConfig = providerContext[_DYN_STORAGE_CONFIG /* @min:%2estorageConfig */];\r\n var itemCtx = providerContext[_DYN_ITEM_CTX /* @min:%2eitemCtx */];\r\n _payloadHelper = new PayloadHelper(itemCtx[_DYN_DIAG_LOG /* @min:%2ediagLog */]());\r\n _endpoint = getEndpointDomain(endpointUrl || providerContext[_DYN_ENDPOINT /* @min:%2eendpoint */]);\r\n var autoClean = !!storageConfig.autoClean;\r\n _notificationManager = providerContext[_DYN_NOTIFICATION_MGR /* @min:%2enotificationMgr */];\r\n var unloadHook = onConfigChange(storageConfig, function () {\r\n _maxStorageSizeInBytes = storageConfig.maxStorageSizeInBytes || DefaultMaxStorageSizeInBytes; // value checks and defaults should be applied during core config\r\n _maxStorageTime = storageConfig[_DYN_IN_STORAGE_MAX_TIME /* @min:%2einStorageMaxTime */] || DefaultMaxInStorageTime; // TODO: handle 0\r\n var dropNum = storageConfig[_DYN__EVENTS_TO_DROP_PER_2 /* @min:%2eEventsToDropPerTime */];\r\n _eventDropPerTime = isNotNullOrUndefined(dropNum) ? dropNum : EventsToDropAtOneTime;\r\n _maxCriticalCnt = storageConfig[_DYN_MAX_CRITICAL_EVTS_DR3 /* @min:%2emaxCriticalEvtsDropCnt */] || MaxCriticalEvtsDropCnt;\r\n });\r\n unloadHookContainer && unloadHookContainer.add(unloadHook);\r\n // currently, won't handle endpoint change here\r\n // new endpoint will open a new db\r\n // endpoint change will be handled at offline batch level\r\n // namePrefix should not contain any \"_\"\r\n _storageKeyPrefix = storageConfig[_DYN_STORAGE_KEY_PREFIX /* @min:%2estorageKeyPrefix */] || DefaultStorageKey;\r\n _storageKey = _storageKeyPrefix + \"_\" + Version + \"_\" + _endpoint;\r\n if (autoClean) {\r\n // won't wait response here\r\n _this.clean();\r\n }\r\n // TODO: handle versoin Upgrade\r\n //_checkVersion();\r\n return true;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n _this[_DYN_SUPPORTS_SYNC_REQUES4 /* @min:%2esupportsSyncRequests */] = function () {\r\n return true;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n _this.getAllEvents = function (cnt) {\r\n try {\r\n if (!_storage) {\r\n // if not init, return null\r\n return;\r\n }\r\n return _getEvts(cnt);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Get Next cached event from the storage mechanism\r\n */\r\n _this[_DYN_GET_NEXT_BATCH /* @min:%2egetNextBatch */] = function () {\r\n try {\r\n if (!_storage) {\r\n // if not init, return null\r\n return;\r\n }\r\n // set ordered to true, to make sure to get earliest events first\r\n return _getEvts(1, true);\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n function _getEvts(cnt, ordered) {\r\n var allItems = [];\r\n var theStore = _fetchStoredDb(_storageKey).db;\r\n if (theStore) {\r\n var events = theStore[_DYN_EVTS /* @min:%2eevts */];\r\n forEachMap(events, function (evt) {\r\n if (evt) {\r\n if (evt[_DYN_IS_ARR /* @min:%2eisArr */]) {\r\n evt = _payloadHelper.base64ToArr(evt);\r\n }\r\n allItems[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n if (cnt && allItems && allItems[_DYN_LENGTH /* @min:%2elength */] == cnt) {\r\n return false;\r\n }\r\n return true;\r\n }, ordered);\r\n }\r\n return allItems;\r\n }\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param value - The actual value of the request\r\n */\r\n _this[_DYN_ADD_EVENT /* @min:%2eaddEvent */] = function (key, evt, itemCtx) {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey);\r\n evt.id = evt.id || getTimeId();\r\n evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] = evt[_DYN_CRITICAL_CNT /* @min:%2ecriticalCnt */] || 0;\r\n var events = theStore.db[_DYN_EVTS /* @min:%2eevts */];\r\n var id_1 = evt.id;\r\n if (evt && evt[_DYN_IS_ARR /* @min:%2eisArr */]) {\r\n evt = _payloadHelper.base64ToStr(evt);\r\n }\r\n var preDroppedCnt = 0;\r\n // eslint-disable-next-line no-constant-condition\r\n while (true && evt) {\r\n events[id_1] = evt;\r\n if (_updateStoredDb(theStore)) {\r\n // Database successfully updated\r\n if (preDroppedCnt && _notificationManager) {\r\n // only send notification when batches are updated successfully in storage\r\n batchDropNotification(_notificationManager, preDroppedCnt, 2 /* eBatchDiscardedReason.CleanStorage */);\r\n }\r\n return evt;\r\n }\r\n // Could not not add events to storage assuming its full, so drop events to make space\r\n // or max size exceeded\r\n delete events[id_1];\r\n var droppedCnt = _dropEventsUpToPersistence(_maxCriticalCnt, events, _eventDropPerTime);\r\n preDroppedCnt += droppedCnt;\r\n if (!droppedCnt) {\r\n // Can't free any space for event\r\n return createAsyncRejectedPromise(new Error(\"Unable to free up event space\"));\r\n }\r\n }\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n _this[_DYN_REMOVE_EVENTS /* @min:%2eremoveEvents */] = function (evts) {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var currentDb = theStore.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n for (var i = 0; i < evts[_DYN_LENGTH /* @min:%2elength */]; ++i) {\r\n var evt = evts[i];\r\n delete events[evt.id];\r\n }\r\n // Update takes care of removing the DB if it's completely empty now\r\n if (_updateStoredDb(theStore)) {\r\n return evts;\r\n }\r\n }\r\n catch (e) {\r\n // Storage corrupted\r\n }\r\n // failure here so try and remove db to unblock following events\r\n evts = _clearDatabase(theStore.key);\r\n }\r\n return evts;\r\n }\r\n catch (e) {\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n /**\r\n * Removes all entries from the storage provider for the current endpoint and returns them as part of the response, if there are any.\r\n */\r\n _this[_DYN_CLEAR /* @min:%2eclear */] = function () {\r\n try {\r\n var removedItems_1 = [];\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var storedDb = theStore.db;\r\n if (storedDb) {\r\n var events_1 = storedDb[_DYN_EVTS /* @min:%2eevts */];\r\n forEachMap(events_1, function (evt) {\r\n if (evt) {\r\n delete events_1[evt.id];\r\n removedItems_1[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n return true;\r\n });\r\n _updateStoredDb(theStore);\r\n }\r\n return removedItems_1;\r\n }\r\n catch (e) {\r\n // Unable to clear the database\r\n return createAsyncRejectedPromise(e);\r\n }\r\n };\r\n _this.clean = function () {\r\n var storeDetails = _fetchStoredDb(_storageKey, false);\r\n var currentDb = storeDetails.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n var isDropped = _dropMaxTimeEvents(_maxStorageTime, events, _eventDropPerTime, _notificationManager);\r\n if (isDropped) {\r\n return _updateStoredDb(storeDetails);\r\n }\r\n return true;\r\n }\r\n catch (e) {\r\n // should not throw errors here\r\n // because we don't want to block following process\r\n }\r\n return false;\r\n }\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n * This attempts to update the lastAccessTime for any storedDb\r\n */\r\n _this[_DYN_TEARDOWN /* @min:%2eteardown */] = function () {\r\n try {\r\n var theStore = _fetchStoredDb(_storageKey, false);\r\n var storedDb = theStore.db;\r\n if (storedDb) {\r\n // reset the last access time\r\n storedDb[_DYN_LAST_ACCESS_TIME /* @min:%2elastAccessTime */] = 0;\r\n _updateStoredDb(theStore, false);\r\n }\r\n }\r\n catch (e) {\r\n // Add diagnostic logging\r\n }\r\n };\r\n /**\r\n * @ignore\r\n * Creates a new json store with the StorageJSON (may be null), a null db value indicates that the store\r\n * associated with the key is empty and should be removed.\r\n * @param dbKey - The key to associate with the database\r\n * @param db - The database\r\n */\r\n function _newStore(dbKey, db) {\r\n return {\r\n key: dbKey,\r\n db: db\r\n };\r\n }\r\n function _fetchStoredDb(dbKey, returnDefault) {\r\n var _a;\r\n if (returnDefault === void 0) { returnDefault = true; }\r\n var dbToStore = null;\r\n if (_storage) {\r\n var previousDb = _storage.getItem(dbKey);\r\n if (previousDb) {\r\n try {\r\n dbToStore = getJSON().parse(previousDb);\r\n }\r\n catch (e) {\r\n // storage corrupted\r\n _storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](dbKey);\r\n }\r\n }\r\n if (returnDefault && !dbToStore) {\r\n // Create and return a default empty database\r\n dbToStore = (_a = {\r\n evts: {}\r\n },\r\n _a[_DYN_LAST_ACCESS_TIME /* @min:lastAccessTime */] = 0,\r\n _a);\r\n }\r\n }\r\n return _newStore(dbKey, dbToStore);\r\n }\r\n function _updateStoredDb(jsonStore, updateLastAccessTime) {\r\n if (updateLastAccessTime === void 0) { updateLastAccessTime = true; }\r\n //let removeDb = true;\r\n var dbToStore = jsonStore.db;\r\n if (dbToStore) {\r\n if (updateLastAccessTime) {\r\n // Update the last access time\r\n dbToStore.lastAccessTime = (new Date())[_DYN_GET_TIME /* @min:%2egetTime */]();\r\n }\r\n }\r\n try {\r\n var jsonString = getJSON().stringify(dbToStore);\r\n if (jsonString[_DYN_LENGTH /* @min:%2elength */] > _maxStorageSizeInBytes) {\r\n // We can't store the database as it would exceed the configured max size\r\n return false;\r\n }\r\n _storage && _storage.setItem(jsonStore.key, jsonString);\r\n //}\r\n }\r\n catch (e) {\r\n // catch exception due to trying to store or clear JSON\r\n // We could not store the database\r\n return false;\r\n }\r\n return true;\r\n }\r\n function _clearDatabase(dbKey) {\r\n var removedItems = [];\r\n var storeDetails = _fetchStoredDb(dbKey, false);\r\n var currentDb = storeDetails.db;\r\n if (currentDb) {\r\n var events = currentDb[_DYN_EVTS /* @min:%2eevts */];\r\n try {\r\n forEachMap(events, function (evt) {\r\n if (evt) {\r\n removedItems[_DYN_PUSH /* @min:%2epush */](evt);\r\n }\r\n return true;\r\n });\r\n }\r\n catch (e) {\r\n // catch exception due to trying to store or clear JSON\r\n }\r\n // Remove the entire stored database\r\n _storage && _storage[_DYN_REMOVE_ITEM /* @min:%2eremoveItem */](storeDetails.key);\r\n }\r\n return removedItems;\r\n }\r\n });\r\n }\r\n /**\r\n * Initializes the provider using the config\r\n * @param providerContext The provider context that should be used to initialize the provider\r\n * @returns True if the provider is initialized and available for use otherwise false\r\n */\r\n WebStorageProvider.prototype.initialize = function (providerContext) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Identifies whether this storage provider support synchronous requests\r\n */\r\n WebStorageProvider.prototype.supportsSyncRequests = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return false;\r\n };\r\n /**\r\n * Get all of the currently cached events from the storage mechanism\r\n */\r\n WebStorageProvider.prototype.getAllEvents = function (cnt) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Get the Next one cached batch from the storage mechanism\r\n */\r\n WebStorageProvider.prototype.getNextBatch = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return null;\r\n };\r\n /**\r\n * Stores the value into the storage using the specified key.\r\n * @param key - The key value to use for the value\r\n * @param evt - The actual event of the request\r\n * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances\r\n * can optionally use this to access the current core instance or define / pass additional information\r\n * to later plugins (vs appending items to the telemetry item)\r\n */\r\n WebStorageProvider.prototype.addEvent = function (key, evt, itemCtx) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes the value associated with the provided key\r\n * @param evts - The events to be removed\r\n */\r\n WebStorageProvider.prototype.removeEvents = function (evts) {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries from the storage provider, if there are any.\r\n */\r\n WebStorageProvider.prototype.clear = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Removes all entries with stroage time longer than inStorageMaxTime from the storage provider\r\n */\r\n WebStorageProvider.prototype.clean = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n return;\r\n };\r\n /**\r\n * Shuts-down the telemetry plugin. This is usually called when telemetry is shut down.\r\n */\r\n WebStorageProvider.prototype.teardown = function () {\r\n // @DynamicProtoStub - DO NOT add any code as this will be removed during packaging\r\n };\r\n return WebStorageProvider;\r\n}());\r\nexport { WebStorageProvider };\r\n//# sourceMappingURL=WebStorageProvider.js.map"],"names":[],"mappings":";;;;AAA4D;AAC1B;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;0DAqEM,CAAC;;;;;8BACuB;AAC9B;AACA;AACA"}
|
package/dist-es5/Sender.js
CHANGED