ultimatedarktower 2.5.0 → 4.0.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/README.md +84 -71
  3. package/dist/esm/index.mjs +1270 -268
  4. package/dist/src/UltimateDarkTower.d.ts +48 -6
  5. package/dist/src/UltimateDarkTower.js +115 -53
  6. package/dist/src/UltimateDarkTower.js.map +1 -1
  7. package/dist/src/adapters/NodeBluetoothAdapter.js +9 -5
  8. package/dist/src/adapters/NodeBluetoothAdapter.js.map +1 -1
  9. package/dist/src/adapters/WebBluetoothAdapter.js +11 -8
  10. package/dist/src/adapters/WebBluetoothAdapter.js.map +1 -1
  11. package/dist/src/index.d.ts +8 -0
  12. package/dist/src/index.js +34 -1
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/sinks/IndexedDBSink.d.ts +26 -0
  15. package/dist/src/sinks/IndexedDBSink.js +165 -0
  16. package/dist/src/sinks/IndexedDBSink.js.map +1 -0
  17. package/dist/src/udtBleConnection.d.ts +28 -5
  18. package/dist/src/udtBleConnection.js +80 -13
  19. package/dist/src/udtBleConnection.js.map +1 -1
  20. package/dist/src/udtBluetoothAdapter.d.ts +6 -6
  21. package/dist/src/udtBluetoothAdapter.js.map +1 -1
  22. package/dist/src/udtCommandFactory.d.ts +6 -0
  23. package/dist/src/udtCommandFactory.js +26 -22
  24. package/dist/src/udtCommandFactory.js.map +1 -1
  25. package/dist/src/udtCommandQueue.d.ts +6 -3
  26. package/dist/src/udtCommandQueue.js +28 -5
  27. package/dist/src/udtCommandQueue.js.map +1 -1
  28. package/dist/src/udtConstants.d.ts +3 -8
  29. package/dist/src/udtConstants.js +2 -0
  30. package/dist/src/udtConstants.js.map +1 -1
  31. package/dist/src/udtDiagnostics.d.ts +122 -0
  32. package/dist/src/udtDiagnostics.js +228 -0
  33. package/dist/src/udtDiagnostics.js.map +1 -0
  34. package/dist/src/udtGameBoard.d.ts +38 -0
  35. package/dist/src/udtGameBoard.js +86 -0
  36. package/dist/src/udtGameBoard.js.map +1 -0
  37. package/dist/src/udtLogger.d.ts +16 -0
  38. package/dist/src/udtLogger.js +41 -2
  39. package/dist/src/udtLogger.js.map +1 -1
  40. package/dist/src/udtSeedParser.d.ts +124 -0
  41. package/dist/src/udtSeedParser.js +369 -0
  42. package/dist/src/udtSeedParser.js.map +1 -0
  43. package/dist/src/udtSystemRandom.d.ts +58 -0
  44. package/dist/src/udtSystemRandom.js +154 -0
  45. package/dist/src/udtSystemRandom.js.map +1 -0
  46. package/dist/src/udtTowerCommands.d.ts +4 -2
  47. package/dist/src/udtTowerCommands.js +24 -43
  48. package/dist/src/udtTowerCommands.js.map +1 -1
  49. package/dist/src/udtTowerResponse.d.ts +9 -5
  50. package/dist/src/udtTowerResponse.js +5 -6
  51. package/dist/src/udtTowerResponse.js.map +1 -1
  52. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WebBluetoothAdapter.js","sourceRoot":"","sources":["../../../src/adapters/WebBluetoothAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WebBluetoothAdapter.js","sourceRoot":"","sources":["../../../src/adapters/WebBluetoothAdapter.ts"],"names":[],"mappings":"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"}
@@ -15,5 +15,13 @@ export { rtdt_unpack_state, rtdt_pack_state, isCalibrated } from './udtTowerStat
15
15
  export { createDefaultTowerState, parseDifferentialReadings, type ParsedDifferentialReadings } from './udtHelpers';
16
16
  export type { TowerResponseConfig } from './udtTowerResponse';
17
17
  export type { TowerEventCallbacks, DeviceInformation, ConnectionStatus } from './udtBleConnection';
18
+ export { UdtDiagnosticsRecorder, InMemorySink, bytesToHex } from './udtDiagnostics';
19
+ export type { DiagnosticsConfig, DiagnosticsSink, DiagEvent, DiagEventKind, DisconnectCause, IncidentReport, BatterySample, CommandQueueSnapshot, } from './udtDiagnostics';
20
+ export { IndexedDBSink } from './sinks/IndexedDBSink';
21
+ export { charToValue, valueToChar, validateSeed, decodeSeed, decodeRngSeed, createSeed, encodeSeed, compareSeedsRaw, dumpSeedChars, TIER1_FOES, TIER2_FOES, TIER3_FOES, ADVERSARIES, ALLIES, DIFFICULTIES, GAME_SOURCES, } from './udtSeedParser';
22
+ export type { Tier1Foe, Tier2Foe, Tier3Foe, Adversary, Ally, Difficulty, GameSource, ExpansionType, Confidence, SeedBank, DecodedSeed, SeedConfig, CharDiff, SeedComparison, CharInfo, CharDump, } from './udtSeedParser';
23
+ export { SystemRandom } from './udtSystemRandom';
24
+ export { BOARD_LOCATIONS, BOARD_LOCATION_BY_NAME, BOARD_GROUPINGS, } from './udtGameBoard';
25
+ export type { TerrainType, BuildingType, BoardKingdom, BoardGrouping, BoardLocation } from './udtGameBoard';
18
26
  import UltimateDarkTower from './UltimateDarkTower';
