@amplitude/analytics-core 2.24.1 → 2.26.0
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/lib/cjs/diagnostics/diagnostics-client.d.ts +156 -0
- package/lib/cjs/diagnostics/diagnostics-client.d.ts.map +1 -0
- package/lib/cjs/diagnostics/diagnostics-client.js +305 -0
- package/lib/cjs/diagnostics/diagnostics-client.js.map +1 -0
- package/lib/cjs/diagnostics/diagnostics-storage.d.ts +123 -0
- package/lib/cjs/diagnostics/diagnostics-storage.d.ts.map +1 -0
- package/lib/cjs/diagnostics/diagnostics-storage.js +492 -0
- package/lib/cjs/diagnostics/diagnostics-storage.js.map +1 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/types/config/core-config.d.ts +5 -0
- package/lib/cjs/types/config/core-config.d.ts.map +1 -1
- package/lib/cjs/types/config/core-config.js.map +1 -1
- package/lib/esm/diagnostics/diagnostics-client.d.ts +156 -0
- package/lib/esm/diagnostics/diagnostics-client.d.ts.map +1 -0
- package/lib/esm/diagnostics/diagnostics-client.js +302 -0
- package/lib/esm/diagnostics/diagnostics-client.js.map +1 -0
- package/lib/esm/diagnostics/diagnostics-storage.d.ts +123 -0
- package/lib/esm/diagnostics/diagnostics-storage.d.ts.map +1 -0
- package/lib/esm/diagnostics/diagnostics-storage.js +489 -0
- package/lib/esm/diagnostics/diagnostics-storage.js.map +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/types/config/core-config.d.ts +5 -0
- package/lib/esm/types/config/core-config.d.ts.map +1 -1
- package/lib/esm/types/config/core-config.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ILogger } from '../logger';
|
|
2
|
+
import { HistogramStats } from './diagnostics-client';
|
|
3
|
+
export declare const TABLE_NAMES: {
|
|
4
|
+
readonly TAGS: "tags";
|
|
5
|
+
readonly COUNTERS: "counters";
|
|
6
|
+
readonly HISTOGRAMS: "histograms";
|
|
7
|
+
readonly EVENTS: "events";
|
|
8
|
+
readonly INTERNAL: "internal";
|
|
9
|
+
};
|
|
10
|
+
export declare const INTERNAL_KEYS: {
|
|
11
|
+
readonly LAST_FLUSH_TIMESTAMP: "last_flush_timestamp";
|
|
12
|
+
};
|
|
13
|
+
export interface TagRecord {
|
|
14
|
+
key: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CounterRecord {
|
|
18
|
+
key: string;
|
|
19
|
+
value: number;
|
|
20
|
+
}
|
|
21
|
+
export interface HistogramRecord {
|
|
22
|
+
key: string;
|
|
23
|
+
count: number;
|
|
24
|
+
min: number;
|
|
25
|
+
max: number;
|
|
26
|
+
sum: number;
|
|
27
|
+
}
|
|
28
|
+
export interface EventRecord {
|
|
29
|
+
id?: number;
|
|
30
|
+
event_name: string;
|
|
31
|
+
time: number;
|
|
32
|
+
event_properties: Record<string, any>;
|
|
33
|
+
}
|
|
34
|
+
export interface InternalRecord {
|
|
35
|
+
key: string;
|
|
36
|
+
value: string;
|
|
37
|
+
}
|
|
38
|
+
export interface IDiagnosticsStorage {
|
|
39
|
+
/**
|
|
40
|
+
* Set multiple tags in a single transaction (batch operation)
|
|
41
|
+
* Promise never rejects - errors are logged and operation continues gracefully
|
|
42
|
+
*/
|
|
43
|
+
setTags(tags: Record<string, string>): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Increment multiple counters in a single transaction (batch operation)
|
|
46
|
+
* Uses read-modify-write pattern to accumulate with existing values
|
|
47
|
+
* Promise never rejects - errors are logged and operation continues gracefully
|
|
48
|
+
*/
|
|
49
|
+
incrementCounters(counters: Record<string, number>): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Set multiple histogram stats in a single transaction (batch operation)
|
|
52
|
+
* Uses read-modify-write pattern to accumulate count/sum and update min/max with existing values
|
|
53
|
+
* Promise never rejects - errors are logged and operation continues gracefully
|
|
54
|
+
*/
|
|
55
|
+
setHistogramStats(histogramStats: Record<string, {
|
|
56
|
+
count: number;
|
|
57
|
+
min: number;
|
|
58
|
+
max: number;
|
|
59
|
+
sum: number;
|
|
60
|
+
}>): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Add multiple event records in a single transaction (batch operation)
|
|
63
|
+
* Promise never rejects - errors are logged and operation continues gracefully
|
|
64
|
+
*/
|
|
65
|
+
addEventRecords(events: Array<{
|
|
66
|
+
event_name: string;
|
|
67
|
+
time: number;
|
|
68
|
+
event_properties: Record<string, any>;
|
|
69
|
+
}>): Promise<void>;
|
|
70
|
+
setLastFlushTimestamp(timestamp: number): Promise<void>;
|
|
71
|
+
getLastFlushTimestamp(): Promise<number | undefined>;
|
|
72
|
+
/**
|
|
73
|
+
* Get all data except internal data from storage and clear it
|
|
74
|
+
*/
|
|
75
|
+
getAllAndClear(): Promise<{
|
|
76
|
+
tags: TagRecord[];
|
|
77
|
+
counters: CounterRecord[];
|
|
78
|
+
histogramStats: HistogramRecord[];
|
|
79
|
+
events: EventRecord[];
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Purpose-specific IndexedDB storage for diagnostics data
|
|
84
|
+
* Provides optimized methods for each type of diagnostics data
|
|
85
|
+
*/
|
|
86
|
+
export declare class DiagnosticsStorage implements IDiagnosticsStorage {
|
|
87
|
+
dbPromise: Promise<IDBDatabase> | null;
|
|
88
|
+
dbName: string;
|
|
89
|
+
logger: ILogger;
|
|
90
|
+
constructor(apiKey: string, logger: ILogger);
|
|
91
|
+
/**
|
|
92
|
+
* Check if IndexedDB is supported in the current environment
|
|
93
|
+
* @returns true if IndexedDB is available, false otherwise
|
|
94
|
+
*/
|
|
95
|
+
static isSupported(): boolean;
|
|
96
|
+
getDB(): Promise<IDBDatabase>;
|
|
97
|
+
openDB(): Promise<IDBDatabase>;
|
|
98
|
+
createTables(db: IDBDatabase): void;
|
|
99
|
+
setTags(tags: Record<string, string>): Promise<void>;
|
|
100
|
+
incrementCounters(counters: Record<string, number>): Promise<void>;
|
|
101
|
+
setHistogramStats(histogramStats: Record<string, HistogramStats>): Promise<void>;
|
|
102
|
+
addEventRecords(events: Array<{
|
|
103
|
+
event_name: string;
|
|
104
|
+
time: number;
|
|
105
|
+
event_properties: Record<string, any>;
|
|
106
|
+
}>): Promise<void>;
|
|
107
|
+
setInternal(key: string, value: string): Promise<void>;
|
|
108
|
+
getInternal(key: string): Promise<InternalRecord | undefined>;
|
|
109
|
+
getLastFlushTimestamp(): Promise<number | undefined>;
|
|
110
|
+
setLastFlushTimestamp(timestamp: number): Promise<void>;
|
|
111
|
+
clearTable(transaction: IDBTransaction, tableName: string): Promise<void>;
|
|
112
|
+
getAllAndClear(): Promise<{
|
|
113
|
+
tags: TagRecord[];
|
|
114
|
+
counters: CounterRecord[];
|
|
115
|
+
histogramStats: HistogramRecord[];
|
|
116
|
+
events: EventRecord[];
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Helper method to get all records from a store within a transaction
|
|
120
|
+
*/
|
|
121
|
+
private getAllFromStore;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=diagnostics-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics-storage.d.ts","sourceRoot":"","sources":["../../../src/diagnostics/diagnostics-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD,eAAO,MAAM,WAAW;;;;;;CAMd,CAAC;AAGX,eAAO,MAAM,aAAa;;CAEhB,CAAC;AAGX,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD;;;;OAIG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE;;;;OAIG;IACH,iBAAiB,CACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GACvF,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;OAGG;IACH,eAAe,CACb,MAAM,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAC,GACzF,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAErD;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC;QACxB,IAAI,EAAE,SAAS,EAAE,CAAC;QAClB,QAAQ,EAAE,aAAa,EAAE,CAAC;QAC1B,cAAc,EAAE,eAAe,EAAE,CAAC;QAClC,MAAM,EAAE,WAAW,EAAE,CAAC;KACvB,CAAC,CAAC;CACJ;AAED;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAQ;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;gBAEJ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAK3C;;;OAGG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;IAIvB,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IAOnC,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC;IAgC9B,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI;IAmC7B,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+ClE,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoEhF,eAAe,CACnB,MAAM,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAC,GACzF,OAAO,CAAC,IAAI,CAAC;IAuDV,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBtD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAuB7D,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAYpD,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,UAAU,CAAC,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnE,cAAc,IAAI,OAAO,CAAC;QAC9B,IAAI,EAAE,SAAS,EAAE,CAAC;QAClB,QAAQ,EAAE,aAAa,EAAE,CAAC;QAC1B,cAAc,EAAE,eAAe,EAAE,CAAC;QAClC,MAAM,EAAE,WAAW,EAAE,CAAC;KACvB,CAAC;IA8BF;;OAEG;IAEH,OAAO,CAAC,eAAe;CASxB"}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { __awaiter, __generator, __read } from "tslib";
|
|
2
|
+
import { getGlobalScope } from '../global-scope';
|
|
3
|
+
var MAX_PERSISTENT_STORAGE_EVENTS_COUNT = 10;
|
|
4
|
+
// Database configuration
|
|
5
|
+
var DB_VERSION = 1;
|
|
6
|
+
// Table names for different diagnostics types
|
|
7
|
+
export var TABLE_NAMES = {
|
|
8
|
+
TAGS: 'tags',
|
|
9
|
+
COUNTERS: 'counters',
|
|
10
|
+
HISTOGRAMS: 'histograms',
|
|
11
|
+
EVENTS: 'events',
|
|
12
|
+
INTERNAL: 'internal', // New table for internal storage like flush timestamps
|
|
13
|
+
};
|
|
14
|
+
// Keys for internal storage table
|
|
15
|
+
export var INTERNAL_KEYS = {
|
|
16
|
+
LAST_FLUSH_TIMESTAMP: 'last_flush_timestamp',
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Purpose-specific IndexedDB storage for diagnostics data
|
|
20
|
+
* Provides optimized methods for each type of diagnostics data
|
|
21
|
+
*/
|
|
22
|
+
var DiagnosticsStorage = /** @class */ (function () {
|
|
23
|
+
function DiagnosticsStorage(apiKey, logger) {
|
|
24
|
+
this.dbPromise = null;
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
this.dbName = "AMP_diagnostics_".concat(apiKey.substring(0, 10));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if IndexedDB is supported in the current environment
|
|
30
|
+
* @returns true if IndexedDB is available, false otherwise
|
|
31
|
+
*/
|
|
32
|
+
DiagnosticsStorage.isSupported = function () {
|
|
33
|
+
var _a;
|
|
34
|
+
return ((_a = getGlobalScope()) === null || _a === void 0 ? void 0 : _a.indexedDB) !== undefined;
|
|
35
|
+
};
|
|
36
|
+
DiagnosticsStorage.prototype.getDB = function () {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
38
|
+
return __generator(this, function (_a) {
|
|
39
|
+
if (!this.dbPromise) {
|
|
40
|
+
this.dbPromise = this.openDB();
|
|
41
|
+
}
|
|
42
|
+
return [2 /*return*/, this.dbPromise];
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
DiagnosticsStorage.prototype.openDB = function () {
|
|
47
|
+
var _this = this;
|
|
48
|
+
return new Promise(function (resolve, reject) {
|
|
49
|
+
var request = indexedDB.open(_this.dbName, DB_VERSION);
|
|
50
|
+
request.onerror = function () {
|
|
51
|
+
// Clear dbPromise when it rejects for the first time
|
|
52
|
+
_this.dbPromise = null;
|
|
53
|
+
reject(new Error('Failed to open IndexedDB'));
|
|
54
|
+
};
|
|
55
|
+
request.onsuccess = function () {
|
|
56
|
+
var db = request.result;
|
|
57
|
+
// Clear dbPromise when connection was on but went off later
|
|
58
|
+
db.onclose = function () {
|
|
59
|
+
_this.dbPromise = null;
|
|
60
|
+
_this.logger.debug('DiagnosticsStorage: DB connection closed.');
|
|
61
|
+
};
|
|
62
|
+
db.onerror = function (event) {
|
|
63
|
+
_this.logger.debug('DiagnosticsStorage: A global database error occurred.', event);
|
|
64
|
+
db.close();
|
|
65
|
+
};
|
|
66
|
+
resolve(db);
|
|
67
|
+
};
|
|
68
|
+
request.onupgradeneeded = function (event) {
|
|
69
|
+
var db = event.target.result;
|
|
70
|
+
_this.createTables(db);
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
DiagnosticsStorage.prototype.createTables = function (db) {
|
|
75
|
+
// Create tags table
|
|
76
|
+
if (!db.objectStoreNames.contains(TABLE_NAMES.TAGS)) {
|
|
77
|
+
db.createObjectStore(TABLE_NAMES.TAGS, { keyPath: 'key' });
|
|
78
|
+
}
|
|
79
|
+
// Create counters table
|
|
80
|
+
if (!db.objectStoreNames.contains(TABLE_NAMES.COUNTERS)) {
|
|
81
|
+
db.createObjectStore(TABLE_NAMES.COUNTERS, { keyPath: 'key' });
|
|
82
|
+
}
|
|
83
|
+
// Create histograms table for storing histogram stats (count, min, max, sum)
|
|
84
|
+
if (!db.objectStoreNames.contains(TABLE_NAMES.HISTOGRAMS)) {
|
|
85
|
+
db.createObjectStore(TABLE_NAMES.HISTOGRAMS, {
|
|
86
|
+
keyPath: 'key',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Create events table
|
|
90
|
+
if (!db.objectStoreNames.contains(TABLE_NAMES.EVENTS)) {
|
|
91
|
+
var eventsStore = db.createObjectStore(TABLE_NAMES.EVENTS, {
|
|
92
|
+
keyPath: 'id',
|
|
93
|
+
autoIncrement: true,
|
|
94
|
+
});
|
|
95
|
+
// Create index on time for chronological queries
|
|
96
|
+
eventsStore.createIndex('time_idx', 'time', { unique: false });
|
|
97
|
+
}
|
|
98
|
+
// Create internal table for storing internal data like flush timestamps
|
|
99
|
+
if (!db.objectStoreNames.contains(TABLE_NAMES.INTERNAL)) {
|
|
100
|
+
db.createObjectStore(TABLE_NAMES.INTERNAL, { keyPath: 'key' });
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
DiagnosticsStorage.prototype.setTags = function (tags) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
105
|
+
var db, transaction_1, store_1, error_1;
|
|
106
|
+
var _this = this;
|
|
107
|
+
return __generator(this, function (_a) {
|
|
108
|
+
switch (_a.label) {
|
|
109
|
+
case 0:
|
|
110
|
+
_a.trys.push([0, 2, , 3]);
|
|
111
|
+
if (Object.entries(tags).length === 0) {
|
|
112
|
+
return [2 /*return*/];
|
|
113
|
+
}
|
|
114
|
+
return [4 /*yield*/, this.getDB()];
|
|
115
|
+
case 1:
|
|
116
|
+
db = _a.sent();
|
|
117
|
+
transaction_1 = db.transaction([TABLE_NAMES.TAGS], 'readwrite');
|
|
118
|
+
store_1 = transaction_1.objectStore(TABLE_NAMES.TAGS);
|
|
119
|
+
return [2 /*return*/, new Promise(function (resolve) {
|
|
120
|
+
var entries = Object.entries(tags);
|
|
121
|
+
transaction_1.oncomplete = function () {
|
|
122
|
+
resolve();
|
|
123
|
+
};
|
|
124
|
+
transaction_1.onabort = function (event) {
|
|
125
|
+
_this.logger.debug('DiagnosticsStorage: Failed to set tags', event);
|
|
126
|
+
resolve();
|
|
127
|
+
};
|
|
128
|
+
entries.forEach(function (_a) {
|
|
129
|
+
var _b = __read(_a, 2), key = _b[0], value = _b[1];
|
|
130
|
+
var putRequest = store_1.put({ key: key, value: value });
|
|
131
|
+
putRequest.onerror = function (event) {
|
|
132
|
+
_this.logger.debug('DiagnosticsStorage: Failed to set tag', key, value, event);
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
})];
|
|
136
|
+
case 2:
|
|
137
|
+
error_1 = _a.sent();
|
|
138
|
+
this.logger.debug('DiagnosticsStorage: Failed to set tags', error_1);
|
|
139
|
+
return [3 /*break*/, 3];
|
|
140
|
+
case 3: return [2 /*return*/];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
DiagnosticsStorage.prototype.incrementCounters = function (counters) {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
147
|
+
var db, transaction_2, store_2, error_2;
|
|
148
|
+
var _this = this;
|
|
149
|
+
return __generator(this, function (_a) {
|
|
150
|
+
switch (_a.label) {
|
|
151
|
+
case 0:
|
|
152
|
+
_a.trys.push([0, 2, , 3]);
|
|
153
|
+
if (Object.entries(counters).length === 0) {
|
|
154
|
+
return [2 /*return*/];
|
|
155
|
+
}
|
|
156
|
+
return [4 /*yield*/, this.getDB()];
|
|
157
|
+
case 1:
|
|
158
|
+
db = _a.sent();
|
|
159
|
+
transaction_2 = db.transaction([TABLE_NAMES.COUNTERS], 'readwrite');
|
|
160
|
+
store_2 = transaction_2.objectStore(TABLE_NAMES.COUNTERS);
|
|
161
|
+
return [2 /*return*/, new Promise(function (resolve) {
|
|
162
|
+
var entries = Object.entries(counters);
|
|
163
|
+
transaction_2.oncomplete = function () {
|
|
164
|
+
resolve();
|
|
165
|
+
};
|
|
166
|
+
transaction_2.onabort = function (event) {
|
|
167
|
+
_this.logger.debug('DiagnosticsStorage: Failed to increment counters', event);
|
|
168
|
+
resolve();
|
|
169
|
+
};
|
|
170
|
+
// Read existing values and update them
|
|
171
|
+
entries.forEach(function (_a) {
|
|
172
|
+
var _b = __read(_a, 2), key = _b[0], incrementValue = _b[1];
|
|
173
|
+
var getRequest = store_2.get(key);
|
|
174
|
+
getRequest.onsuccess = function () {
|
|
175
|
+
var existingRecord = getRequest.result;
|
|
176
|
+
/* istanbul ignore next */
|
|
177
|
+
var existingValue = existingRecord ? existingRecord.value : 0;
|
|
178
|
+
var putRequest = store_2.put({ key: key, value: existingValue + incrementValue });
|
|
179
|
+
putRequest.onerror = function (event) {
|
|
180
|
+
_this.logger.debug('DiagnosticsStorage: Failed to update counter', key, event);
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
getRequest.onerror = function (event) {
|
|
184
|
+
_this.logger.debug('DiagnosticsStorage: Failed to read existing counter', key, event);
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
})];
|
|
188
|
+
case 2:
|
|
189
|
+
error_2 = _a.sent();
|
|
190
|
+
this.logger.debug('DiagnosticsStorage: Failed to increment counters', error_2);
|
|
191
|
+
return [3 /*break*/, 3];
|
|
192
|
+
case 3: return [2 /*return*/];
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
DiagnosticsStorage.prototype.setHistogramStats = function (histogramStats) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
199
|
+
var db, transaction_3, store_3, error_3;
|
|
200
|
+
var _this = this;
|
|
201
|
+
return __generator(this, function (_a) {
|
|
202
|
+
switch (_a.label) {
|
|
203
|
+
case 0:
|
|
204
|
+
_a.trys.push([0, 2, , 3]);
|
|
205
|
+
if (Object.entries(histogramStats).length === 0) {
|
|
206
|
+
return [2 /*return*/];
|
|
207
|
+
}
|
|
208
|
+
return [4 /*yield*/, this.getDB()];
|
|
209
|
+
case 1:
|
|
210
|
+
db = _a.sent();
|
|
211
|
+
transaction_3 = db.transaction([TABLE_NAMES.HISTOGRAMS], 'readwrite');
|
|
212
|
+
store_3 = transaction_3.objectStore(TABLE_NAMES.HISTOGRAMS);
|
|
213
|
+
return [2 /*return*/, new Promise(function (resolve) {
|
|
214
|
+
var entries = Object.entries(histogramStats);
|
|
215
|
+
transaction_3.oncomplete = function () {
|
|
216
|
+
resolve();
|
|
217
|
+
};
|
|
218
|
+
transaction_3.onabort = function (event) {
|
|
219
|
+
_this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', event);
|
|
220
|
+
resolve();
|
|
221
|
+
};
|
|
222
|
+
// Read existing values and update them
|
|
223
|
+
entries.forEach(function (_a) {
|
|
224
|
+
var _b = __read(_a, 2), key = _b[0], newStats = _b[1];
|
|
225
|
+
var getRequest = store_3.get(key);
|
|
226
|
+
getRequest.onsuccess = function () {
|
|
227
|
+
var existingRecord = getRequest.result;
|
|
228
|
+
var updatedStats;
|
|
229
|
+
/* istanbul ignore next */
|
|
230
|
+
if (existingRecord) {
|
|
231
|
+
// Accumulate with existing stats
|
|
232
|
+
updatedStats = {
|
|
233
|
+
key: key,
|
|
234
|
+
count: existingRecord.count + newStats.count,
|
|
235
|
+
min: Math.min(existingRecord.min, newStats.min),
|
|
236
|
+
max: Math.max(existingRecord.max, newStats.max),
|
|
237
|
+
sum: existingRecord.sum + newStats.sum,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Create new stats
|
|
242
|
+
updatedStats = {
|
|
243
|
+
key: key,
|
|
244
|
+
count: newStats.count,
|
|
245
|
+
min: newStats.min,
|
|
246
|
+
max: newStats.max,
|
|
247
|
+
sum: newStats.sum,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
var putRequest = store_3.put(updatedStats);
|
|
251
|
+
putRequest.onerror = function (event) {
|
|
252
|
+
_this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', key, event);
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
getRequest.onerror = function (event) {
|
|
256
|
+
_this.logger.debug('DiagnosticsStorage: Failed to read existing histogram stats', key, event);
|
|
257
|
+
};
|
|
258
|
+
});
|
|
259
|
+
})];
|
|
260
|
+
case 2:
|
|
261
|
+
error_3 = _a.sent();
|
|
262
|
+
this.logger.debug('DiagnosticsStorage: Failed to set histogram stats', error_3);
|
|
263
|
+
return [3 /*break*/, 3];
|
|
264
|
+
case 3: return [2 /*return*/];
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
DiagnosticsStorage.prototype.addEventRecords = function (events) {
|
|
270
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
271
|
+
var db, transaction_4, store_4, error_4;
|
|
272
|
+
var _this = this;
|
|
273
|
+
return __generator(this, function (_a) {
|
|
274
|
+
switch (_a.label) {
|
|
275
|
+
case 0:
|
|
276
|
+
_a.trys.push([0, 2, , 3]);
|
|
277
|
+
if (events.length === 0) {
|
|
278
|
+
return [2 /*return*/];
|
|
279
|
+
}
|
|
280
|
+
return [4 /*yield*/, this.getDB()];
|
|
281
|
+
case 1:
|
|
282
|
+
db = _a.sent();
|
|
283
|
+
transaction_4 = db.transaction([TABLE_NAMES.EVENTS], 'readwrite');
|
|
284
|
+
store_4 = transaction_4.objectStore(TABLE_NAMES.EVENTS);
|
|
285
|
+
return [2 /*return*/, new Promise(function (resolve) {
|
|
286
|
+
transaction_4.oncomplete = function () {
|
|
287
|
+
resolve();
|
|
288
|
+
};
|
|
289
|
+
/* istanbul ignore next */
|
|
290
|
+
transaction_4.onabort = function (event) {
|
|
291
|
+
_this.logger.debug('DiagnosticsStorage: Failed to add event records', event);
|
|
292
|
+
resolve();
|
|
293
|
+
};
|
|
294
|
+
// First, check how many events are currently stored
|
|
295
|
+
var countRequest = store_4.count();
|
|
296
|
+
countRequest.onsuccess = function () {
|
|
297
|
+
var currentCount = countRequest.result;
|
|
298
|
+
// Calculate how many events we can add
|
|
299
|
+
var availableSlots = Math.max(0, MAX_PERSISTENT_STORAGE_EVENTS_COUNT - currentCount);
|
|
300
|
+
if (availableSlots < events.length) {
|
|
301
|
+
_this.logger.debug("DiagnosticsStorage: Only added ".concat(availableSlots, " of ").concat(events.length, " events due to storage limit"));
|
|
302
|
+
}
|
|
303
|
+
// Only add events up to the available slots (take the least recent ones)
|
|
304
|
+
events.slice(0, availableSlots).forEach(function (event) {
|
|
305
|
+
var request = store_4.add(event);
|
|
306
|
+
request.onerror = function (event) {
|
|
307
|
+
_this.logger.debug('DiagnosticsStorage: Failed to add event record', event);
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
countRequest.onerror = function (event) {
|
|
312
|
+
_this.logger.debug('DiagnosticsStorage: Failed to count existing events', event);
|
|
313
|
+
};
|
|
314
|
+
})];
|
|
315
|
+
case 2:
|
|
316
|
+
error_4 = _a.sent();
|
|
317
|
+
this.logger.debug('DiagnosticsStorage: Failed to add event records', error_4);
|
|
318
|
+
return [3 /*break*/, 3];
|
|
319
|
+
case 3: return [2 /*return*/];
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
DiagnosticsStorage.prototype.setInternal = function (key, value) {
|
|
325
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
326
|
+
var db, transaction_5, store_5, error_5;
|
|
327
|
+
return __generator(this, function (_a) {
|
|
328
|
+
switch (_a.label) {
|
|
329
|
+
case 0:
|
|
330
|
+
_a.trys.push([0, 2, , 3]);
|
|
331
|
+
return [4 /*yield*/, this.getDB()];
|
|
332
|
+
case 1:
|
|
333
|
+
db = _a.sent();
|
|
334
|
+
transaction_5 = db.transaction([TABLE_NAMES.INTERNAL], 'readwrite');
|
|
335
|
+
store_5 = transaction_5.objectStore(TABLE_NAMES.INTERNAL);
|
|
336
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
337
|
+
/* istanbul ignore next */
|
|
338
|
+
transaction_5.onabort = function () { return reject(new Error('Failed to set internal value')); };
|
|
339
|
+
var request = store_5.put({ key: key, value: value });
|
|
340
|
+
request.onsuccess = function () { return resolve(); };
|
|
341
|
+
/* istanbul ignore next */
|
|
342
|
+
request.onerror = function () { return reject(new Error('Failed to set internal value')); };
|
|
343
|
+
})];
|
|
344
|
+
case 2:
|
|
345
|
+
error_5 = _a.sent();
|
|
346
|
+
/* istanbul ignore next */
|
|
347
|
+
this.logger.debug('DiagnosticsStorage: Failed to set internal value', error_5);
|
|
348
|
+
return [3 /*break*/, 3];
|
|
349
|
+
case 3: return [2 /*return*/];
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
};
|
|
354
|
+
DiagnosticsStorage.prototype.getInternal = function (key) {
|
|
355
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
356
|
+
var db, transaction_6, store_6, error_6;
|
|
357
|
+
return __generator(this, function (_a) {
|
|
358
|
+
switch (_a.label) {
|
|
359
|
+
case 0:
|
|
360
|
+
_a.trys.push([0, 2, , 3]);
|
|
361
|
+
return [4 /*yield*/, this.getDB()];
|
|
362
|
+
case 1:
|
|
363
|
+
db = _a.sent();
|
|
364
|
+
transaction_6 = db.transaction([TABLE_NAMES.INTERNAL], 'readonly');
|
|
365
|
+
store_6 = transaction_6.objectStore(TABLE_NAMES.INTERNAL);
|
|
366
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
367
|
+
/* istanbul ignore next */
|
|
368
|
+
transaction_6.onabort = function () { return reject(new Error('Failed to get internal value')); };
|
|
369
|
+
var request = store_6.get(key);
|
|
370
|
+
request.onsuccess = function () { return resolve(request.result); };
|
|
371
|
+
/* istanbul ignore next */
|
|
372
|
+
request.onerror = function () { return reject(new Error('Failed to get internal value')); };
|
|
373
|
+
})];
|
|
374
|
+
case 2:
|
|
375
|
+
error_6 = _a.sent();
|
|
376
|
+
this.logger.debug('DiagnosticsStorage: Failed to get internal value', error_6);
|
|
377
|
+
return [2 /*return*/, undefined];
|
|
378
|
+
case 3: return [2 /*return*/];
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
DiagnosticsStorage.prototype.getLastFlushTimestamp = function () {
|
|
384
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
385
|
+
var record, error_7;
|
|
386
|
+
return __generator(this, function (_a) {
|
|
387
|
+
switch (_a.label) {
|
|
388
|
+
case 0:
|
|
389
|
+
_a.trys.push([0, 2, , 3]);
|
|
390
|
+
return [4 /*yield*/, this.getInternal(INTERNAL_KEYS.LAST_FLUSH_TIMESTAMP)];
|
|
391
|
+
case 1:
|
|
392
|
+
record = _a.sent();
|
|
393
|
+
return [2 /*return*/, record ? parseInt(record.value, 10) : undefined];
|
|
394
|
+
case 2:
|
|
395
|
+
error_7 = _a.sent();
|
|
396
|
+
/* istanbul ignore next */
|
|
397
|
+
this.logger.debug('DiagnosticsStorage: Failed to get last flush timestamp', error_7);
|
|
398
|
+
/* istanbul ignore next */
|
|
399
|
+
return [2 /*return*/, undefined];
|
|
400
|
+
case 3: return [2 /*return*/];
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
DiagnosticsStorage.prototype.setLastFlushTimestamp = function (timestamp) {
|
|
406
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
407
|
+
var error_8;
|
|
408
|
+
return __generator(this, function (_a) {
|
|
409
|
+
switch (_a.label) {
|
|
410
|
+
case 0:
|
|
411
|
+
_a.trys.push([0, 2, , 3]);
|
|
412
|
+
return [4 /*yield*/, this.setInternal(INTERNAL_KEYS.LAST_FLUSH_TIMESTAMP, timestamp.toString())];
|
|
413
|
+
case 1:
|
|
414
|
+
_a.sent();
|
|
415
|
+
return [3 /*break*/, 3];
|
|
416
|
+
case 2:
|
|
417
|
+
error_8 = _a.sent();
|
|
418
|
+
/* istanbul ignore next */
|
|
419
|
+
this.logger.debug('DiagnosticsStorage: Failed to set last flush timestamp', error_8);
|
|
420
|
+
return [3 /*break*/, 3];
|
|
421
|
+
case 3: return [2 /*return*/];
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
};
|
|
426
|
+
/* istanbul ignore next */
|
|
427
|
+
DiagnosticsStorage.prototype.clearTable = function (transaction, tableName) {
|
|
428
|
+
return new Promise(function (resolve, reject) {
|
|
429
|
+
var store = transaction.objectStore(tableName);
|
|
430
|
+
var request = store.clear();
|
|
431
|
+
request.onsuccess = function () { return resolve(); };
|
|
432
|
+
request.onerror = function () { return reject(new Error("Failed to clear table ".concat(tableName))); };
|
|
433
|
+
});
|
|
434
|
+
};
|
|
435
|
+
/* istanbul ignore next */
|
|
436
|
+
DiagnosticsStorage.prototype.getAllAndClear = function () {
|
|
437
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
438
|
+
var db, transaction, _a, tags, counters, histogramStats, events, error_9;
|
|
439
|
+
return __generator(this, function (_b) {
|
|
440
|
+
switch (_b.label) {
|
|
441
|
+
case 0:
|
|
442
|
+
_b.trys.push([0, 4, , 5]);
|
|
443
|
+
return [4 /*yield*/, this.getDB()];
|
|
444
|
+
case 1:
|
|
445
|
+
db = _b.sent();
|
|
446
|
+
transaction = db.transaction([TABLE_NAMES.TAGS, TABLE_NAMES.COUNTERS, TABLE_NAMES.HISTOGRAMS, TABLE_NAMES.EVENTS], 'readwrite');
|
|
447
|
+
return [4 /*yield*/, Promise.all([
|
|
448
|
+
this.getAllFromStore(transaction, TABLE_NAMES.TAGS),
|
|
449
|
+
this.getAllFromStore(transaction, TABLE_NAMES.COUNTERS),
|
|
450
|
+
this.getAllFromStore(transaction, TABLE_NAMES.HISTOGRAMS),
|
|
451
|
+
this.getAllFromStore(transaction, TABLE_NAMES.EVENTS),
|
|
452
|
+
])];
|
|
453
|
+
case 2:
|
|
454
|
+
_a = __read.apply(void 0, [_b.sent(), 4]), tags = _a[0], counters = _a[1], histogramStats = _a[2], events = _a[3];
|
|
455
|
+
// Clear all data in the same transaction
|
|
456
|
+
return [4 /*yield*/, Promise.all([
|
|
457
|
+
this.clearTable(transaction, TABLE_NAMES.COUNTERS),
|
|
458
|
+
this.clearTable(transaction, TABLE_NAMES.HISTOGRAMS),
|
|
459
|
+
this.clearTable(transaction, TABLE_NAMES.EVENTS),
|
|
460
|
+
])];
|
|
461
|
+
case 3:
|
|
462
|
+
// Clear all data in the same transaction
|
|
463
|
+
_b.sent();
|
|
464
|
+
return [2 /*return*/, { tags: tags, counters: counters, histogramStats: histogramStats, events: events }];
|
|
465
|
+
case 4:
|
|
466
|
+
error_9 = _b.sent();
|
|
467
|
+
this.logger.debug('DiagnosticsStorage: Failed to get all and clear data', error_9);
|
|
468
|
+
return [2 /*return*/, { tags: [], counters: [], histogramStats: [], events: [] }];
|
|
469
|
+
case 5: return [2 /*return*/];
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
* Helper method to get all records from a store within a transaction
|
|
476
|
+
*/
|
|
477
|
+
/* istanbul ignore next */
|
|
478
|
+
DiagnosticsStorage.prototype.getAllFromStore = function (transaction, tableName) {
|
|
479
|
+
return new Promise(function (resolve, reject) {
|
|
480
|
+
var store = transaction.objectStore(tableName);
|
|
481
|
+
var request = store.getAll();
|
|
482
|
+
request.onsuccess = function () { return resolve(request.result); };
|
|
483
|
+
request.onerror = function () { return reject(new Error("Failed to get all from ".concat(tableName))); };
|
|
484
|
+
});
|
|
485
|
+
};
|
|
486
|
+
return DiagnosticsStorage;
|
|
487
|
+
}());
|
|
488
|
+
export { DiagnosticsStorage };
|
|
489
|
+
//# sourceMappingURL=diagnostics-storage.js.map
|