@trillboards/edge-core 0.2.1 → 0.2.3
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/JsonFileStore.d.ts +33 -0
- package/dist/JsonFileStore.d.ts.map +1 -0
- package/dist/JsonFileStore.js +210 -0
- package/dist/JsonFileStore.js.map +1 -0
- package/dist/MemoryAttenuationManager.d.ts +164 -0
- package/dist/MemoryAttenuationManager.d.ts.map +1 -0
- package/dist/MemoryAttenuationManager.js +400 -0
- package/dist/MemoryAttenuationManager.js.map +1 -0
- package/dist/ModelManager.d.ts +166 -0
- package/dist/ModelManager.d.ts.map +1 -0
- package/dist/ModelManager.js +580 -0
- package/dist/ModelManager.js.map +1 -0
- package/dist/SignalBuffer.d.ts +20 -12
- package/dist/SignalBuffer.d.ts.map +1 -1
- package/dist/SignalBuffer.js +56 -71
- package/dist/SignalBuffer.js.map +1 -1
- package/dist/SignalStore.d.ts +35 -0
- package/dist/SignalStore.d.ts.map +1 -0
- package/dist/SignalStore.js +13 -0
- package/dist/SignalStore.js.map +1 -0
- package/dist/SqliteStore.d.ts +41 -0
- package/dist/SqliteStore.d.ts.map +1 -0
- package/dist/SqliteStore.js +162 -0
- package/dist/SqliteStore.js.map +1 -0
- package/dist/StatusServer.d.ts +99 -0
- package/dist/StatusServer.d.ts.map +1 -0
- package/dist/StatusServer.js +262 -0
- package/dist/StatusServer.js.map +1 -0
- package/dist/ZKAudienceProver.d.ts +137 -0
- package/dist/ZKAudienceProver.d.ts.map +1 -0
- package/dist/ZKAudienceProver.js +321 -0
- package/dist/ZKAudienceProver.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignalBuffer.d.ts","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SignalBuffer.d.ts","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ;IACpC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,MAAM;IACtC,MAAM,CAAC,QAAQ,CAAC,UAAU,SAAuB;IACjD,MAAM,CAAC,QAAQ,CAAC,WAAW,KAAK;IAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,OAAO;IAElC,OAAO,CAAC,KAAK,CAAc;IAC3B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;gBAExB,MAAM,EAAE,MAAM;IAiC1B;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpD;;;;OAIG;IACH,WAAW,CACT,aAAa,EAAE,aAAa,EAC5B,KAAK,GAAE,MAAsC,GAC5C,MAAM;IA8BT;;OAEG;IACH,eAAe,IAAI,MAAM;IAKzB;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,KAAK,IAAI,gBAAgB;IAIzB;;OAEG;IACH,QAAQ,IAAI,IAAI;CAGjB"}
|
package/dist/SignalBuffer.js
CHANGED
|
@@ -1,92 +1,73 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* SignalBuffer — Offline signal buffering
|
|
4
|
-
* Port of SignalBuffer.kt (Room database) to cross-platform
|
|
3
|
+
* SignalBuffer — Offline signal buffering with auto-detecting backend.
|
|
4
|
+
* Port of SignalBuffer.kt (Room database) to cross-platform storage.
|
|
5
|
+
*
|
|
6
|
+
* Backends:
|
|
7
|
+
* - SqliteStore (better-sqlite3 installed → WAL mode, prepared stmts)
|
|
8
|
+
* - JsonFileStore (fallback → zero deps, fs.renameSync atomic writes)
|
|
9
|
+
*
|
|
10
|
+
* Auto-detection: tries require('better-sqlite3') at construction time.
|
|
11
|
+
* If unavailable (native compilation failed, not installed), falls back
|
|
12
|
+
* to JsonFileStore — guaranteed to work on any Node.js >=18 platform.
|
|
5
13
|
*
|
|
6
14
|
* Capacity: 8,640 signals (24h at 6 signals/min)
|
|
7
15
|
* Eviction: oldest 10% when at capacity
|
|
8
16
|
* Flush: batch of 50, marks with _buffered and _bufferedAt
|
|
9
17
|
* Pruning: signals older than 24h auto-deleted
|
|
18
|
+
* Priority: FACE_BACKED > PERSON_BACKED > SPEECH_ONLY > PROXY_ONLY > EMPTY
|
|
10
19
|
*/
|
|
11
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
-
}
|
|
17
|
-
Object.defineProperty(o, k2, desc);
|
|
18
|
-
}) : (function(o, m, k, k2) {
|
|
19
|
-
if (k2 === undefined) k2 = k;
|
|
20
|
-
o[k2] = m[k];
|
|
21
|
-
}));
|
|
22
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
-
}) : function(o, v) {
|
|
25
|
-
o["default"] = v;
|
|
26
|
-
});
|
|
27
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
21
|
exports.SignalBuffer = void 0;
|
|
39
|
-
const
|
|
40
|
-
const path = __importStar(require("path"));
|
|
41
|
-
const fs = __importStar(require("fs"));
|
|
22
|
+
const JsonFileStore_1 = require("./JsonFileStore");
|
|
42
23
|
class SignalBuffer {
|
|
43
24
|
constructor(dbPath) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
25
|
+
let store = null;
|
|
26
|
+
let backend = 'json';
|
|
27
|
+
// Try SQLite first (high-performance, optional)
|
|
28
|
+
try {
|
|
29
|
+
// Dynamic require — only resolves if better-sqlite3 is installed + compiled
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
31
|
+
const Database = require('better-sqlite3');
|
|
32
|
+
const { SqliteStore } = require('./SqliteStore');
|
|
33
|
+
store = new SqliteStore(dbPath, Database);
|
|
34
|
+
backend = 'sqlite';
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// better-sqlite3 not available — fall back to JSON file store
|
|
47
38
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
CREATE INDEX IF NOT EXISTS idx_signals_timestamp ON buffered_signals(timestamp)
|
|
61
|
-
`);
|
|
62
|
-
// Prepared statements for performance
|
|
63
|
-
this.insertStmt = this.db.prepare('INSERT INTO buffered_signals (payload, timestamp, retry_count) VALUES (?, ?, 0)');
|
|
64
|
-
this.getOldestStmt = this.db.prepare('SELECT id, payload, timestamp, retry_count FROM buffered_signals ORDER BY timestamp ASC LIMIT ?');
|
|
65
|
-
this.deleteByIdStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id = ?');
|
|
66
|
-
this.countStmt = this.db.prepare('SELECT COUNT(*) as count FROM buffered_signals');
|
|
67
|
-
this.pruneStmt = this.db.prepare('DELETE FROM buffered_signals WHERE timestamp < ?');
|
|
68
|
-
this.deleteOldestNStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id IN (SELECT id FROM buffered_signals ORDER BY timestamp ASC LIMIT ?)');
|
|
69
|
-
this.incrementRetryStmt = this.db.prepare('UPDATE buffered_signals SET retry_count = retry_count + 1 WHERE id = ?');
|
|
70
|
-
this.deleteMaxRetriesStmt = this.db.prepare('DELETE FROM buffered_signals WHERE retry_count >= ?');
|
|
39
|
+
if (!store) {
|
|
40
|
+
// Use JSON file store — zero dependencies, universal
|
|
41
|
+
const jsonPath = dbPath.replace(/\.db$/, '.json');
|
|
42
|
+
store = new JsonFileStore_1.JsonFileStore(jsonPath);
|
|
43
|
+
backend = 'json';
|
|
44
|
+
}
|
|
45
|
+
this.store = store;
|
|
46
|
+
this.backend = backend;
|
|
47
|
+
const label = backend === 'sqlite'
|
|
48
|
+
? 'SQLite (disk-persistent, WAL mode)'
|
|
49
|
+
: 'JSON file (disk-persistent, atomic writes)';
|
|
50
|
+
console.log(`[SignalBuffer] Initialized: ${label}`);
|
|
71
51
|
}
|
|
72
52
|
/**
|
|
73
53
|
* Buffer a signal for later sending.
|
|
74
54
|
* If at capacity, evicts oldest 10% first.
|
|
75
55
|
*/
|
|
76
56
|
bufferSignal(payload) {
|
|
77
|
-
const count = this.count();
|
|
57
|
+
const count = this.store.count();
|
|
78
58
|
if (count >= SignalBuffer.MAX_CAPACITY) {
|
|
79
59
|
const evictCount = Math.ceil(SignalBuffer.MAX_CAPACITY * SignalBuffer.EVICT_RATIO);
|
|
80
|
-
this.
|
|
60
|
+
this.store.deleteOldestN(evictCount);
|
|
81
61
|
}
|
|
82
|
-
this.
|
|
62
|
+
this.store.insert(JSON.stringify(payload), Date.now());
|
|
83
63
|
}
|
|
84
64
|
/**
|
|
85
65
|
* Flush buffered signals via socket.
|
|
86
66
|
* Returns number of successfully sent signals.
|
|
67
|
+
* Signals are flushed in priority order — highest evidence grade first.
|
|
87
68
|
*/
|
|
88
69
|
flushBuffer(socketManager, limit = SignalBuffer.FLUSH_BATCH_SIZE) {
|
|
89
|
-
const signals = this.
|
|
70
|
+
const signals = this.store.getOldest(limit);
|
|
90
71
|
let sent = 0;
|
|
91
72
|
for (const signal of signals) {
|
|
92
73
|
try {
|
|
@@ -96,20 +77,20 @@ class SignalBuffer {
|
|
|
96
77
|
payload._bufferedAt = signal.timestamp;
|
|
97
78
|
const success = socketManager.emitAudienceSignal(payload);
|
|
98
79
|
if (success) {
|
|
99
|
-
this.
|
|
80
|
+
this.store.deleteById(signal.id);
|
|
100
81
|
sent++;
|
|
101
82
|
}
|
|
102
83
|
else {
|
|
103
|
-
this.
|
|
84
|
+
this.store.incrementRetry(signal.id);
|
|
104
85
|
}
|
|
105
86
|
}
|
|
106
87
|
catch {
|
|
107
88
|
// Corrupted payload — remove it
|
|
108
|
-
this.
|
|
89
|
+
this.store.deleteById(signal.id);
|
|
109
90
|
}
|
|
110
91
|
}
|
|
111
92
|
// Clean up signals that have exceeded max retries
|
|
112
|
-
this.
|
|
93
|
+
this.store.deleteExceedingRetries(SignalBuffer.MAX_RETRIES);
|
|
113
94
|
return sent;
|
|
114
95
|
}
|
|
115
96
|
/**
|
|
@@ -117,21 +98,25 @@ class SignalBuffer {
|
|
|
117
98
|
*/
|
|
118
99
|
pruneOldSignals() {
|
|
119
100
|
const cutoff = Date.now() - SignalBuffer.MAX_AGE_MS;
|
|
120
|
-
|
|
121
|
-
return result.changes;
|
|
101
|
+
return this.store.deleteOlderThan(cutoff);
|
|
122
102
|
}
|
|
123
103
|
/**
|
|
124
104
|
* Current number of buffered signals.
|
|
125
105
|
*/
|
|
126
106
|
count() {
|
|
127
|
-
|
|
128
|
-
|
|
107
|
+
return this.store.count();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Signal buffer statistics — count by evidence grade, oldest timestamp.
|
|
111
|
+
*/
|
|
112
|
+
stats() {
|
|
113
|
+
return this.store.stats();
|
|
129
114
|
}
|
|
130
115
|
/**
|
|
131
|
-
* Close the
|
|
116
|
+
* Close the store connection.
|
|
132
117
|
*/
|
|
133
118
|
shutdown() {
|
|
134
|
-
this.
|
|
119
|
+
this.store.close();
|
|
135
120
|
}
|
|
136
121
|
}
|
|
137
122
|
exports.SignalBuffer = SignalBuffer;
|
package/dist/SignalBuffer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignalBuffer.js","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"SignalBuffer.js","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SignalStore — Internal interface for signal-aware persistence backends.
|
|
3
|
+
*
|
|
4
|
+
* The SignalBuffer delegates all storage operations to a SignalStore implementation.
|
|
5
|
+
* Two built-in implementations:
|
|
6
|
+
* - JsonFileStore (zero dependencies, universal default)
|
|
7
|
+
* - SqliteStore (optional, high-throughput upgrade via better-sqlite3)
|
|
8
|
+
*
|
|
9
|
+
* Advanced users can implement this interface for custom backends (Redis, IndexedDB, etc.)
|
|
10
|
+
*/
|
|
11
|
+
export interface StoredSignal {
|
|
12
|
+
id: number;
|
|
13
|
+
payload: string;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
retryCount: number;
|
|
16
|
+
evidenceGrade?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SignalStoreStats {
|
|
19
|
+
total: number;
|
|
20
|
+
byEvidenceGrade: Record<string, number>;
|
|
21
|
+
oldestTimestampMs: number | null;
|
|
22
|
+
}
|
|
23
|
+
export interface SignalStore {
|
|
24
|
+
insert(payload: string, timestamp: number): void;
|
|
25
|
+
getOldest(limit: number): StoredSignal[];
|
|
26
|
+
deleteById(id: number): void;
|
|
27
|
+
deleteOlderThan(cutoffMs: number): number;
|
|
28
|
+
deleteOldestN(n: number): void;
|
|
29
|
+
deleteExceedingRetries(maxRetries: number): void;
|
|
30
|
+
incrementRetry(id: number): void;
|
|
31
|
+
count(): number;
|
|
32
|
+
stats(): SignalStoreStats;
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=SignalStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignalStore.d.ts","sourceRoot":"","sources":["../src/SignalStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IACzC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,IAAI,MAAM,CAAC;IAChB,KAAK,IAAI,gBAAgB,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SignalStore — Internal interface for signal-aware persistence backends.
|
|
4
|
+
*
|
|
5
|
+
* The SignalBuffer delegates all storage operations to a SignalStore implementation.
|
|
6
|
+
* Two built-in implementations:
|
|
7
|
+
* - JsonFileStore (zero dependencies, universal default)
|
|
8
|
+
* - SqliteStore (optional, high-throughput upgrade via better-sqlite3)
|
|
9
|
+
*
|
|
10
|
+
* Advanced users can implement this interface for custom backends (Redis, IndexedDB, etc.)
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
//# sourceMappingURL=SignalStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignalStore.js","sourceRoot":"","sources":["../src/SignalStore.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SqliteStore — High-performance signal store using better-sqlite3.
|
|
3
|
+
* Extracted from the original SignalBuffer implementation.
|
|
4
|
+
*
|
|
5
|
+
* WAL journal mode, prepared statements, evidence_grade column + index
|
|
6
|
+
* for priority-aware flushing (FACE_BACKED sent first).
|
|
7
|
+
*
|
|
8
|
+
* Only loaded when better-sqlite3 is available (optional dependency).
|
|
9
|
+
*/
|
|
10
|
+
import type { SignalStore, StoredSignal, SignalStoreStats } from './SignalStore';
|
|
11
|
+
import type { Database as DatabaseType } from 'better-sqlite3';
|
|
12
|
+
export declare class SqliteStore implements SignalStore {
|
|
13
|
+
private db;
|
|
14
|
+
private insertStmt;
|
|
15
|
+
private getOldestStmt;
|
|
16
|
+
private deleteByIdStmt;
|
|
17
|
+
private countStmt;
|
|
18
|
+
private pruneStmt;
|
|
19
|
+
private deleteOldestNStmt;
|
|
20
|
+
private incrementRetryStmt;
|
|
21
|
+
private deleteMaxRetriesStmt;
|
|
22
|
+
private statsStmt;
|
|
23
|
+
private oldestStmt;
|
|
24
|
+
/**
|
|
25
|
+
* @param dbPath - Path to the SQLite database file
|
|
26
|
+
* @param DatabaseConstructor - The better-sqlite3 Database constructor (injected to avoid top-level require)
|
|
27
|
+
*/
|
|
28
|
+
constructor(dbPath: string, DatabaseConstructor: new (filename: string) => DatabaseType);
|
|
29
|
+
private extractEvidenceGrade;
|
|
30
|
+
insert(payload: string, timestamp: number): void;
|
|
31
|
+
getOldest(limit: number): StoredSignal[];
|
|
32
|
+
deleteById(id: number): void;
|
|
33
|
+
deleteOlderThan(cutoffMs: number): number;
|
|
34
|
+
deleteOldestN(n: number): void;
|
|
35
|
+
deleteExceedingRetries(maxRetries: number): void;
|
|
36
|
+
incrementRetry(id: number): void;
|
|
37
|
+
count(): number;
|
|
38
|
+
stats(): SignalStoreStats;
|
|
39
|
+
close(): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=SqliteStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqliteStore.d.ts","sourceRoot":"","sources":["../src/SqliteStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjF,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE/D,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,kBAAkB,CAAsC;IAChE,OAAO,CAAC,oBAAoB,CAAsC;IAClE,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,UAAU,CAAsC;IAExD;;;OAGG;gBAED,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,YAAY;IA4F7D,OAAO,CAAC,oBAAoB;IAW5B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE;IAIxC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI5B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKzC,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAI9B,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,KAAK,IAAI,MAAM;IAKf,KAAK,IAAI,gBAAgB;IAoBzB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SqliteStore — High-performance signal store using better-sqlite3.
|
|
4
|
+
* Extracted from the original SignalBuffer implementation.
|
|
5
|
+
*
|
|
6
|
+
* WAL journal mode, prepared statements, evidence_grade column + index
|
|
7
|
+
* for priority-aware flushing (FACE_BACKED sent first).
|
|
8
|
+
*
|
|
9
|
+
* Only loaded when better-sqlite3 is available (optional dependency).
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.SqliteStore = void 0;
|
|
36
|
+
const path = __importStar(require("path"));
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
class SqliteStore {
|
|
39
|
+
/**
|
|
40
|
+
* @param dbPath - Path to the SQLite database file
|
|
41
|
+
* @param DatabaseConstructor - The better-sqlite3 Database constructor (injected to avoid top-level require)
|
|
42
|
+
*/
|
|
43
|
+
constructor(dbPath, DatabaseConstructor) {
|
|
44
|
+
const dir = path.dirname(dbPath);
|
|
45
|
+
if (!fs.existsSync(dir)) {
|
|
46
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
this.db = new DatabaseConstructor(dbPath);
|
|
49
|
+
this.db.pragma('journal_mode = WAL');
|
|
50
|
+
this.db.pragma('synchronous = NORMAL');
|
|
51
|
+
this.db.exec(`
|
|
52
|
+
CREATE TABLE IF NOT EXISTS buffered_signals (
|
|
53
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
54
|
+
payload TEXT NOT NULL,
|
|
55
|
+
timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000),
|
|
56
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
evidence_grade TEXT NOT NULL DEFAULT 'EMPTY'
|
|
58
|
+
)
|
|
59
|
+
`);
|
|
60
|
+
this.db.exec(`
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_signals_timestamp ON buffered_signals(timestamp)
|
|
62
|
+
`);
|
|
63
|
+
this.db.exec(`
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_signals_evidence_grade ON buffered_signals(evidence_grade)
|
|
65
|
+
`);
|
|
66
|
+
// Migrate existing rows that lack evidence_grade (from pre-0.2.2 databases)
|
|
67
|
+
try {
|
|
68
|
+
// Check if evidence_grade column exists by querying pragma
|
|
69
|
+
const columns = this.db
|
|
70
|
+
.prepare("PRAGMA table_info('buffered_signals')")
|
|
71
|
+
.all();
|
|
72
|
+
const hasGradeCol = columns.some((c) => c.name === 'evidence_grade');
|
|
73
|
+
if (!hasGradeCol) {
|
|
74
|
+
this.db.exec("ALTER TABLE buffered_signals ADD COLUMN evidence_grade TEXT NOT NULL DEFAULT 'EMPTY'");
|
|
75
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_signals_evidence_grade ON buffered_signals(evidence_grade)");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Column already exists or migration not needed
|
|
80
|
+
}
|
|
81
|
+
// Prepared statements
|
|
82
|
+
this.insertStmt = this.db.prepare('INSERT INTO buffered_signals (payload, timestamp, retry_count, evidence_grade) VALUES (?, ?, 0, ?)');
|
|
83
|
+
this.getOldestStmt = this.db.prepare(`
|
|
84
|
+
SELECT id, payload, timestamp, retry_count as retryCount, evidence_grade as evidenceGrade
|
|
85
|
+
FROM buffered_signals
|
|
86
|
+
ORDER BY
|
|
87
|
+
CASE evidence_grade
|
|
88
|
+
WHEN 'FACE_BACKED' THEN 1
|
|
89
|
+
WHEN 'PERSON_BACKED' THEN 2
|
|
90
|
+
WHEN 'SPEECH_ONLY' THEN 3
|
|
91
|
+
WHEN 'PROXY_ONLY' THEN 4
|
|
92
|
+
ELSE 5
|
|
93
|
+
END,
|
|
94
|
+
timestamp ASC
|
|
95
|
+
LIMIT ?
|
|
96
|
+
`);
|
|
97
|
+
this.deleteByIdStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id = ?');
|
|
98
|
+
this.countStmt = this.db.prepare('SELECT COUNT(*) as count FROM buffered_signals');
|
|
99
|
+
this.pruneStmt = this.db.prepare('DELETE FROM buffered_signals WHERE timestamp < ?');
|
|
100
|
+
this.deleteOldestNStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id IN (SELECT id FROM buffered_signals ORDER BY timestamp ASC LIMIT ?)');
|
|
101
|
+
this.incrementRetryStmt = this.db.prepare('UPDATE buffered_signals SET retry_count = retry_count + 1 WHERE id = ?');
|
|
102
|
+
this.deleteMaxRetriesStmt = this.db.prepare('DELETE FROM buffered_signals WHERE retry_count >= ?');
|
|
103
|
+
this.statsStmt = this.db.prepare('SELECT evidence_grade as grade, COUNT(*) as cnt FROM buffered_signals GROUP BY evidence_grade');
|
|
104
|
+
this.oldestStmt = this.db.prepare('SELECT MIN(timestamp) as oldest FROM buffered_signals');
|
|
105
|
+
}
|
|
106
|
+
extractEvidenceGrade(payload) {
|
|
107
|
+
try {
|
|
108
|
+
const parsed = JSON.parse(payload);
|
|
109
|
+
return typeof parsed.evidenceGrade === 'string'
|
|
110
|
+
? parsed.evidenceGrade
|
|
111
|
+
: 'EMPTY';
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return 'EMPTY';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
insert(payload, timestamp) {
|
|
118
|
+
const grade = this.extractEvidenceGrade(payload);
|
|
119
|
+
this.insertStmt.run(payload, timestamp, grade);
|
|
120
|
+
}
|
|
121
|
+
getOldest(limit) {
|
|
122
|
+
return this.getOldestStmt.all(limit);
|
|
123
|
+
}
|
|
124
|
+
deleteById(id) {
|
|
125
|
+
this.deleteByIdStmt.run(id);
|
|
126
|
+
}
|
|
127
|
+
deleteOlderThan(cutoffMs) {
|
|
128
|
+
const result = this.pruneStmt.run(cutoffMs);
|
|
129
|
+
return result.changes;
|
|
130
|
+
}
|
|
131
|
+
deleteOldestN(n) {
|
|
132
|
+
this.deleteOldestNStmt.run(n);
|
|
133
|
+
}
|
|
134
|
+
deleteExceedingRetries(maxRetries) {
|
|
135
|
+
this.deleteMaxRetriesStmt.run(maxRetries);
|
|
136
|
+
}
|
|
137
|
+
incrementRetry(id) {
|
|
138
|
+
this.incrementRetryStmt.run(id);
|
|
139
|
+
}
|
|
140
|
+
count() {
|
|
141
|
+
const row = this.countStmt.get();
|
|
142
|
+
return row.count;
|
|
143
|
+
}
|
|
144
|
+
stats() {
|
|
145
|
+
const rows = this.statsStmt.all();
|
|
146
|
+
const byGrade = {};
|
|
147
|
+
for (const row of rows) {
|
|
148
|
+
byGrade[row.grade] = row.cnt;
|
|
149
|
+
}
|
|
150
|
+
const oldestRow = this.oldestStmt.get();
|
|
151
|
+
return {
|
|
152
|
+
total: this.count(),
|
|
153
|
+
byEvidenceGrade: byGrade,
|
|
154
|
+
oldestTimestampMs: oldestRow.oldest,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
close() {
|
|
158
|
+
this.db.close();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.SqliteStore = SqliteStore;
|
|
162
|
+
//# sourceMappingURL=SqliteStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqliteStore.js","sourceRoot":"","sources":["../src/SqliteStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatusServer — HTTP server exposing device status, health, and Prometheus metrics.
|
|
3
|
+
*
|
|
4
|
+
* Runs inside the EdgeAgent process on a configurable port (default 9090).
|
|
5
|
+
* Uses ONLY Node.js built-in `http` module — zero external dependencies.
|
|
6
|
+
*
|
|
7
|
+
* Endpoints:
|
|
8
|
+
* GET /status — Full JSON status snapshot
|
|
9
|
+
* GET /health — Simple health probe (200 OK / 503 degraded)
|
|
10
|
+
* GET /metrics — Prometheus-format text metrics
|
|
11
|
+
*/
|
|
12
|
+
export interface StatusServerOptions {
|
|
13
|
+
/** HTTP listen port. Default: 9090 */
|
|
14
|
+
port?: number;
|
|
15
|
+
/** HTTP listen host. Default: '0.0.0.0' */
|
|
16
|
+
host?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface StatusData {
|
|
19
|
+
/** Device fingerprint */
|
|
20
|
+
fingerprint: string;
|
|
21
|
+
/** Assigned screen ID, or null if unassigned */
|
|
22
|
+
screenId: string | null;
|
|
23
|
+
/** Capability tier (1-4) */
|
|
24
|
+
tier: number;
|
|
25
|
+
/** Platform string, e.g. 'linux x64' */
|
|
26
|
+
platform: string;
|
|
27
|
+
/** Seconds since agent start (computed on read) */
|
|
28
|
+
uptime: number;
|
|
29
|
+
/** SDK version string */
|
|
30
|
+
sdkVersion: string;
|
|
31
|
+
/** Health snapshot from SubsystemHealthRegistry.toHeartbeatPayload() */
|
|
32
|
+
subsystemHealth: Record<string, unknown>;
|
|
33
|
+
/** Current sensing mode, e.g. 'edge_onnx', 'cloud', 'proxy_only' */
|
|
34
|
+
sensingMode: string;
|
|
35
|
+
/** Current detected face count */
|
|
36
|
+
currentFaceCount: number;
|
|
37
|
+
/** Average attention score (0-1) */
|
|
38
|
+
avgAttention: number;
|
|
39
|
+
/** Weighted VAS score (0-1) */
|
|
40
|
+
avgVAS: number;
|
|
41
|
+
/** Evidence grade, e.g. 'FACE_BACKED' */
|
|
42
|
+
evidenceGrade: string;
|
|
43
|
+
/** Number of signals currently buffered */
|
|
44
|
+
signalBufferCount: number;
|
|
45
|
+
/** Maximum buffer capacity */
|
|
46
|
+
signalBufferCapacity: number;
|
|
47
|
+
/** Whether the Socket.io connection is live */
|
|
48
|
+
socketConnected: boolean;
|
|
49
|
+
/** Epoch ms of last signal emit */
|
|
50
|
+
lastSignalTimestamp: number;
|
|
51
|
+
/** Total RSS memory usage in MB */
|
|
52
|
+
memoryUsageMb: number;
|
|
53
|
+
/** V8 heap used in MB */
|
|
54
|
+
heapUsedMb: number;
|
|
55
|
+
/** List of loaded model names, e.g. ['blazeFace', 'yamnet'] */
|
|
56
|
+
modelsLoaded: string[];
|
|
57
|
+
/** ONNX execution provider, e.g. 'cpu', 'openvino' */
|
|
58
|
+
executionProvider: string;
|
|
59
|
+
/** Whether federated learning is enabled */
|
|
60
|
+
federatedEnabled: boolean;
|
|
61
|
+
/** Epoch ms of last gradient upload */
|
|
62
|
+
lastGradientUpload: number;
|
|
63
|
+
}
|
|
64
|
+
export declare class StatusServer {
|
|
65
|
+
private server;
|
|
66
|
+
private statusData;
|
|
67
|
+
private startTime;
|
|
68
|
+
private port;
|
|
69
|
+
private host;
|
|
70
|
+
constructor(options?: StatusServerOptions);
|
|
71
|
+
/**
|
|
72
|
+
* Merge partial updates into the status snapshot.
|
|
73
|
+
* Call this from EdgeAgent whenever subsystem state changes.
|
|
74
|
+
*/
|
|
75
|
+
updateStatus(partial: Partial<StatusData>): void;
|
|
76
|
+
/**
|
|
77
|
+
* Start the HTTP server. Resolves once the server is listening.
|
|
78
|
+
* If the port is already in use, logs a warning and resolves without starting.
|
|
79
|
+
*/
|
|
80
|
+
start(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Stop the HTTP server gracefully. Resolves once all connections are closed.
|
|
83
|
+
*/
|
|
84
|
+
stop(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Get the current status snapshot with computed fields (uptime, memory).
|
|
87
|
+
* Also used by the status CLI command via the /status HTTP endpoint.
|
|
88
|
+
*/
|
|
89
|
+
getStatus(): StatusData & {
|
|
90
|
+
uptime: number;
|
|
91
|
+
memoryUsageMb: number;
|
|
92
|
+
heapUsedMb: number;
|
|
93
|
+
};
|
|
94
|
+
private handleRequest;
|
|
95
|
+
private handleStatus;
|
|
96
|
+
private handleHealth;
|
|
97
|
+
private handleMetrics;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=StatusServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusServer.d.ts","sourceRoot":"","sources":["../src/StatusServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IAGzB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAInB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIzC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IAItB,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8BAA8B;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAI7B,+CAA+C;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,mCAAmC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAI5B,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAInB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAI1B,4CAA4C;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AA2BD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,CAAC,EAAE,mBAAmB;IAOzC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI;IAIhD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B;;;OAGG;IACH,SAAS,IAAI,UAAU,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAcvF,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,aAAa;CAyDtB"}
|