19
27
  export default UltimateDarkTower;
package/dist/src/index.js CHANGED
@@ -21,7 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  return (mod && mod.__esModule) ? mod : { "default": mod };
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.parseDifferentialReadings = exports.createDefaultTowerState = exports.isCalibrated = exports.rtdt_pack_state = exports.rtdt_unpack_state = exports.BluetoothAdapterFactory = exports.BluetoothPlatform = exports.BluetoothTimeoutError = exports.BluetoothUserCancelledError = exports.BluetoothDeviceNotFoundError = exports.BluetoothConnectionError = exports.BluetoothError = exports.milliVoltsToPercentageNumber = exports.milliVoltsToPercentage = exports.BufferOutput = exports.DOMOutput = exports.ConsoleOutput = exports.Logger = exports.logger = exports.UltimateDarkTower = void 0;
24
+ exports.BOARD_GROUPINGS = exports.BOARD_LOCATION_BY_NAME = exports.BOARD_LOCATIONS = exports.SystemRandom = exports.GAME_SOURCES = exports.DIFFICULTIES = exports.ALLIES = exports.ADVERSARIES = exports.TIER3_FOES = exports.TIER2_FOES = exports.TIER1_FOES = exports.dumpSeedChars = exports.compareSeedsRaw = exports.encodeSeed = exports.createSeed = exports.decodeRngSeed = exports.decodeSeed = exports.validateSeed = exports.valueToChar = exports.charToValue = exports.IndexedDBSink = exports.bytesToHex = exports.InMemorySink = exports.UdtDiagnosticsRecorder = exports.parseDifferentialReadings = exports.createDefaultTowerState = exports.isCalibrated = exports.rtdt_pack_state = exports.rtdt_unpack_state = exports.BluetoothAdapterFactory = exports.BluetoothPlatform = exports.BluetoothTimeoutError = exports.BluetoothUserCancelledError = exports.BluetoothDeviceNotFoundError = exports.BluetoothConnectionError = exports.BluetoothError = exports.milliVoltsToPercentageNumber = exports.milliVoltsToPercentage = exports.BufferOutput = exports.DOMOutput = exports.ConsoleOutput = exports.Logger = exports.logger = exports.UltimateDarkTower = void 0;
25
25
  var UltimateDarkTower_1 = require("./UltimateDarkTower");
26
26
  Object.defineProperty(exports, "UltimateDarkTower", { enumerable: true, get: function () { return __importDefault(UltimateDarkTower_1).default; } });
27
27
  __exportStar(require("./udtConstants"), exports);
