@frontmcp/storage-sqlite 0.1.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/LICENSE +201 -0
- package/encryption.d.ts +31 -0
- package/encryption.d.ts.map +1 -0
- package/esm/index.mjs +533 -0
- package/esm/package.json +57 -0
- package/index.d.ts +17 -0
- package/index.d.ts.map +1 -0
- package/index.js +553 -0
- package/package.json +57 -0
- package/sqlite-elicitation.store.d.ts +112 -0
- package/sqlite-elicitation.store.d.ts.map +1 -0
- package/sqlite-event.store.d.ts +69 -0
- package/sqlite-event.store.d.ts.map +1 -0
- package/sqlite-kv.store.d.ts +98 -0
- package/sqlite-kv.store.d.ts.map +1 -0
- package/sqlite-session.store.d.ts +55 -0
- package/sqlite-session.store.d.ts.map +1 -0
- package/sqlite.options.d.ts +51 -0
- package/sqlite.options.d.ts.map +1 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Elicitation Store
|
|
3
|
+
*
|
|
4
|
+
* Implements the ElicitationStore interface using SQLite KV store.
|
|
5
|
+
* Uses Node.js EventEmitter for single-process pub/sub (replaces Redis pub/sub).
|
|
6
|
+
* Suitable for local-only deployments (no distributed pub/sub needed).
|
|
7
|
+
*/
|
|
8
|
+
import { SqliteKvStore } from './sqlite-kv.store';
|
|
9
|
+
import type { SqliteStorageOptions } from './sqlite.options';
|
|
10
|
+
/**
|
|
11
|
+
* Pending elicitation record.
|
|
12
|
+
* Matches PendingElicitRecord from @frontmcp/sdk.
|
|
13
|
+
*/
|
|
14
|
+
export interface PendingElicitRecord {
|
|
15
|
+
elicitId: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
createdAt: number;
|
|
18
|
+
expiresAt: number;
|
|
19
|
+
message: string;
|
|
20
|
+
mode: string;
|
|
21
|
+
requestedSchema?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Pending fallback record.
|
|
25
|
+
* Matches PendingElicitFallback from @frontmcp/sdk.
|
|
26
|
+
*/
|
|
27
|
+
export type PendingElicitFallback = Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Elicit result type.
|
|
30
|
+
*/
|
|
31
|
+
export type ElicitResult<T = unknown> = {
|
|
32
|
+
status: string;
|
|
33
|
+
content?: T;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Resolved elicit result stored for re-invocation.
|
|
38
|
+
*/
|
|
39
|
+
export type ResolvedElicitResult = Record<string, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* Fallback execution result.
|
|
42
|
+
*/
|
|
43
|
+
export type FallbackExecutionResult = Record<string, unknown>;
|
|
44
|
+
export type ElicitResultCallback<T = unknown> = (result: ElicitResult<T>) => void;
|
|
45
|
+
export type FallbackResultCallback = (result: FallbackExecutionResult) => void;
|
|
46
|
+
export type ElicitUnsubscribe = () => Promise<void>;
|
|
47
|
+
export interface SqliteElicitationStoreOptions extends SqliteStorageOptions {
|
|
48
|
+
/** Key prefix for elicitation keys. @default 'mcp:elicit:' */
|
|
49
|
+
keyPrefix?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Elicitation store interface.
|
|
53
|
+
* Matches ElicitationStore from @frontmcp/sdk.
|
|
54
|
+
*/
|
|
55
|
+
export interface ElicitationStoreInterface {
|
|
56
|
+
setPending(record: PendingElicitRecord): Promise<void>;
|
|
57
|
+
getPending(sessionId: string): Promise<PendingElicitRecord | null>;
|
|
58
|
+
deletePending(sessionId: string): Promise<void>;
|
|
59
|
+
subscribeResult<T = unknown>(elicitId: string, callback: ElicitResultCallback<T>, sessionId?: string): Promise<ElicitUnsubscribe>;
|
|
60
|
+
publishResult<T = unknown>(elicitId: string, sessionId: string, result: ElicitResult<T>): Promise<void>;
|
|
61
|
+
destroy?(): Promise<void>;
|
|
62
|
+
setPendingFallback(record: PendingElicitFallback): Promise<void>;
|
|
63
|
+
getPendingFallback(elicitId: string, sessionId?: string): Promise<PendingElicitFallback | null>;
|
|
64
|
+
deletePendingFallback(elicitId: string): Promise<void>;
|
|
65
|
+
setResolvedResult(elicitId: string, result: ElicitResult<unknown>, sessionId?: string): Promise<void>;
|
|
66
|
+
getResolvedResult(elicitId: string, sessionId?: string): Promise<ResolvedElicitResult | null>;
|
|
67
|
+
deleteResolvedResult(elicitId: string): Promise<void>;
|
|
68
|
+
subscribeFallbackResult(elicitId: string, callback: FallbackResultCallback, sessionId?: string): Promise<ElicitUnsubscribe>;
|
|
69
|
+
publishFallbackResult(elicitId: string, sessionId: string, result: FallbackExecutionResult): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* SQLite-backed elicitation store with EventEmitter-based pub/sub.
|
|
73
|
+
*
|
|
74
|
+
* Storage layout:
|
|
75
|
+
* - `pending:{sessionId}` - Pending elicitation records
|
|
76
|
+
* - `fallback:{elicitId}` - Fallback context
|
|
77
|
+
* - `resolved:{elicitId}` - Pre-resolved results
|
|
78
|
+
*
|
|
79
|
+
* Pub/sub channels (via EventEmitter):
|
|
80
|
+
* - `result:{elicitId}` - Elicitation results
|
|
81
|
+
* - `fallback-result:{elicitId}` - Fallback execution results
|
|
82
|
+
*/
|
|
83
|
+
export declare class SqliteElicitationStore implements ElicitationStoreInterface {
|
|
84
|
+
private kv;
|
|
85
|
+
private emitter;
|
|
86
|
+
private keyPrefix;
|
|
87
|
+
constructor(options: SqliteElicitationStoreOptions);
|
|
88
|
+
private pendingKey;
|
|
89
|
+
private fallbackKey;
|
|
90
|
+
private resolvedKey;
|
|
91
|
+
private resultChannel;
|
|
92
|
+
private fallbackResultChannel;
|
|
93
|
+
setPending(record: PendingElicitRecord): Promise<void>;
|
|
94
|
+
getPending(sessionId: string): Promise<PendingElicitRecord | null>;
|
|
95
|
+
deletePending(sessionId: string): Promise<void>;
|
|
96
|
+
subscribeResult<T = unknown>(elicitId: string, callback: ElicitResultCallback<T>, _sessionId?: string): Promise<ElicitUnsubscribe>;
|
|
97
|
+
publishResult<T = unknown>(elicitId: string, sessionId: string, result: ElicitResult<T>): Promise<void>;
|
|
98
|
+
setPendingFallback(record: PendingElicitFallback): Promise<void>;
|
|
99
|
+
getPendingFallback(elicitId: string, _sessionId?: string): Promise<PendingElicitFallback | null>;
|
|
100
|
+
deletePendingFallback(elicitId: string): Promise<void>;
|
|
101
|
+
setResolvedResult(elicitId: string, result: ElicitResult<unknown>, _sessionId?: string): Promise<void>;
|
|
102
|
+
getResolvedResult(elicitId: string, _sessionId?: string): Promise<ResolvedElicitResult | null>;
|
|
103
|
+
deleteResolvedResult(elicitId: string): Promise<void>;
|
|
104
|
+
subscribeFallbackResult(elicitId: string, callback: FallbackResultCallback, _sessionId?: string): Promise<ElicitUnsubscribe>;
|
|
105
|
+
publishFallbackResult(elicitId: string, _sessionId: string, result: FallbackExecutionResult): Promise<void>;
|
|
106
|
+
destroy(): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Get the underlying KV store (for testing/advanced use).
|
|
109
|
+
*/
|
|
110
|
+
getKvStore(): SqliteKvStore;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=sqlite-elicitation.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-elicitation.store.d.ts","sourceRoot":"","sources":["../src/sqlite-elicitation.store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Event Store
|
|
3
|
+
*
|
|
4
|
+
* Implements the EventStore interface from @modelcontextprotocol/sdk for SSE resumability.
|
|
5
|
+
* Stores events in SQLite with TTL-based expiration and max event limits.
|
|
6
|
+
*/
|
|
7
|
+
import type { SqliteStorageOptions } from './sqlite.options';
|
|
8
|
+
/**
|
|
9
|
+
* Event store interface matching @modelcontextprotocol/sdk EventStore.
|
|
10
|
+
* Redeclared here to avoid hard dependency on @modelcontextprotocol/sdk.
|
|
11
|
+
*/
|
|
12
|
+
export interface EventStoreInterface {
|
|
13
|
+
storeEvent(streamId: string, message: unknown): Promise<string>;
|
|
14
|
+
replayEventsAfter(lastEventId: string, callbacks: {
|
|
15
|
+
send: (eventId: string, message: unknown) => Promise<void>;
|
|
16
|
+
}): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
export interface SqliteEventStoreOptions extends SqliteStorageOptions {
|
|
19
|
+
/** Maximum number of events to store before eviction. @default 10000 */
|
|
20
|
+
maxEvents?: number;
|
|
21
|
+
/** TTL in milliseconds for stored events. @default 300000 (5 minutes) */
|
|
22
|
+
ttlMs?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* SQLite-backed event store for SSE resumability.
|
|
26
|
+
*
|
|
27
|
+
* Schema:
|
|
28
|
+
* ```sql
|
|
29
|
+
* CREATE TABLE IF NOT EXISTS events (
|
|
30
|
+
* id TEXT PRIMARY KEY,
|
|
31
|
+
* stream_id TEXT NOT NULL,
|
|
32
|
+
* message TEXT NOT NULL,
|
|
33
|
+
* created_at INTEGER NOT NULL
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare class SqliteEventStore implements EventStoreInterface {
|
|
38
|
+
private db;
|
|
39
|
+
private maxEvents;
|
|
40
|
+
private ttlMs;
|
|
41
|
+
private counters;
|
|
42
|
+
private cleanupTimer;
|
|
43
|
+
private stmts;
|
|
44
|
+
constructor(options: SqliteEventStoreOptions);
|
|
45
|
+
private initSchema;
|
|
46
|
+
private prepareStatements;
|
|
47
|
+
/**
|
|
48
|
+
* Return prepared statements, throwing if not yet initialized.
|
|
49
|
+
*/
|
|
50
|
+
private prepared;
|
|
51
|
+
/**
|
|
52
|
+
* Get the next counter value for a stream, rehydrating from SQLite on first use.
|
|
53
|
+
*/
|
|
54
|
+
private getNextCounter;
|
|
55
|
+
storeEvent(streamId: string, message: unknown): Promise<string>;
|
|
56
|
+
replayEventsAfter(lastEventId: string, { send }: {
|
|
57
|
+
send: (eventId: string, message: unknown) => Promise<void>;
|
|
58
|
+
}): Promise<string>;
|
|
59
|
+
private evictExpired;
|
|
60
|
+
/**
|
|
61
|
+
* Close the database connection and stop cleanup timer.
|
|
62
|
+
*/
|
|
63
|
+
close(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get the current number of stored events.
|
|
66
|
+
*/
|
|
67
|
+
get size(): number;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=sqlite-event.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-event.store.d.ts","sourceRoot":"","sources":["../src/sqlite-event.store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,iBAAiB,CACf,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GACxE,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAED,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAiB,YAAW,mBAAmB;IAC1D,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,KAAK,CAAmC;gBAEpC,OAAO,EAAE,uBAAuB;IA+B5C,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmBhB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB/D,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GACvE,OAAO,CAAC,MAAM,CAAC;IAyBlB,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAIjB;CACF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Key-Value Store
|
|
3
|
+
*
|
|
4
|
+
* Core KV store built on better-sqlite3 with Redis-compatible interface.
|
|
5
|
+
* Supports TTL expiration, optional encryption, and WAL mode.
|
|
6
|
+
*/
|
|
7
|
+
import type Database from 'better-sqlite3';
|
|
8
|
+
import type { SqliteStorageOptions } from './sqlite.options';
|
|
9
|
+
/**
|
|
10
|
+
* SQLite-backed key-value store with TTL support and optional encryption.
|
|
11
|
+
*
|
|
12
|
+
* Schema:
|
|
13
|
+
* ```sql
|
|
14
|
+
* CREATE TABLE IF NOT EXISTS kv (
|
|
15
|
+
* key TEXT PRIMARY KEY,
|
|
16
|
+
* value TEXT NOT NULL,
|
|
17
|
+
* expires_at INTEGER -- Unix timestamp ms, NULL = no expiry
|
|
18
|
+
* );
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class SqliteKvStore {
|
|
22
|
+
private db;
|
|
23
|
+
private encryptionKey;
|
|
24
|
+
private cleanupTimer;
|
|
25
|
+
private stmts;
|
|
26
|
+
constructor(options: SqliteStorageOptions);
|
|
27
|
+
private initSchema;
|
|
28
|
+
private prepareStatements;
|
|
29
|
+
/**
|
|
30
|
+
* Return prepared statements, throwing if not yet initialized.
|
|
31
|
+
*/
|
|
32
|
+
private prepared;
|
|
33
|
+
/**
|
|
34
|
+
* Get a value by key.
|
|
35
|
+
* Returns null if key doesn't exist or is expired.
|
|
36
|
+
*/
|
|
37
|
+
get(key: string): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Get a value and parse it as JSON.
|
|
40
|
+
*/
|
|
41
|
+
getJSON<T = unknown>(key: string): T | null;
|
|
42
|
+
/**
|
|
43
|
+
* Set a key-value pair with optional TTL.
|
|
44
|
+
*
|
|
45
|
+
* @param key - The key
|
|
46
|
+
* @param value - The value to store
|
|
47
|
+
* @param ttlMs - Time to live in milliseconds (optional)
|
|
48
|
+
*/
|
|
49
|
+
set(key: string, value: string, ttlMs?: number): void;
|
|
50
|
+
/**
|
|
51
|
+
* Set a key-value pair with JSON serialization and optional TTL.
|
|
52
|
+
*/
|
|
53
|
+
setJSON(key: string, value: unknown, ttlMs?: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Delete a key.
|
|
56
|
+
*/
|
|
57
|
+
del(key: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Check if a key exists (and is not expired).
|
|
60
|
+
*/
|
|
61
|
+
has(key: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* List keys matching an optional glob-like pattern.
|
|
64
|
+
* Pattern uses SQL LIKE syntax: `%` for any characters, `_` for single character.
|
|
65
|
+
*
|
|
66
|
+
* @param pattern - Optional pattern (uses SQL LIKE). Without pattern, returns all keys.
|
|
67
|
+
* @returns Array of matching key strings
|
|
68
|
+
*/
|
|
69
|
+
keys(pattern?: string): string[];
|
|
70
|
+
/**
|
|
71
|
+
* Set TTL on an existing key.
|
|
72
|
+
*
|
|
73
|
+
* @param key - The key to set expiry on
|
|
74
|
+
* @param ttlMs - Time to live in milliseconds
|
|
75
|
+
* @returns true if key exists and TTL was set, false if key doesn't exist
|
|
76
|
+
*/
|
|
77
|
+
expire(key: string, ttlMs: number): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Get remaining TTL for a key in milliseconds.
|
|
80
|
+
*
|
|
81
|
+
* @returns TTL in ms, -1 if no expiry, -2 if key doesn't exist
|
|
82
|
+
*/
|
|
83
|
+
ttl(key: string): number;
|
|
84
|
+
/**
|
|
85
|
+
* Purge all expired keys.
|
|
86
|
+
* Called periodically by the cleanup timer.
|
|
87
|
+
*/
|
|
88
|
+
purgeExpired(): number;
|
|
89
|
+
/**
|
|
90
|
+
* Close the database connection and stop cleanup timer.
|
|
91
|
+
*/
|
|
92
|
+
close(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get the underlying database instance (for advanced use cases / testing).
|
|
95
|
+
*/
|
|
96
|
+
getDatabase(): Database.Database;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=sqlite-kv.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-kv.store.d.ts","sourceRoot":"","sources":["../src/sqlite-kv.store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAe7D;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,KAAK,CAAqC;gBAEtC,OAAO,EAAE,oBAAoB;IAmCzC,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAmB/B;;OAEG;IACH,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAW3C;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IASrD;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAI1D;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAItB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKzB;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAchC;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAM3C;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAexB;;;OAGG;IACH,YAAY,IAAI,MAAM;IAKtB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,WAAW,IAAI,QAAQ,CAAC,QAAQ;CAGjC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Session Store
|
|
3
|
+
*
|
|
4
|
+
* Implements the SessionStore interface using SQLite KV store.
|
|
5
|
+
* Uses key-prefix namespace isolation for session data.
|
|
6
|
+
*/
|
|
7
|
+
import { SqliteKvStore } from './sqlite-kv.store';
|
|
8
|
+
import type { SqliteStorageOptions } from './sqlite.options';
|
|
9
|
+
/**
|
|
10
|
+
* Session store interface (matching @frontmcp/sdk SessionStore).
|
|
11
|
+
* Redeclared here to avoid hard dependency on @frontmcp/sdk.
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionStoreInterface {
|
|
14
|
+
get(sessionId: string): Promise<StoredSessionData | null>;
|
|
15
|
+
set(sessionId: string, session: StoredSessionData, ttlMs?: number): Promise<void>;
|
|
16
|
+
delete(sessionId: string): Promise<void>;
|
|
17
|
+
exists(sessionId: string): Promise<boolean>;
|
|
18
|
+
allocId(): string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Stored session data type.
|
|
22
|
+
* This is a generic JSON-serializable record that matches StoredSession from SDK.
|
|
23
|
+
*/
|
|
24
|
+
export type StoredSessionData = Record<string, unknown>;
|
|
25
|
+
export interface SqliteSessionStoreOptions extends SqliteStorageOptions {
|
|
26
|
+
/** Key prefix for session keys. @default 'mcp:session:' */
|
|
27
|
+
keyPrefix?: string;
|
|
28
|
+
/** Default TTL for sessions in milliseconds. @default 3600000 (1 hour) */
|
|
29
|
+
defaultTtlMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SQLite-backed session store.
|
|
33
|
+
* Stores sessions as JSON in the SQLite KV store with TTL support.
|
|
34
|
+
*/
|
|
35
|
+
export declare class SqliteSessionStore implements SessionStoreInterface {
|
|
36
|
+
private kv;
|
|
37
|
+
private keyPrefix;
|
|
38
|
+
private defaultTtlMs;
|
|
39
|
+
constructor(options: SqliteSessionStoreOptions);
|
|
40
|
+
private sessionKey;
|
|
41
|
+
get(sessionId: string): Promise<StoredSessionData | null>;
|
|
42
|
+
set(sessionId: string, session: StoredSessionData, ttlMs?: number): Promise<void>;
|
|
43
|
+
delete(sessionId: string): Promise<void>;
|
|
44
|
+
exists(sessionId: string): Promise<boolean>;
|
|
45
|
+
allocId(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Close the underlying SQLite connection.
|
|
48
|
+
*/
|
|
49
|
+
close(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get the underlying KV store (for testing/advanced use).
|
|
52
|
+
*/
|
|
53
|
+
getKvStore(): SqliteKvStore;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=sqlite-session.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-session.store.d.ts","sourceRoot":"","sources":["../src/sqlite-session.store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC1D,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,IAAI,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAExD,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,yBAAyB;IAM9C,OAAO,CAAC,UAAU;IAIZ,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAIzD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjF,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,UAAU,IAAI,aAAa;CAG5B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Storage Options
|
|
3
|
+
*
|
|
4
|
+
* Configuration types and Zod schema for SQLite-based storage.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* SQLite storage configuration options.
|
|
9
|
+
*/
|
|
10
|
+
export interface SqliteStorageOptions {
|
|
11
|
+
/** Path to the .sqlite database file */
|
|
12
|
+
path: string;
|
|
13
|
+
/**
|
|
14
|
+
* Encryption configuration for at-rest encryption of values.
|
|
15
|
+
* Keys are stored in plaintext (needed for lookups), values are encrypted.
|
|
16
|
+
*/
|
|
17
|
+
encryption?: {
|
|
18
|
+
/** Secret key material for AES-256-GCM encryption via HKDF-SHA256 */
|
|
19
|
+
secret: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Interval in milliseconds for purging expired keys.
|
|
23
|
+
* @default 60000
|
|
24
|
+
*/
|
|
25
|
+
ttlCleanupIntervalMs?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Enable WAL (Write-Ahead Logging) mode for better read concurrency.
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
walMode?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Zod schema for SQLite storage configuration.
|
|
34
|
+
*/
|
|
35
|
+
export declare const sqliteStorageOptionsSchema: z.ZodObject<{
|
|
36
|
+
path: z.ZodString;
|
|
37
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
38
|
+
secret: z.ZodString;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
ttlCleanupIntervalMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
41
|
+
walMode: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
/**
|
|
44
|
+
* SQLite storage input type (before Zod defaults).
|
|
45
|
+
*/
|
|
46
|
+
export type SqliteStorageOptionsInput = z.input<typeof sqliteStorageOptionsSchema>;
|
|
47
|
+
/**
|
|
48
|
+
* SQLite storage output type (after Zod defaults).
|
|
49
|
+
*/
|
|
50
|
+
export type SqliteStorageOptionsParsed = z.infer<typeof sqliteStorageOptionsSchema>;
|
|
51
|
+
//# sourceMappingURL=sqlite.options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.options.d.ts","sourceRoot":"","sources":["../src/sqlite.options.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,UAAU,CAAC,EAAE;QACX,qEAAqE;QACrE,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,0BAA0B;;;;;;;iBASrC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEnF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|