@chainmcp/storage 0.0.0-stage → 0.4.1

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.
@@ -0,0 +1,69 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import type { BlobPayload, BlobPayloadStore, BlobStorePutOptions, KeyValueStore, StorageDriver, StorageDriverOptions, TelemetryEvent, TelemetryQueryOptions, TelemetryRingBuffer, TelemetryRingBufferOptions } from "./types.js";
3
+ export interface SqliteStorageDriverOptions extends StorageDriverOptions {
4
+ busyTimeoutMs?: number | undefined;
5
+ }
6
+ export declare class SqliteKeyValueStore<T = unknown> implements KeyValueStore<T> {
7
+ private readonly db;
8
+ readonly namespace: string;
9
+ constructor(db: DatabaseSync, namespace: string);
10
+ get(key: string, tenantId?: string): Promise<T | null>;
11
+ set(key: string, value: T, options?: {
12
+ tenantId?: string | undefined;
13
+ ttlMs?: number | undefined;
14
+ }): Promise<void>;
15
+ delete(key: string, tenantId?: string): Promise<boolean>;
16
+ list(options?: {
17
+ tenantId?: string | undefined;
18
+ prefix?: string | undefined;
19
+ limit?: number | undefined;
20
+ }): Promise<Array<{
21
+ key: string;
22
+ value: T;
23
+ }>>;
24
+ clear(tenantId?: string): Promise<void>;
25
+ }
26
+ export declare class SqliteBlobPayloadStore implements BlobPayloadStore {
27
+ private readonly db;
28
+ readonly namespace: string;
29
+ constructor(db: DatabaseSync, namespace?: string);
30
+ put(handle: string, data: string | Uint8Array, options?: BlobStorePutOptions): Promise<BlobPayload>;
31
+ get(handle: string, options?: {
32
+ tenantId?: string | undefined;
33
+ principalId?: string | undefined;
34
+ }): Promise<BlobPayload | null>;
35
+ delete(handle: string, options?: {
36
+ tenantId?: string | undefined;
37
+ principalId?: string | undefined;
38
+ }): Promise<boolean>;
39
+ pruneExpired(): Promise<number>;
40
+ }
41
+ export declare class SqliteTelemetryRingBuffer implements TelemetryRingBuffer {
42
+ private readonly db;
43
+ private readonly maxEntries;
44
+ constructor(db: DatabaseSync, options?: TelemetryRingBufferOptions);
45
+ push(event: TelemetryEvent): Promise<void>;
46
+ pushBatch(events: TelemetryEvent[]): Promise<void>;
47
+ private pruneBuffer;
48
+ query(options?: TelemetryQueryOptions): Promise<TelemetryEvent[]>;
49
+ clear(tenantId?: string): Promise<void>;
50
+ }
51
+ export declare class SqliteStorageDriver implements StorageDriver {
52
+ readonly id = "sqlite";
53
+ isConnected: boolean;
54
+ private db;
55
+ private readonly resolvedPath;
56
+ private readonly busyTimeoutMs;
57
+ private readonly kvStores;
58
+ private readonly blobStores;
59
+ private telemetryBuffer;
60
+ constructor(options?: SqliteStorageDriverOptions);
61
+ init(): Promise<void>;
62
+ close(): Promise<void>;
63
+ ping(): Promise<boolean>;
64
+ getKeyValueStore<T = unknown>(namespace: string): KeyValueStore<T>;
65
+ getBlobPayloadStore(namespace?: string): BlobPayloadStore;
66
+ getTelemetryRingBuffer(options?: TelemetryRingBufferOptions): TelemetryRingBuffer;
67
+ }
68
+ export declare function createSqliteStorageDriver(options?: SqliteStorageDriverOptions): SqliteStorageDriver;
69
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
package/dist/sqlite.js ADDED
@@ -0,0 +1,439 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { dirname, resolve } from "node:path";
4
+ import { homedir } from "node:os";
5
+ import { StorageError, StoragePayloadTooLargeError } from "./types.js";
6
+ const DEFAULT_MAX_BLOB_BYTES = 10 * 1024 * 1024; // 10 MiB
7
+ const DEFAULT_MAX_TELEMETRY_ENTRIES = 10_000;
8
+ function resolveDbPath(inputPath) {
9
+ if (!inputPath || inputPath === ":memory:") {
10
+ return ":memory:";
11
+ }
12
+ if (inputPath.startsWith("~/")) {
13
+ return resolve(homedir(), inputPath.slice(2));
14
+ }
15
+ return resolve(process.cwd(), inputPath);
16
+ }
17
+ export class SqliteKeyValueStore {
18
+ db;
19
+ namespace;
20
+ constructor(db, namespace) {
21
+ this.db = db;
22
+ this.namespace = namespace;
23
+ }
24
+ async get(key, tenantId) {
25
+ const tid = tenantId ?? "";
26
+ const stmt = this.db.prepare(`
27
+ SELECT value, expires_at FROM chainmcp_kv
28
+ WHERE namespace = ? AND tenant_id = ? AND key = ?
29
+ `);
30
+ const row = stmt.get(this.namespace, tid, key);
31
+ if (!row) {
32
+ return null;
33
+ }
34
+ if (row.expires_at !== null && Date.now() > row.expires_at) {
35
+ const del = this.db.prepare(`
36
+ DELETE FROM chainmcp_kv
37
+ WHERE namespace = ? AND tenant_id = ? AND key = ?
38
+ `);
39
+ del.run(this.namespace, tid, key);
40
+ return null;
41
+ }
42
+ try {
43
+ return JSON.parse(row.value);
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ async set(key, value, options) {
50
+ const tid = options?.tenantId ?? "";
51
+ const now = Date.now();
52
+ const expiresAt = options?.ttlMs ? now + options.ttlMs : null;
53
+ const serialized = JSON.stringify(value);
54
+ const stmt = this.db.prepare(`
55
+ INSERT INTO chainmcp_kv (namespace, tenant_id, key, value, created_at, expires_at)
56
+ VALUES (?, ?, ?, ?, ?, ?)
57
+ ON CONFLICT(namespace, tenant_id, key) DO UPDATE SET
58
+ value = excluded.value,
59
+ created_at = excluded.created_at,
60
+ expires_at = excluded.expires_at
61
+ `);
62
+ stmt.run(this.namespace, tid, key, serialized, now, expiresAt);
63
+ }
64
+ async delete(key, tenantId) {
65
+ const tid = tenantId ?? "";
66
+ const stmt = this.db.prepare(`
67
+ DELETE FROM chainmcp_kv
68
+ WHERE namespace = ? AND tenant_id = ? AND key = ?
69
+ `);
70
+ const result = stmt.run(this.namespace, tid, key);
71
+ return Number(result.changes) > 0;
72
+ }
73
+ async list(options) {
74
+ const tid = options?.tenantId ?? "";
75
+ const limit = options?.limit ?? 100;
76
+ const now = Date.now();
77
+ const prefix = options?.prefix ?? "";
78
+ const stmt = this.db.prepare(`
79
+ SELECT key, value, expires_at FROM chainmcp_kv
80
+ WHERE namespace = ? AND tenant_id = ? AND key LIKE ?
81
+ ORDER BY key ASC
82
+ LIMIT ?
83
+ `);
84
+ const rows = stmt.all(this.namespace, tid, `${prefix}%`, limit);
85
+ const results = [];
86
+ for (const row of rows) {
87
+ if (row.expires_at !== null && now > row.expires_at) {
88
+ continue;
89
+ }
90
+ try {
91
+ results.push({
92
+ key: row.key,
93
+ value: JSON.parse(row.value),
94
+ });
95
+ }
96
+ catch {
97
+ // Skip unparseable
98
+ }
99
+ }
100
+ return results;
101
+ }
102
+ async clear(tenantId) {
103
+ if (tenantId !== undefined) {
104
+ const stmt = this.db.prepare(`
105
+ DELETE FROM chainmcp_kv
106
+ WHERE namespace = ? AND tenant_id = ?
107
+ `);
108
+ stmt.run(this.namespace, tenantId);
109
+ }
110
+ else {
111
+ const stmt = this.db.prepare(`
112
+ DELETE FROM chainmcp_kv
113
+ WHERE namespace = ?
114
+ `);
115
+ stmt.run(this.namespace);
116
+ }
117
+ }
118
+ }
119
+ export class SqliteBlobPayloadStore {
120
+ db;
121
+ namespace;
122
+ constructor(db, namespace = "default") {
123
+ this.db = db;
124
+ this.namespace = namespace;
125
+ }
126
+ async put(handle, data, options) {
127
+ const strData = typeof data === "string" ? data : new TextDecoder().decode(data);
128
+ const byteSize = Buffer.byteLength(strData, "utf8");
129
+ const maxBytes = options?.maxByteSize ?? DEFAULT_MAX_BLOB_BYTES;
130
+ if (byteSize > maxBytes) {
131
+ throw new StoragePayloadTooLargeError(byteSize, maxBytes);
132
+ }
133
+ const tid = options?.tenantId ?? "";
134
+ const pid = options?.principalId ?? null;
135
+ const now = Date.now();
136
+ const expiresAt = options?.ttlMs ? now + options.ttlMs : null;
137
+ const stmt = this.db.prepare(`
138
+ INSERT INTO chainmcp_blobs (namespace, handle, tenant_id, principal_id, data, byte_size, created_at, expires_at)
139
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
140
+ ON CONFLICT(namespace, tenant_id, handle) DO UPDATE SET
141
+ principal_id = excluded.principal_id,
142
+ data = excluded.data,
143
+ byte_size = excluded.byte_size,
144
+ created_at = excluded.created_at,
145
+ expires_at = excluded.expires_at
146
+ `);
147
+ stmt.run(this.namespace, handle, tid, pid, strData, byteSize, now, expiresAt);
148
+ return {
149
+ handle,
150
+ data: strData,
151
+ byteSize,
152
+ tenantId: options?.tenantId,
153
+ principalId: options?.principalId,
154
+ createdAt: now,
155
+ expiresAt: expiresAt ?? undefined,
156
+ };
157
+ }
158
+ async get(handle, options) {
159
+ const tid = options?.tenantId ?? "";
160
+ const stmt = this.db.prepare(`
161
+ SELECT principal_id, data, byte_size, created_at, expires_at
162
+ FROM chainmcp_blobs
163
+ WHERE namespace = ? AND tenant_id = ? AND handle = ?
164
+ `);
165
+ const row = stmt.get(this.namespace, tid, handle);
166
+ if (!row) {
167
+ return null;
168
+ }
169
+ if (row.expires_at !== null && Date.now() > row.expires_at) {
170
+ const del = this.db.prepare(`
171
+ DELETE FROM chainmcp_blobs
172
+ WHERE namespace = ? AND tenant_id = ? AND handle = ?
173
+ `);
174
+ del.run(this.namespace, tid, handle);
175
+ return null;
176
+ }
177
+ if (options?.principalId && row.principal_id !== options.principalId) {
178
+ return null;
179
+ }
180
+ return {
181
+ handle,
182
+ data: row.data,
183
+ byteSize: row.byte_size,
184
+ tenantId: options?.tenantId,
185
+ principalId: row.principal_id ?? undefined,
186
+ createdAt: row.created_at,
187
+ expiresAt: row.expires_at ?? undefined,
188
+ };
189
+ }
190
+ async delete(handle, options) {
191
+ const tid = options?.tenantId ?? "";
192
+ if (options?.principalId) {
193
+ const stmt = this.db.prepare(`
194
+ DELETE FROM chainmcp_blobs
195
+ WHERE namespace = ? AND tenant_id = ? AND handle = ? AND principal_id = ?
196
+ `);
197
+ const result = stmt.run(this.namespace, tid, handle, options.principalId);
198
+ return Number(result.changes) > 0;
199
+ }
200
+ else {
201
+ const stmt = this.db.prepare(`
202
+ DELETE FROM chainmcp_blobs
203
+ WHERE namespace = ? AND tenant_id = ? AND handle = ?
204
+ `);
205
+ const result = stmt.run(this.namespace, tid, handle);
206
+ return Number(result.changes) > 0;
207
+ }
208
+ }
209
+ async pruneExpired() {
210
+ const stmt = this.db.prepare(`
211
+ DELETE FROM chainmcp_blobs
212
+ WHERE namespace = ? AND expires_at IS NOT NULL AND expires_at < ?
213
+ `);
214
+ const result = stmt.run(this.namespace, Date.now());
215
+ return Number(result.changes);
216
+ }
217
+ }
218
+ export class SqliteTelemetryRingBuffer {
219
+ db;
220
+ maxEntries;
221
+ constructor(db, options) {
222
+ this.db = db;
223
+ this.maxEntries = options?.maxEntries ?? DEFAULT_MAX_TELEMETRY_ENTRIES;
224
+ }
225
+ async push(event) {
226
+ const stmt = this.db.prepare(`
227
+ INSERT INTO chainmcp_telemetry (id, timestamp, tenant_id, tool_name, duration_ms, is_error, error_code, cached, token_count, metadata)
228
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
229
+ `);
230
+ stmt.run(event.id, event.timestamp, event.tenantId ?? null, event.toolName ?? null, event.durationMs ?? null, event.isError ? 1 : 0, event.errorCode ?? null, event.cached ? 1 : 0, event.tokenCount ?? null, event.metadata ? JSON.stringify(event.metadata) : null);
231
+ this.pruneBuffer();
232
+ }
233
+ async pushBatch(events) {
234
+ if (events.length === 0)
235
+ return;
236
+ this.db.exec("BEGIN TRANSACTION;");
237
+ try {
238
+ const stmt = this.db.prepare(`
239
+ INSERT INTO chainmcp_telemetry (id, timestamp, tenant_id, tool_name, duration_ms, is_error, error_code, cached, token_count, metadata)
240
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
241
+ `);
242
+ for (const event of events) {
243
+ stmt.run(event.id, event.timestamp, event.tenantId ?? null, event.toolName ?? null, event.durationMs ?? null, event.isError ? 1 : 0, event.errorCode ?? null, event.cached ? 1 : 0, event.tokenCount ?? null, event.metadata ? JSON.stringify(event.metadata) : null);
244
+ }
245
+ this.db.exec("COMMIT;");
246
+ }
247
+ catch (err) {
248
+ this.db.exec("ROLLBACK;");
249
+ throw err;
250
+ }
251
+ this.pruneBuffer();
252
+ }
253
+ pruneBuffer() {
254
+ const pruneStmt = this.db.prepare(`
255
+ DELETE FROM chainmcp_telemetry
256
+ WHERE id NOT IN (
257
+ SELECT id FROM chainmcp_telemetry
258
+ ORDER BY timestamp DESC
259
+ LIMIT ?
260
+ )
261
+ `);
262
+ pruneStmt.run(this.maxEntries);
263
+ }
264
+ async query(options) {
265
+ let sql = "SELECT * FROM chainmcp_telemetry WHERE 1=1";
266
+ const params = [];
267
+ if (options?.tenantId) {
268
+ sql += " AND tenant_id = ?";
269
+ params.push(options.tenantId);
270
+ }
271
+ if (options?.toolName) {
272
+ sql += " AND tool_name = ?";
273
+ params.push(options.toolName);
274
+ }
275
+ if (options?.since) {
276
+ sql += " AND timestamp >= ?";
277
+ params.push(options.since);
278
+ }
279
+ sql += " ORDER BY timestamp ASC LIMIT ?";
280
+ params.push(options?.limit ?? 100);
281
+ const stmt = this.db.prepare(sql);
282
+ const rows = stmt.all(...params);
283
+ return rows.map((r) => ({
284
+ id: r.id,
285
+ timestamp: r.timestamp,
286
+ tenantId: r.tenant_id ?? undefined,
287
+ toolName: r.tool_name ?? undefined,
288
+ durationMs: r.duration_ms ?? undefined,
289
+ isError: r.is_error === 1,
290
+ errorCode: r.error_code ?? undefined,
291
+ cached: r.cached === 1,
292
+ tokenCount: r.token_count ?? undefined,
293
+ metadata: r.metadata ? JSON.parse(r.metadata) : undefined,
294
+ }));
295
+ }
296
+ async clear(tenantId) {
297
+ if (tenantId) {
298
+ const stmt = this.db.prepare("DELETE FROM chainmcp_telemetry WHERE tenant_id = ?");
299
+ stmt.run(tenantId);
300
+ }
301
+ else {
302
+ this.db.exec("DELETE FROM chainmcp_telemetry;");
303
+ }
304
+ }
305
+ }
306
+ export class SqliteStorageDriver {
307
+ id = "sqlite";
308
+ isConnected = false;
309
+ db = undefined;
310
+ resolvedPath;
311
+ busyTimeoutMs;
312
+ kvStores = new Map();
313
+ blobStores = new Map();
314
+ telemetryBuffer = undefined;
315
+ constructor(options) {
316
+ this.resolvedPath = resolveDbPath(options?.path);
317
+ this.busyTimeoutMs = options?.busyTimeoutMs ?? 5000;
318
+ }
319
+ async init() {
320
+ if (this.isConnected) {
321
+ return;
322
+ }
323
+ if (this.resolvedPath !== ":memory:") {
324
+ await mkdir(dirname(this.resolvedPath), { recursive: true });
325
+ }
326
+ try {
327
+ this.db = new DatabaseSync(this.resolvedPath);
328
+ if (this.resolvedPath !== ":memory:") {
329
+ this.db.exec("PRAGMA journal_mode = WAL;");
330
+ this.db.exec("PRAGMA synchronous = NORMAL;");
331
+ }
332
+ this.db.exec(`PRAGMA busy_timeout = ${this.busyTimeoutMs};`);
333
+ this.db.exec("PRAGMA foreign_keys = ON;");
334
+ this.db.exec(`
335
+ CREATE TABLE IF NOT EXISTS chainmcp_kv (
336
+ namespace TEXT NOT NULL,
337
+ tenant_id TEXT NOT NULL DEFAULT '',
338
+ key TEXT NOT NULL,
339
+ value TEXT NOT NULL,
340
+ created_at INTEGER NOT NULL,
341
+ expires_at INTEGER,
342
+ PRIMARY KEY (namespace, tenant_id, key)
343
+ );
344
+ CREATE INDEX IF NOT EXISTS idx_chainmcp_kv_exp ON chainmcp_kv (expires_at);
345
+
346
+ CREATE TABLE IF NOT EXISTS chainmcp_blobs (
347
+ namespace TEXT NOT NULL,
348
+ handle TEXT NOT NULL,
349
+ tenant_id TEXT NOT NULL DEFAULT '',
350
+ principal_id TEXT,
351
+ data TEXT NOT NULL,
352
+ byte_size INTEGER NOT NULL,
353
+ created_at INTEGER NOT NULL,
354
+ expires_at INTEGER,
355
+ PRIMARY KEY (namespace, tenant_id, handle)
356
+ );
357
+ CREATE INDEX IF NOT EXISTS idx_chainmcp_blobs_exp ON chainmcp_blobs (expires_at);
358
+
359
+ CREATE TABLE IF NOT EXISTS chainmcp_telemetry (
360
+ id TEXT PRIMARY KEY,
361
+ timestamp INTEGER NOT NULL,
362
+ tenant_id TEXT,
363
+ tool_name TEXT,
364
+ duration_ms REAL,
365
+ is_error INTEGER NOT NULL DEFAULT 0,
366
+ error_code TEXT,
367
+ cached INTEGER NOT NULL DEFAULT 0,
368
+ token_count INTEGER,
369
+ metadata TEXT
370
+ );
371
+ CREATE INDEX IF NOT EXISTS idx_chainmcp_telemetry_ts ON chainmcp_telemetry (timestamp);
372
+ CREATE INDEX IF NOT EXISTS idx_chainmcp_telemetry_tenant ON chainmcp_telemetry (tenant_id);
373
+ `);
374
+ this.isConnected = true;
375
+ }
376
+ catch (err) {
377
+ throw new StorageError("SQLITE_INIT_FAILED", `Failed to initialize SQLite storage at '${this.resolvedPath}': ${err.message}`, { cause: err });
378
+ }
379
+ }
380
+ async close() {
381
+ if (!this.isConnected || !this.db) {
382
+ return;
383
+ }
384
+ this.isConnected = false;
385
+ this.kvStores.clear();
386
+ this.blobStores.clear();
387
+ this.telemetryBuffer = undefined;
388
+ this.db.close();
389
+ this.db = undefined;
390
+ }
391
+ async ping() {
392
+ if (!this.isConnected || !this.db) {
393
+ return false;
394
+ }
395
+ try {
396
+ const stmt = this.db.prepare("SELECT 1 as alive;");
397
+ const res = stmt.get();
398
+ return res?.alive === 1;
399
+ }
400
+ catch {
401
+ return false;
402
+ }
403
+ }
404
+ getKeyValueStore(namespace) {
405
+ if (!this.db || !this.isConnected) {
406
+ throw new StorageError("NOT_CONNECTED", "Storage driver is not initialized");
407
+ }
408
+ let store = this.kvStores.get(namespace);
409
+ if (!store) {
410
+ store = new SqliteKeyValueStore(this.db, namespace);
411
+ this.kvStores.set(namespace, store);
412
+ }
413
+ return store;
414
+ }
415
+ getBlobPayloadStore(namespace = "default") {
416
+ if (!this.db || !this.isConnected) {
417
+ throw new StorageError("NOT_CONNECTED", "Storage driver is not initialized");
418
+ }
419
+ let store = this.blobStores.get(namespace);
420
+ if (!store) {
421
+ store = new SqliteBlobPayloadStore(this.db, namespace);
422
+ this.blobStores.set(namespace, store);
423
+ }
424
+ return store;
425
+ }
426
+ getTelemetryRingBuffer(options) {
427
+ if (!this.db || !this.isConnected) {
428
+ throw new StorageError("NOT_CONNECTED", "Storage driver is not initialized");
429
+ }
430
+ if (!this.telemetryBuffer) {
431
+ this.telemetryBuffer = new SqliteTelemetryRingBuffer(this.db, options);
432
+ }
433
+ return this.telemetryBuffer;
434
+ }
435
+ }
436
+ export function createSqliteStorageDriver(options) {
437
+ return new SqliteStorageDriver(options);
438
+ }
439
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ export declare class StorageError extends Error {
2
+ readonly code: string;
3
+ constructor(code: string, message: string, options?: ErrorOptions);
4
+ }
5
+ export declare class StoragePayloadTooLargeError extends StorageError {
6
+ constructor(byteSize: number, maxBytes: number);
7
+ }
8
+ export interface StorageDriverOptions {
9
+ path?: string | undefined;
10
+ readOnly?: boolean | undefined;
11
+ }
12
+ export interface StorageDriver {
13
+ readonly id: string;
14
+ readonly isConnected: boolean;
15
+ init(): Promise<void>;
16
+ close(): Promise<void>;
17
+ ping(): Promise<boolean>;
18
+ getKeyValueStore<T = unknown>(namespace: string): KeyValueStore<T>;
19
+ getBlobPayloadStore(namespace?: string): BlobPayloadStore;
20
+ getTelemetryRingBuffer(options?: TelemetryRingBufferOptions): TelemetryRingBuffer;
21
+ }
22
+ export interface KeyValueStore<T = unknown> {
23
+ readonly namespace: string;
24
+ get(key: string, tenantId?: string): Promise<T | null>;
25
+ set(key: string, value: T, options?: {
26
+ tenantId?: string | undefined;
27
+ ttlMs?: number | undefined;
28
+ }): Promise<void>;
29
+ delete(key: string, tenantId?: string): Promise<boolean>;
30
+ list(options?: {
31
+ tenantId?: string | undefined;
32
+ prefix?: string | undefined;
33
+ limit?: number | undefined;
34
+ }): Promise<Array<{
35
+ key: string;
36
+ value: T;
37
+ }>>;
38
+ clear(tenantId?: string): Promise<void>;
39
+ }
40
+ export interface BlobPayload {
41
+ handle: string;
42
+ data: string;
43
+ byteSize: number;
44
+ tenantId?: string | undefined;
45
+ principalId?: string | undefined;
46
+ createdAt: number;
47
+ expiresAt?: number | undefined;
48
+ }
49
+ export interface BlobStorePutOptions {
50
+ tenantId?: string | undefined;
51
+ principalId?: string | undefined;
52
+ ttlMs?: number | undefined;
53
+ maxByteSize?: number | undefined;
54
+ }
55
+ export interface BlobPayloadStore {
56
+ readonly namespace: string;
57
+ put(handle: string, data: string | Uint8Array, options?: BlobStorePutOptions): Promise<BlobPayload>;
58
+ get(handle: string, options?: {
59
+ tenantId?: string | undefined;
60
+ principalId?: string | undefined;
61
+ }): Promise<BlobPayload | null>;
62
+ delete(handle: string, options?: {
63
+ tenantId?: string | undefined;
64
+ principalId?: string | undefined;
65
+ }): Promise<boolean>;
66
+ pruneExpired(): Promise<number>;
67
+ }
68
+ export interface TelemetryEvent {
69
+ id: string;
70
+ timestamp: number;
71
+ tenantId?: string | undefined;
72
+ toolName?: string | undefined;
73
+ durationMs?: number | undefined;
74
+ isError?: boolean | undefined;
75
+ errorCode?: string | undefined;
76
+ cached?: boolean | undefined;
77
+ tokenCount?: number | undefined;
78
+ metadata?: Record<string, unknown> | undefined;
79
+ }
80
+ export interface TelemetryRingBufferOptions {
81
+ maxEntries?: number | undefined;
82
+ retentionMs?: number | undefined;
83
+ }
84
+ export interface TelemetryQueryOptions {
85
+ tenantId?: string | undefined;
86
+ toolName?: string | undefined;
87
+ since?: number | undefined;
88
+ limit?: number | undefined;
89
+ }
90
+ export interface TelemetryRingBuffer {
91
+ push(event: TelemetryEvent): Promise<void>;
92
+ pushBatch(events: TelemetryEvent[]): Promise<void>;
93
+ query(options?: TelemetryQueryOptions): Promise<TelemetryEvent[]>;
94
+ clear(tenantId?: string): Promise<void>;
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,14 @@
1
+ export class StorageError extends Error {
2
+ code;
3
+ constructor(code, message, options) {
4
+ super(message, options);
5
+ this.name = "StorageError";
6
+ this.code = code;
7
+ }
8
+ }
9
+ export class StoragePayloadTooLargeError extends StorageError {
10
+ constructor(byteSize, maxBytes) {
11
+ super("PAYLOAD_TOO_LARGE", `Payload size of ${byteSize} bytes exceeds the maximum allowed limit of ${maxBytes} bytes`);
12
+ }
13
+ }
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrB,IAAI,CAAS;IAE7B,YAAY,IAAY,EAAE,OAAe,EAAE,OAAsB;QAC/D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,YAAY;IAC3D,YAAY,QAAgB,EAAE,QAAgB;QAC5C,KAAK,CACH,mBAAmB,EACnB,mBAAmB,QAAQ,+CAA+C,QAAQ,QAAQ,CAC3F,CAAC;IACJ,CAAC;CACF"}