@@ -50,6 +50,39 @@ Object.defineProperty(exports, "isCalibrated", { enumerable: true, get: function
50
50
  var udtHelpers_2 = require("./udtHelpers");
51
51
  Object.defineProperty(exports, "createDefaultTowerState", { enumerable: true, get: function () { return udtHelpers_2.createDefaultTowerState; } });
52
52
  Object.defineProperty(exports, "parseDifferentialReadings", { enumerable: true, get: function () { return udtHelpers_2.parseDifferentialReadings; } });
53
+ // BLE disconnect diagnostics ("flight recorder") - off by default, see docs/BLE_DIAGNOSTICS.md
54
+ var udtDiagnostics_1 = require("./udtDiagnostics");
55
+ Object.defineProperty(exports, "UdtDiagnosticsRecorder", { enumerable: true, get: function () { return udtDiagnostics_1.UdtDiagnosticsRecorder; } });
56
+ Object.defineProperty(exports, "InMemorySink", { enumerable: true, get: function () { return udtDiagnostics_1.InMemorySink; } });
57
+ Object.defineProperty(exports, "bytesToHex", { enumerable: true, get: function () { return udtDiagnostics_1.bytesToHex; } });
58
+ var IndexedDBSink_1 = require("./sinks/IndexedDBSink");
59
+ Object.defineProperty(exports, "IndexedDBSink", { enumerable: true, get: function () { return IndexedDBSink_1.IndexedDBSink; } });
60
+ // Seed parser
61
+ var udtSeedParser_1 = require("./udtSeedParser");
62
+ Object.defineProperty(exports, "charToValue", { enumerable: true, get: function () { return udtSeedParser_1.charToValue; } });
63
+ Object.defineProperty(exports, "valueToChar", { enumerable: true, get: function () { return udtSeedParser_1.valueToChar; } });
64
+ Object.defineProperty(exports, "validateSeed", { enumerable: true, get: function () { return udtSeedParser_1.validateSeed; } });
65
+ Object.defineProperty(exports, "decodeSeed", { enumerable: true, get: function () { return udtSeedParser_1.decodeSeed; } });
66
+ Object.defineProperty(exports, "decodeRngSeed", { enumerable: true, get: function () { return udtSeedParser_1.decodeRngSeed; } });
67
+ Object.defineProperty(exports, "createSeed", { enumerable: true, get: function () { return udtSeedParser_1.createSeed; } });
68
+ Object.defineProperty(exports, "encodeSeed", { enumerable: true, get: function () { return udtSeedParser_1.encodeSeed; } });
69
+ Object.defineProperty(exports, "compareSeedsRaw", { enumerable: true, get: function () { return udtSeedParser_1.compareSeedsRaw; } });
70
+ Object.defineProperty(exports, "dumpSeedChars", { enumerable: true, get: function () { return udtSeedParser_1.dumpSeedChars; } });
71
+ Object.defineProperty(exports, "TIER1_FOES", { enumerable: true, get: function () { return udtSeedParser_1.TIER1_FOES; } });
72
+ Object.defineProperty(exports, "TIER2_FOES", { enumerable: true, get: function () { return udtSeedParser_1.TIER2_FOES; } });
73
+ Object.defineProperty(exports, "TIER3_FOES", { enumerable: true, get: function () { return udtSeedParser_1.TIER3_FOES; } });
74
+ Object.defineProperty(exports, "ADVERSARIES", { enumerable: true, get: function () { return udtSeedParser_1.ADVERSARIES; } });
75
+ Object.defineProperty(exports, "ALLIES", { enumerable: true, get: function () { return udtSeedParser_1.ALLIES; } });
76
+ Object.defineProperty(exports, "DIFFICULTIES", { enumerable: true, get: function () { return udtSeedParser_1.DIFFICULTIES; } });
77
+ Object.defineProperty(exports, "GAME_SOURCES", { enumerable: true, get: function () { return udtSeedParser_1.GAME_SOURCES; } });
78
+ // System.Random replica (C# PRNG)
79
+ var udtSystemRandom_1 = require("./udtSystemRandom");
80
+ Object.defineProperty(exports, "SystemRandom", { enumerable: true, get: function () { return udtSystemRandom_1.SystemRandom; } });
81
+ // Game board data
82
+ var udtGameBoard_1 = require("./udtGameBoard");
83
+ Object.defineProperty(exports, "BOARD_LOCATIONS", { enumerable: true, get: function () { return udtGameBoard_1.BOARD_LOCATIONS; } });
84
+ Object.defineProperty(exports, "BOARD_LOCATION_BY_NAME", { enumerable: true, get: function () { return udtGameBoard_1.BOARD_LOCATION_BY_NAME; } });
85
+ Object.defineProperty(exports, "BOARD_GROUPINGS", { enumerable: true, get: function () { return udtGameBoard_1.BOARD_GROUPINGS; } });
53
86
  // For convenience, also export as default
54
87
  const UltimateDarkTower_2 = __importDefault(require("./UltimateDarkTower"));
55
88
  exports.default = UltimateDarkTower_2.default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;AAEH,yDAAmE;AAA1D,uIAAA,OAAO,OAAqB;AAErC,iDAA+B;AAC/B,yCAAoH;AAA3G,mGAAA,MAAM,OAAA;AAAE,mGAAA,MAAM,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,yGAAA,YAAY,OAAA;AAC/D,2CAAoF;AAA3E,oHAAA,sBAAsB,OAAA;AAAE,0HAAA,4BAA4B,OAAA;AAI7D,6DAM+B;AAL7B,qHAAA,cAAc,OAAA;AACd,+HAAA,wBAAwB,OAAA;AACxB,mIAAA,4BAA4B,OAAA;AAC5B,kIAAA,2BAA2B,OAAA;AAC3B,4HAAA,qBAAqB,OAAA;AAEvB,2EAA0F;AAAjF,+HAAA,iBAAiB,OAAA;AAAE,qIAAA,uBAAuB,OAAA;AAInD,iDAAmF;AAA1E,kHAAA,iBAAiB,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,6GAAA,YAAY,OAAA;AACzD,2CAAmH;AAA1G,qHAAA,uBAAuB,OAAA;AAAE,uHAAA,yBAAyB,OAAA;AAQ3D,0CAA0C;AAC1C,4EAAoD;AACpD,kBAAe,2BAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;AAEH,yDAAmE;AAA1D,uIAAA,OAAO,OAAqB;AAErC,iDAA+B;AAC/B,yCAAoH;AAA3G,mGAAA,MAAM,OAAA;AAAE,mGAAA,MAAM,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,yGAAA,YAAY,OAAA;AAC/D,2CAAoF;AAA3E,oHAAA,sBAAsB,OAAA;AAAE,0HAAA,4BAA4B,OAAA;AAI7D,6DAM+B;AAL7B,qHAAA,cAAc,OAAA;AACd,+HAAA,wBAAwB,OAAA;AACxB,mIAAA,4BAA4B,OAAA;AAC5B,kIAAA,2BAA2B,OAAA;AAC3B,4HAAA,qBAAqB,OAAA;AAEvB,2EAA0F;AAAjF,+HAAA,iBAAiB,OAAA;AAAE,qIAAA,uBAAuB,OAAA;AAInD,iDAAmF;AAA1E,kHAAA,iBAAiB,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,6GAAA,YAAY,OAAA;AACzD,2CAAmH;AAA1G,qHAAA,uBAAuB,OAAA;AAAE,uHAAA,yBAAyB,OAAA;AAQ3D,+FAA+F;AAC/F,mDAAoF;AAA3E,wHAAA,sBAAsB,OAAA;AAAE,8GAAA,YAAY,OAAA;AAAE,4GAAA,UAAU,OAAA;AAKzD,uDAAsD;AAA7C,8GAAA,aAAa,OAAA;AAEtB,cAAc;AACd,iDAIyB;AAHvB,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,6GAAA,YAAY,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,8GAAA,aAAa,OAAA;AACjE,2GAAA,UAAU,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,8GAAA,aAAa,OAAA;AACtD,2GAAA,UAAU,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,uGAAA,MAAM,OAAA;AAAE,6GAAA,YAAY,OAAA;AAAE,6GAAA,YAAY,OAAA;AAOrF,kCAAkC;AAClC,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AAErB,kBAAkB;AAClB,+CAIwB;AAHtB,+GAAA,eAAe,OAAA;AACf,sHAAA,sBAAsB,OAAA;AACtB,+GAAA,eAAe,OAAA;AAIjB,0CAA0C;AAC1C,4EAAoD;AACpD,kBAAe,2BAAiB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Browser-only durable sink. Persists incidents to IndexedDB so they survive
3
+ * page refresh and tab close.
4
+ *
5
+ * Quota policy: keeps at most `maxIncidents` (default 50). Oldest by
6
+ * triggeredAt are evicted. Reads are async via list() / get().
7
+ *
8
+ * Falls back to a no-op if IndexedDB is unavailable (server-side rendering,
9
+ * old browsers, file:// protocol with restrictive policies, etc.).
10
+ */
11
+ import type { DiagnosticsSink, IncidentReport } from '../udtDiagnostics';
12
+ export declare class IndexedDBSink implements DiagnosticsSink {
13
+ private maxIncidents;
14
+ private dbPromise;
15
+ private available;
16
+ constructor(maxIncidents?: number);
17
+ private getDb;
18
+ onIncident(report: IncidentReport): Promise<void>;
19
+ list(): Promise<IncidentReport[]>;
20
+ get(incidentId: string): Promise<IncidentReport | undefined>;
21
+ delete(incidentId: string): Promise<void>;
22
+ clear(): Promise<void>;
23
+ /** Insert an externally-supplied report (e.g. from a JSON import). */
24
+ put(report: IncidentReport): Promise<void>;
25
+ private evictOld;
26
+ }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ /**
3
+ * Browser-only durable sink. Persists incidents to IndexedDB so they survive
4
+ * page refresh and tab close.
5
+ *
6
+ * Quota policy: keeps at most `maxIncidents` (default 50). Oldest by
7
+ * triggeredAt are evicted. Reads are async via list() / get().
8
+ *
9
+ * Falls back to a no-op if IndexedDB is unavailable (server-side rendering,
10
+ * old browsers, file:// protocol with restrictive policies, etc.).
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.IndexedDBSink = void 0;
14
+ const DB_NAME = 'udt-diagnostics';
15
+ const DB_VERSION = 1;
16
+ const STORE_NAME = 'incidents';
17
+ function indexedDBAvailable() {
18
+ try {
19
+ return typeof indexedDB !== 'undefined';
20
+ }
21
+ catch (_a) {
22
+ return false;
23
+ }
24
+ }
25
+ function openDb() {
26
+ return new Promise((resolve, reject) => {
27
+ const req = indexedDB.open(DB_NAME, DB_VERSION);
28
+ req.onupgradeneeded = () => {
29
+ const db = req.result;
30
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
31
+ const store = db.createObjectStore(STORE_NAME, { keyPath: 'incidentId' });
32
+ store.createIndex('triggeredAt', 'triggeredAt', { unique: false });
33
+ }
34
+ };
35
+ req.onsuccess = () => resolve(req.result);
36
+ req.onerror = () => reject(req.error);
37
+ });
38
+ }
39
+ class IndexedDBSink {
40
+ constructor(maxIncidents = 50) {
41
+ this.dbPromise = null;
42
+ this.maxIncidents = maxIncidents;
43
+ this.available = indexedDBAvailable();
44
+ }
45
+ async getDb() {
46
+ if (!this.available)
47
+ return null;
48
+ if (!this.dbPromise) {
49
+ this.dbPromise = openDb().catch(err => {
50
+ this.available = false;
51
+ this.dbPromise = null;
52
+ throw err;
53
+ });
54
+ }
55
+ try {
56
+ return await this.dbPromise;
57
+ }
58
+ catch (_a) {
59
+ return null;
60
+ }
61
+ }
62
+ async onIncident(report) {
63
+ const db = await this.getDb();
64
+ if (!db)
65
+ return;
66
+ await new Promise((resolve, reject) => {
67
+ const tx = db.transaction(STORE_NAME, 'readwrite');
68
+ const store = tx.objectStore(STORE_NAME);
69
+ store.put(report);
70
+ tx.oncomplete = () => resolve();
71
+ tx.onerror = () => reject(tx.error);
72
+ tx.onabort = () => reject(tx.error);
73
+ }).catch(e => console.error('IndexedDBSink put failed:', e));
74
+ await this.evictOld();
75
+ }
76
+ async list() {
77
+ const db = await this.getDb();
78
+ if (!db)
79
+ return [];
80
+ return new Promise((resolve, reject) => {
81
+ const tx = db.transaction(STORE_NAME, 'readonly');
82
+ const store = tx.objectStore(STORE_NAME);
83
+ const req = store.getAll();
84
+ req.onsuccess = () => {
85
+ const all = req.result.slice();
86
+ all.sort((a, b) => b.triggeredAt - a.triggeredAt);
87
+ resolve(all);
88
+ };
89
+ req.onerror = () => reject(req.error);
90
+ });
91
+ }
92
+ async get(incidentId) {
93
+ const db = await this.getDb();
94
+ if (!db)
95
+ return undefined;
96
+ return new Promise((resolve, reject) => {
97
+ const tx = db.transaction(STORE_NAME, 'readonly');
98
+ const store = tx.objectStore(STORE_NAME);
99
+ const req = store.get(incidentId);
100
+ req.onsuccess = () => resolve(req.result);
101
+ req.onerror = () => reject(req.error);
102
+ });
103
+ }
104
+ async delete(incidentId) {
105
+ const db = await this.getDb();
106
+ if (!db)
107
+ return;
108
+ await new Promise((resolve, reject) => {
109
+ const tx = db.transaction(STORE_NAME, 'readwrite');
110
+ tx.objectStore(STORE_NAME).delete(incidentId);
111
+ tx.oncomplete = () => resolve();
112
+ tx.onerror = () => reject(tx.error);
113
+ }).catch(e => console.error('IndexedDBSink delete failed:', e));
114
+ }
115
+ async clear() {
116
+ const db = await this.getDb();
117
+ if (!db)
118
+ return;
119
+ await new Promise((resolve, reject) => {
120
+ const tx = db.transaction(STORE_NAME, 'readwrite');
121
+ tx.objectStore(STORE_NAME).clear();
122
+ tx.oncomplete = () => resolve();
123
+ tx.onerror = () => reject(tx.error);
124
+ }).catch(e => console.error('IndexedDBSink clear failed:', e));
125
+ }
126
+ /** Insert an externally-supplied report (e.g. from a JSON import). */
127
+ async put(report) {
128
+ return this.onIncident(report);
129
+ }
130
+ async evictOld() {
131
+ const db = await this.getDb();
132
+ if (!db)
133
+ return;
134
+ await new Promise((resolve) => {
135
+ const tx = db.transaction(STORE_NAME, 'readwrite');
136
+ const store = tx.objectStore(STORE_NAME);
137
+ const countReq = store.count();
138
+ countReq.onsuccess = () => {
139
+ const total = countReq.result;
140
+ if (total <= this.maxIncidents) {
141
+ resolve();
142
+ return;
143
+ }
144
+ const toRemove = total - this.maxIncidents;
145
+ const idx = store.index('triggeredAt');
146
+ const cursorReq = idx.openCursor();
147
+ let removed = 0;
148
+ cursorReq.onsuccess = () => {
149
+ const cursor = cursorReq.result;
150
+ if (!cursor || removed >= toRemove) {
151
+ resolve();
152
+ return;
153
+ }
154
+ cursor.delete();
155
+ removed++;
156
+ cursor.continue();
157
+ };
158
+ cursorReq.onerror = () => resolve();
159
+ };
160
+ countReq.onerror = () => resolve();
161
+ });
162
+ }
163
+ }
164
+ exports.IndexedDBSink = IndexedDBSink;
165
+ //# sourceMappingURL=IndexedDBSink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IndexedDBSink.js","sourceRoot":"","sources":["../../../src/sinks/IndexedDBSink.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { Logger } from './udtLogger';
2
2
  import { type IBluetoothAdapter } from './udtBluetoothAdapter';
3
+ import type { UdtDiagnosticsRecorder, DisconnectCause, IncidentReport } from './udtDiagnostics';
3
4
  export interface TowerEventCallbacks {
4
5
  onTowerConnect: () => void;
5
6
  onTowerDisconnect: () => void;
@@ -36,6 +37,8 @@ export declare class UdtBleConnection {
36
37
  private logger;
37
38
  private callbacks;
38
39
  private responseProcessor;
40
+ private recorder;
41
+ private snapshotProviders;
39
42
  private bluetoothAdapter;
40
43
  isConnected: boolean;
41
44
  isDisposed: boolean;
@@ -52,11 +55,11 @@ export declare class UdtBleConnection {
52
55
  enableBatteryHeartbeatMonitoring: boolean;
53
56
  batteryHeartbeatVerifyConnection: boolean;
54
57
  towerSkullDropCount: number;
55
- lastBatteryNotification: number;
58
+ lastBatteryLog: number;
56
59
  lastBatteryPercentage: string;
57
- batteryNotifyFrequency: number;
58
- batteryNotifyOnValueChangeOnly: boolean;
59
- batteryNotifyEnabled: boolean;
60
+ batteryLogFrequency: number;
61
+ batteryLogOnChangeOnly: boolean;
62
+ batteryLogEnabled: boolean;
60
63
  private deviceInformation;
61
64
  logTowerResponses: boolean;
62
65
  logTowerResponseConfig: {
@@ -71,7 +74,27 @@ export declare class UdtBleConnection {
71
74
  CALIBRATION_FINISHED: boolean;
72
75
  LOG_ALL: boolean;
73
76
  };
74
- constructor(logger: Logger, callbacks: TowerEventCallbacks, adapter?: IBluetoothAdapter);
77
+ constructor(logger: Logger, callbacks: TowerEventCallbacks, adapter?: IBluetoothAdapter, recorder?: UdtDiagnosticsRecorder);
78
+ setDiagnosticsSnapshotProviders(providers: {
79
+ commandQueue: () => {
80
+ queueLength: number;
81
+ isProcessing: boolean;
82
+ currentCommand: {
83
+ id: string;
84
+ description?: string;
85
+ timestamp: number;
86
+ } | null;
87
+ };
88
+ towerState: () => unknown;
89
+ brokenSeals: () => string[];
90
+ }): void;
91
+ /**
92
+ * Record a disconnect incident with the recorder. Public so higher layers
93
+ * (e.g. UltimateDarkTower's beforeunload handler) can synthesize causes
94
+ * like 'page_unload' that aren't tied to a specific BLE detection path.
95
+ */
96
+ recordIncidentPublic(cause: DisconnectCause): IncidentReport | null;
97
+ private recordIncident;
75
98
  connect(): Promise<void>;
76
99
  disconnect(): Promise<void>;
77
100
  /**
@@ -7,7 +7,12 @@ const udtHelpers_1 = require("./udtHelpers");
7
7
  const udtTowerState_1 = require("./udtTowerState");
8
8
  const udtBluetoothAdapterFactory_1 = require("./udtBluetoothAdapterFactory");
9
9
  class UdtBleConnection {
10
- constructor(logger, callbacks, adapter) {
10
+ constructor(logger, callbacks, adapter, recorder) {
11
+ this.recorder = null;
12
+ // Snapshot providers wired by UltimateDarkTower so the recorder can capture
13
+ // higher-level state (command queue, tower state, broken seals) at the
14
+ // moment a disconnect cause fires.
15
+ this.snapshotProviders = null;
11
16
  // Connection state
12
17
  this.isConnected = false;
13
18
  this.isDisposed = false;
@@ -27,11 +32,11 @@ class UdtBleConnection {
27
32
  this.batteryHeartbeatVerifyConnection = true; // When true, verifies connection before triggering disconnection on heartbeat timeout
28
33
  // Tower state
29
34
  this.towerSkullDropCount = -1;
30
- this.lastBatteryNotification = 0;
35
+ this.lastBatteryLog = 0;
31
36
  this.lastBatteryPercentage = "";
32
- this.batteryNotifyFrequency = 15 * 1000;
33
- this.batteryNotifyOnValueChangeOnly = false;
34
- this.batteryNotifyEnabled = true;
37
+ this.batteryLogFrequency = 15 * 1000;
38
+ this.batteryLogOnChangeOnly = false;
39
+ this.batteryLogEnabled = true;
35
40
  // Device information
36
41
  this.deviceInformation = {};
37
42
  // Logging configuration
@@ -51,6 +56,7 @@ class UdtBleConnection {
51
56
  this.logger = logger;
52
57
  this.callbacks = callbacks;
53
58
  this.responseProcessor = new udtTowerResponse_1.TowerResponseProcessor();
59
+ this.recorder = recorder !== null && recorder !== void 0 ? recorder : null;
54
60
  // Use provided adapter or auto-detect platform
55
61
  this.bluetoothAdapter = adapter || udtBluetoothAdapterFactory_1.BluetoothAdapterFactory.create(udtBluetoothAdapterFactory_1.BluetoothPlatform.AUTO);
56
62
  // Set up adapter event callbacks
@@ -64,7 +70,37 @@ class UdtBleConnection {
64
70
  this.bleAvailabilityChange(available);
65
71
  });
66
72
  }
73
+ setDiagnosticsSnapshotProviders(providers) {
74
+ this.snapshotProviders = providers;
75
+ }
76
+ /**
77
+ * Record a disconnect incident with the recorder. Public so higher layers
78
+ * (e.g. UltimateDarkTower's beforeunload handler) can synthesize causes
79
+ * like 'page_unload' that aren't tied to a specific BLE detection path.
80
+ */
81
+ recordIncidentPublic(cause) {
82
+ return this.recordIncident(cause);
83
+ }
84
+ recordIncident(cause) {
85
+ var _a, _b, _c, _d, _e, _f;
86
+ if (!this.recorder || !this.recorder.enabled)
87
+ return null;
88
+ const queueSnapshot = (_b = (_a = this.snapshotProviders) === null || _a === void 0 ? void 0 : _a.commandQueue()) !== null && _b !== void 0 ? _b : {
89
+ queueLength: 0, isProcessing: false, currentCommand: null
90
+ };
91
+ const towerState = ((_d = (_c = this.snapshotProviders) === null || _c === void 0 ? void 0 : _c.towerState()) !== null && _d !== void 0 ? _d : null);
92
+ const brokenSeals = (_f = (_e = this.snapshotProviders) === null || _e === void 0 ? void 0 : _e.brokenSeals()) !== null && _f !== void 0 ? _f : [];
93
+ return this.recorder.recordIncident({
94
+ cause,
95
+ connectionStatus: this.getConnectionStatus(),
96
+ deviceInformation: this.getDeviceInformation(),
97
+ commandQueue: queueSnapshot,
98
+ towerState,
99
+ brokenSeals,
100
+ });
101
+ }
67
102
  async connect() {
103
+ var _a;
68
104
  if (this.isDisposed) {
69
105
  throw new Error('UdtBleConnection instance has been disposed and cannot reconnect');
70
106
  }
@@ -75,6 +111,7 @@ class UdtBleConnection {
75
111
  this.isConnected = true;
76
112
  this.lastSuccessfulCommand = Date.now();
77
113
  this.lastBatteryHeartbeat = Date.now();
114
+ (_a = this.recorder) === null || _a === void 0 ? void 0 : _a.beginSession();
78
115
  // Read device information after successful connection
79
116
  await this.readDeviceInformation();
80
117
  if (this.enableConnectionMonitoring) {
@@ -85,11 +122,14 @@ class UdtBleConnection {
85
122
  catch (error) {
86
123
  this.logger.error(`Tower Connection Error: ${error}`, '[UDT][BLE]');
87
124
  this.isConnected = false;
88
- this.callbacks.onTowerDisconnect();
125
+ throw error;
89
126
  }
90
127
  }
91
128
  async disconnect() {
92
129
  this.stopConnectionMonitoring();
130
+ if (this.isConnected) {
131
+ this.recordIncident('user_initiated');
132
+ }
93
133
  if (this.bluetoothAdapter.isConnected()) {
94
134
  await this.bluetoothAdapter.disconnect();
95
135
  this.logger.info("Tower disconnected", '[UDT]');
@@ -101,6 +141,8 @@ class UdtBleConnection {
101
141
  * Used by UdtTowerCommands instead of direct characteristic access.
102
142
  */
103
143
  async writeCommand(command) {
144
+ var _a;
145
+ (_a = this.recorder) === null || _a === void 0 ? void 0 : _a.recordCommandPayload('cmd_sent', command, { len: command.length });
104
146
  return await this.bluetoothAdapter.writeCharacteristic(command);
105
147
  }
106
148
  /**
@@ -108,12 +150,16 @@ class UdtBleConnection {
108
150
  * Called by the adapter's onCharacteristicValueChanged callback.
109
151
  */
110
152
  onRxData(receivedData) {
153
+ var _a, _b;
111
154
  this.lastSuccessfulCommand = Date.now();
112
155
  const { cmdKey } = this.responseProcessor.getTowerCommand(receivedData[0]);
113
156
  const isBattery = this.responseProcessor.isBatteryResponse(cmdKey);
157
+ if (((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.enabled) && !isBattery) {
158
+ this.recorder.recordCommandPayload('cmd_response', receivedData, { cmdKey, len: receivedData.length });
159
+ }
114
160
  const shouldLogCommand = this.logTowerResponses &&
115
161
  this.responseProcessor.shouldLogResponse(cmdKey, this.logTowerResponseConfig) &&
116
- (!isBattery || this.batteryNotifyEnabled);
162
+ !isBattery;
117
163
  if (shouldLogCommand) {
118
164
  this.logger.info(`${cmdKey}`, '[UDT][BLE][RCVD]');
119
165
  }
@@ -127,17 +173,19 @@ class UdtBleConnection {
127
173
  this.lastBatteryHeartbeat = Date.now();
128
174
  const millivolts = (0, udtHelpers_1.getMilliVoltsFromTowerResponse)(receivedData);
129
175
  const batteryPercentage = (0, udtHelpers_1.milliVoltsToPercentage)(millivolts);
176
+ (_b = this.recorder) === null || _b === void 0 ? void 0 : _b.recordBattery(millivolts, (0, udtHelpers_1.milliVoltsToPercentageNumber)(millivolts));
130
177
  const didBatteryLevelChange = this.lastBatteryPercentage !== "" && this.lastBatteryPercentage !== batteryPercentage;
131
- const batteryNotifyFrequencyPassed = ((Date.now() - this.lastBatteryNotification) >= this.batteryNotifyFrequency);
132
- const shouldNotify = this.batteryNotifyEnabled && (this.batteryNotifyOnValueChangeOnly ?
178
+ const batteryLogFrequencyPassed = ((Date.now() - this.lastBatteryLog) >= this.batteryLogFrequency);
179
+ const shouldLog = this.batteryLogEnabled && (this.batteryLogOnChangeOnly ?
133
180
  (didBatteryLevelChange || this.lastBatteryPercentage === "") :
134
- batteryNotifyFrequencyPassed);
135
- if (shouldNotify) {
181
+ batteryLogFrequencyPassed);
182
+ if (shouldLog) {
136
183
  this.logger.info(`${this.responseProcessor.commandToString(receivedData).join(' ')}`, '[UDT][BLE]');
137
- this.lastBatteryNotification = Date.now();
184
+ this.lastBatteryLog = Date.now();
138
185
  this.lastBatteryPercentage = batteryPercentage;
139
- this.callbacks.onBatteryLevelNotify(millivolts);
140
186
  }
187
+ // Always notify so internal state and UI stay current
188
+ this.callbacks.onBatteryLevelNotify(millivolts);
141
189
  }
142
190
  else {
143
191
  // For non-battery responses, notify the command queue
@@ -148,20 +196,24 @@ class UdtBleConnection {
148
196
  }
149
197
  }
150
198
  handleTowerStateResponse(receivedData) {
199
+ var _a, _b, _c;
151
200
  const dataSkullDropCount = receivedData[udtConstants_1.SKULL_DROP_COUNT_POS];
152
201
  const state = (0, udtTowerState_1.rtdt_unpack_state)(receivedData);
153
202
  this.logger.debug(`Tower State: ${JSON.stringify(state)} `, '[UDT][BLE]');
203
+ (_a = this.recorder) === null || _a === void 0 ? void 0 : _a.recordEvent('tower_state_response');
154
204
  if (this.performingCalibration) {
155
205
  this.performingCalibration = false;
156
206
  this.performingLongCommand = false;
157
207
  this.lastBatteryHeartbeat = Date.now();
158
208
  this.callbacks.onCalibrationComplete();
159
209
  this.logger.info('Tower calibration complete', '[UDT]');
210
+ (_b = this.recorder) === null || _b === void 0 ? void 0 : _b.recordEvent('calibration_complete');
160
211
  }
161
212
  if (dataSkullDropCount !== this.towerSkullDropCount) {
162
213
  if (dataSkullDropCount) {
163
214
  this.callbacks.onSkullDrop(dataSkullDropCount);
164
215
  this.logger.info(`Skull drop detected: app:${this.towerSkullDropCount < 0 ? 'empty' : this.towerSkullDropCount} tower:${dataSkullDropCount}`, '[UDT]');
216
+ (_c = this.recorder) === null || _c === void 0 ? void 0 : _c.recordEvent('skull_drop', { count: dataSkullDropCount });
165
217
  }
166
218
  else {
167
219
  this.logger.info(`Skull count reset to ${dataSkullDropCount}`, '[UDT]');
@@ -189,11 +241,15 @@ class UdtBleConnection {
189
241
  this.logger.info('Bluetooth availability changed', '[UDT][BLE]');
190
242
  if (!available && this.isConnected) {
191
243
  this.logger.warn('Bluetooth became unavailable - handling disconnection', '[UDT][BLE]');
244
+ this.recordIncident('bt_unavailable');
192
245
  this.handleDisconnection();
193
246
  }
194
247
  }
195
248
  onTowerDeviceDisconnected() {
196
249
  this.logger.warn('Tower device disconnected unexpectedly', '[UDT][BLE]');
250
+ if (this.isConnected) {
251
+ this.recordIncident('adapter_event');
252
+ }
197
253
  this.handleDisconnection();
198
254
  }
199
255
  handleDisconnection() {
@@ -222,11 +278,13 @@ class UdtBleConnection {
222
278
  }
223
279
  }
224
280
  checkConnectionHealth() {
281
+ var _a;
225
282
  if (!this.isConnected) {
226
283
  return;
227
284
  }
228
285
  if (!this.bluetoothAdapter.isGattConnected()) {
229
286
  this.logger.warn('GATT connection lost detected during health check', '[UDT][BLE]');
287
+ this.recordIncident('gatt_health_check');
230
288
  this.handleDisconnection();
231
289
  return;
232
290
  }
@@ -246,6 +304,13 @@ class UdtBleConnection {
246
304
  // Check if GATT is still connected via the adapter
247
305
  if (this.bluetoothAdapter.isGattConnected()) {
248
306
  this.logger.info('GATT connection still available - heartbeat timeout may be temporary', '[UDT][BLE]');
307
+ // Near-miss: the heartbeat went late but the GATT is still up. This is a
308
+ // strong signal worth recording for diagnostics — repeated near-misses
309
+ // before a real drop are the smoking gun.
310
+ (_a = this.recorder) === null || _a === void 0 ? void 0 : _a.recordEvent('heartbeat_late', {
311
+ sinceMs: timeSinceLastBatteryHeartbeat,
312
+ threshold: timeoutThreshold,
313
+ });
249
314
  // Reset the last battery heartbeat to current time to give it another chance
250
315
  this.lastBatteryHeartbeat = Date.now();
251
316
  this.logger.info('Reset battery heartbeat timer - will monitor for another timeout period', '[UDT][BLE]');
@@ -253,6 +318,7 @@ class UdtBleConnection {
253
318
  }
254
319
  }
255
320
  this.logger.warn('Tower possibly disconnected due to battery depletion or power loss', '[UDT][BLE]');
321
+ this.recordIncident('heartbeat_timeout');
256
322
  this.handleDisconnection();
257
323
  return;
258
324
  }
@@ -260,6 +326,7 @@ class UdtBleConnection {
260
326
  const timeSinceLastResponse = Date.now() - this.lastSuccessfulCommand;
261
327
  if (timeSinceLastResponse > this.connectionTimeoutThreshold) {
262
328
  this.logger.warn('General connection timeout detected - no responses received', '[UDT][BLE]');
329
+ this.recordIncident('response_timeout');
263
330
  this.handleDisconnection();
264
331
  }
265
332
  }