symmetry-cli 1.0.7 → 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,114 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PeerRepository = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const database_1 = require("./database");
9
- const logger_1 = require("./logger");
10
- class PeerRepository {
11
- constructor() {
12
- this.db = database_1.database;
13
- }
14
- upsert(message) {
15
- return new Promise((resolve, reject) => {
16
- this.db.run(`
17
- INSERT OR REPLACE INTO peers (
18
- key, discovery_key, gpu_memory, model_name, public, server_key, last_seen, online
19
- ) VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, TRUE)
20
- `, [
21
- message.key,
22
- message.discoveryKey,
23
- message.config.gpuMemory,
24
- message.config.modelName,
25
- message.config.public,
26
- message.config.serverKey,
27
- ], function (err) {
28
- if (err) {
29
- reject(err);
30
- }
31
- else {
32
- resolve(this.lastID);
33
- }
34
- });
35
- });
36
- }
37
- getByDiscoveryKey(discoveryKey) {
38
- return new Promise((resolve, reject) => {
39
- this.db.get("SELECT * FROM peers WHERE discovery_key = ?", [discoveryKey], (err, row) => {
40
- if (err) {
41
- reject(err);
42
- }
43
- else {
44
- resolve(row);
45
- }
46
- });
47
- });
48
- }
49
- getPeer(randomPeerRequest) {
50
- return new Promise((resolve, reject) => {
51
- const { modelName } = randomPeerRequest;
52
- this.db.get(`SELECT * FROM peers WHERE model_name = ? ORDER BY RANDOM() LIMIT 1`, [modelName], (err, row) => {
53
- if (err) {
54
- reject(err);
55
- }
56
- else {
57
- resolve(row);
58
- }
59
- });
60
- });
61
- }
62
- updateLastSeen(peerKey) {
63
- return new Promise((resolve, reject) => {
64
- this.db.run("UPDATE peers SET last_seen = ?, online = FALSE WHERE key = ?", [new Date().toISOString(), peerKey], function (err) {
65
- if (err) {
66
- console.error(chalk_1.default.red("❌ Error updating peer last seen in database:"), err);
67
- reject(err);
68
- }
69
- else {
70
- if (this.changes > 0) {
71
- logger_1.logger.info(chalk_1.default.yellow("🕒 Peer disconnected"));
72
- }
73
- else {
74
- logger_1.logger.info(chalk_1.default.yellow("⚠️ Peer not found in database"));
75
- }
76
- resolve(this.changes);
77
- }
78
- });
79
- });
80
- }
81
- async getActivePeerCount() {
82
- return new Promise((resolve, reject) => {
83
- this.db.get("SELECT COUNT(*) as count FROM peers WHERE online = TRUE", (err, row) => {
84
- if (err) {
85
- reject(err);
86
- }
87
- else {
88
- resolve(row.count);
89
- }
90
- });
91
- });
92
- }
93
- async getActiveModelCount() {
94
- return new Promise((resolve, reject) => {
95
- this.db.get("SELECT COUNT(DISTINCT model_name) as count FROM peers WHERE online = TRUE", (err, row) => {
96
- if (err) {
97
- reject(err);
98
- }
99
- else {
100
- resolve(row.count);
101
- }
102
- });
103
- });
104
- }
105
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
- updateStats(peerKey, data) {
107
- // TODO: Update stats in database
108
- logger_1.logger.info(peerKey, data);
109
- }
110
- }
111
- exports.PeerRepository = PeerRepository;
112
- module.exports = {
113
- PeerRepository,
114
- };
package/dist/provider.js DELETED
@@ -1,307 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SymmetryProvider = void 0;
7
- const node_stream_1 = require("node:stream");
8
- const promises_1 = require("stream/promises");
9
- const chalk_1 = __importDefault(require("chalk"));
10
- const hyperswarm_1 = __importDefault(require("hyperswarm"));
11
- const hypercore_crypto_1 = __importDefault(require("hypercore-crypto"));
12
- const node_fs_1 = __importDefault(require("node:fs"));
13
- const config_1 = require("./config");
14
- const utils_1 = require("./utils");
15
- const logger_1 = require("./logger");
16
- const constants_1 = require("./constants");
17
- class SymmetryProvider {
18
- constructor(configPath) {
19
- this._challenge = null;
20
- this._conversationIndex = 0;
21
- this._discoveryKey = null;
22
- this._isPublic = false;
23
- this._providerConnections = 0;
24
- this._providerSwarm = null;
25
- this._serverSwarm = null;
26
- this._serverPeer = null;
27
- logger_1.logger.info(`🔗 Initializing client using config file: ${configPath}`);
28
- this._config = new config_1.ConfigManager(configPath);
29
- this._isPublic = this._config.get("public");
30
- }
31
- async init() {
32
- this._providerSwarm = new hyperswarm_1.default({
33
- maxConnections: this._config.get("maxConnections"),
34
- });
35
- const keyPair = hypercore_crypto_1.default.keyPair(Buffer.alloc(32).fill(this._config.get("name")));
36
- this._discoveryKey = hypercore_crypto_1.default.discoveryKey(keyPair.publicKey);
37
- const discovery = this._providerSwarm.join(this._discoveryKey, {
38
- server: true,
39
- client: true,
40
- });
41
- await discovery.flushed();
42
- this._providerSwarm.on("error", (err) => {
43
- logger_1.logger.error(chalk_1.default.red("🚨 Swarm Error:"), err);
44
- });
45
- this._providerSwarm.on("connection", (peer) => {
46
- logger_1.logger.info(`⚡️ New connection from peer: ${peer.rawStream.remoteHost}`);
47
- this.listeners(peer);
48
- });
49
- logger_1.logger.info(`📁 Symmetry client initialized.`);
50
- logger_1.logger.info(`🔑 Discovery key: ${this._discoveryKey.toString("hex")}`);
51
- if (this._isPublic) {
52
- logger_1.logger.info(chalk_1.default.white(`🔑 Server key: ${this._config.get("serverKey")}`));
53
- logger_1.logger.info(chalk_1.default.white("🔗 Joining server, please wait."));
54
- this.joinServer();
55
- }
56
- process.on("SIGINT", async () => {
57
- var _a;
58
- await ((_a = this._providerSwarm) === null || _a === void 0 ? void 0 : _a.destroy());
59
- process.exit(0);
60
- });
61
- process.on("uncaughtException", (err) => {
62
- if (err.message === "connection reset by peer") {
63
- this._providerConnections = Math.max(0, this._providerConnections - 1);
64
- }
65
- });
66
- }
67
- async destroySwarms() {
68
- var _a, _b;
69
- await ((_a = this._providerSwarm) === null || _a === void 0 ? void 0 : _a.destroy());
70
- await ((_b = this._serverSwarm) === null || _b === void 0 ? void 0 : _b.destroy());
71
- }
72
- async testProviderCall() {
73
- const testCall = async () => {
74
- logger_1.logger.info(chalk_1.default.white(`👋 Saying hello to your provider...`));
75
- const testMessages = [
76
- { role: "user", content: "Hello, this is a test message." },
77
- ];
78
- const req = this.buildStreamRequest(testMessages);
79
- if (!req) {
80
- logger_1.logger.error(chalk_1.default.red("❌ Failed to build test request"));
81
- throw new Error("Failed to build test request");
82
- }
83
- const { requestOptions, requestBody } = req;
84
- const { protocol, hostname, port, path, method, headers } = requestOptions;
85
- const url = `${protocol}://${hostname}:${port}${path}`;
86
- logger_1.logger.info(chalk_1.default.white(`🚀 Sending test request to ${url}`));
87
- try {
88
- const response = await fetch(url, {
89
- method,
90
- headers,
91
- body: JSON.stringify(requestBody),
92
- });
93
- if (!response.ok) {
94
- logger_1.logger.error(chalk_1.default.red(`❌ Server responded with status code: ${response.status}`));
95
- this.destroySwarms();
96
- throw new Error(`Server responded with status code: ${response.status}`);
97
- }
98
- if (!response.body) {
99
- logger_1.logger.error(chalk_1.default.red("❌ Failed to get a ReadableStream from the response"));
100
- this.destroySwarms();
101
- throw new Error("Failed to get a ReadableStream from the response");
102
- }
103
- logger_1.logger.info(chalk_1.default.white(`📡 Got response, checking stream...`));
104
- const reader = response.body.getReader();
105
- const { done } = await reader.read();
106
- if (done) {
107
- logger_1.logger.error(chalk_1.default.red("❌ Stream ended without data"));
108
- this.destroySwarms();
109
- throw new Error("Stream ended without data");
110
- }
111
- logger_1.logger.info(chalk_1.default.green(`✅ Test inference call successful!`));
112
- }
113
- catch (error) {
114
- this.destroySwarms();
115
- logger_1.logger.error(chalk_1.default.red(`❌ Error during test inference call: ${error}`));
116
- throw error;
117
- }
118
- logger_1.logger.info(chalk_1.default.white(`🔗 Test call successful!`));
119
- };
120
- setTimeout(() => testCall(), constants_1.PROVIDER_HELLO_TIMEOUT);
121
- }
122
- async joinServer() {
123
- this._serverSwarm = new hyperswarm_1.default();
124
- const serverKey = Buffer.from(this._config.get("serverKey"));
125
- this._serverSwarm.join(hypercore_crypto_1.default.discoveryKey(serverKey), {
126
- client: true,
127
- server: false,
128
- });
129
- this._serverSwarm.flush();
130
- this._serverSwarm.on("connection", (peer) => {
131
- var _a;
132
- this._serverPeer = peer;
133
- logger_1.logger.info(chalk_1.default.green("🔗 Connected to server."));
134
- this.testProviderCall();
135
- this._challenge = hypercore_crypto_1.default.randomBytes(32);
136
- this._serverPeer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.challenge, {
137
- challenge: this._challenge,
138
- }));
139
- this._serverPeer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.join, {
140
- ...this._config.getAll(),
141
- discoveryKey: (_a = this._discoveryKey) === null || _a === void 0 ? void 0 : _a.toString("hex"),
142
- }));
143
- this._serverPeer.on("data", async (buffer) => {
144
- var _a;
145
- if (!buffer)
146
- return;
147
- const data = (0, utils_1.safeParseJson)(buffer.toString());
148
- if (data && data.key) {
149
- switch (data.key) {
150
- case constants_1.serverMessageKeys.challenge:
151
- this.handleServerVerification(data.data);
152
- break;
153
- case constants_1.serverMessageKeys.ping:
154
- (_a = this._serverPeer) === null || _a === void 0 ? void 0 : _a.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.pong));
155
- break;
156
- }
157
- }
158
- });
159
- });
160
- }
161
- getServerPublicKey(serverKeyHex) {
162
- const publicKey = Buffer.from(serverKeyHex, "hex");
163
- if (publicKey.length !== 32) {
164
- throw new Error(`Expected a 32-byte public key, but got ${publicKey.length} bytes`);
165
- }
166
- return publicKey;
167
- }
168
- handleServerVerification(data) {
169
- if (!this._challenge) {
170
- console.log("No challenge set. Cannot verify.");
171
- return;
172
- }
173
- const serverKeyHex = this._config.get("serverKey");
174
- try {
175
- const publicKey = this.getServerPublicKey(serverKeyHex);
176
- const signatureBuffer = Buffer.from(data.signature.data, "base64");
177
- const verified = hypercore_crypto_1.default.verify(this._challenge, signatureBuffer, publicKey);
178
- if (verified) {
179
- logger_1.logger.info(chalk_1.default.greenBright(`✅ Verification successful.`));
180
- }
181
- else {
182
- logger_1.logger.error(`❌ Verification failed!`);
183
- }
184
- }
185
- catch (error) {
186
- console.error("Error during verification:", error);
187
- }
188
- }
189
- listeners(peer) {
190
- peer.on("data", async (buffer) => {
191
- if (!buffer)
192
- return;
193
- const data = (0, utils_1.safeParseJson)(buffer.toString());
194
- if (data && data.key) {
195
- switch (data.key) {
196
- case constants_1.serverMessageKeys.newConversation:
197
- this._conversationIndex = this._conversationIndex + 1;
198
- break;
199
- case constants_1.serverMessageKeys.inference:
200
- logger_1.logger.info(`📦 Inference message received from ${peer.rawStream.remoteHost}`);
201
- await this.handleInferenceRequest(data, peer);
202
- break;
203
- }
204
- }
205
- });
206
- }
207
- getMessagesWithSystem(messages) {
208
- const systemMessage = this._config.get("systemMessage");
209
- if (messages.length === 2 && systemMessage) {
210
- messages.unshift({
211
- role: "system",
212
- content: systemMessage,
213
- });
214
- }
215
- return messages;
216
- }
217
- async handleInferenceRequest(data, peer) {
218
- const emitterKey = data.data.key;
219
- const messages = this.getMessagesWithSystem(data === null || data === void 0 ? void 0 : data.data.messages);
220
- const req = this.buildStreamRequest(messages);
221
- if (!req)
222
- return;
223
- const { requestOptions, requestBody } = req;
224
- const { protocol, hostname, port, path, method, headers } = requestOptions;
225
- const url = `${protocol}://${hostname}:${port}${path}`;
226
- try {
227
- const response = await fetch(url, {
228
- method,
229
- headers,
230
- body: JSON.stringify(requestBody),
231
- });
232
- if (!response.ok) {
233
- throw new Error(`Server responded with status code: ${response.status}`);
234
- }
235
- if (!response.body) {
236
- throw new Error("Failed to get a ReadableStream from the response");
237
- }
238
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
239
- const responseStream = node_stream_1.Readable.fromWeb(response.body);
240
- const peerStream = new node_stream_1.PassThrough();
241
- responseStream.pipe(peerStream);
242
- let completion = "";
243
- const provider = this._config.get("apiProvider");
244
- peer.write(JSON.stringify({
245
- symmetryEmitterKey: emitterKey,
246
- }));
247
- const peerPipeline = (0, promises_1.pipeline)(peerStream, async function (source) {
248
- for await (const chunk of source) {
249
- if (peer.writable) {
250
- completion += (0, utils_1.getChatDataFromProvider)(provider, (0, utils_1.safeParseStreamResponse)(chunk.toString()));
251
- const write = peer.write(chunk);
252
- if (!write) {
253
- await new Promise((resolve) => peer.once("drain", resolve));
254
- }
255
- }
256
- else {
257
- break;
258
- }
259
- }
260
- });
261
- await Promise.resolve(peerPipeline);
262
- peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.inferenceEnded, data === null || data === void 0 ? void 0 : data.data.key));
263
- if (this._config.get("dataCollectionEnabled") &&
264
- data.data.key === constants_1.serverMessageKeys.inference) {
265
- this.saveCompletion(completion, peer, data.data.messages);
266
- }
267
- }
268
- catch (error) {
269
- let errorMessage = "An error occurred during inference";
270
- if (error instanceof Error)
271
- errorMessage = error.message;
272
- logger_1.logger.error(`🚨 ${errorMessage}`);
273
- }
274
- }
275
- async saveCompletion(completion, peer, messages) {
276
- node_fs_1.default.writeFile(`${this._config.get("path")}/${peer.publicKey.toString("hex")}-${this._conversationIndex}.json`, JSON.stringify([
277
- ...messages,
278
- {
279
- role: "assistant",
280
- content: completion,
281
- },
282
- ]), () => {
283
- logger_1.logger.info(`📝 Completion saved to file`);
284
- });
285
- }
286
- buildStreamRequest(messages) {
287
- const requestOptions = {
288
- hostname: this._config.get("apiHostname"),
289
- port: Number(this._config.get("apiPort")),
290
- path: this._config.get("apiPath"),
291
- protocol: this._config.get("apiProtocol"),
292
- method: "POST",
293
- headers: {
294
- "Content-Type": "application/json",
295
- Authorization: `Bearer ${this._config.get("apiKey")}`,
296
- },
297
- };
298
- const requestBody = {
299
- model: this._config.get("modelName"),
300
- messages: messages || undefined,
301
- stream: true,
302
- };
303
- return { requestOptions, requestBody };
304
- }
305
- }
306
- exports.SymmetryProvider = SymmetryProvider;
307
- exports.default = SymmetryProvider;
package/dist/server.js DELETED
@@ -1,143 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SymmetryServer = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const corestore_1 = __importDefault(require("corestore"));
9
- const hyperdrive_1 = __importDefault(require("hyperdrive"));
10
- const hyperswarm_1 = __importDefault(require("hyperswarm"));
11
- const path_1 = __importDefault(require("path"));
12
- const config_manager_1 = require("./config-manager");
13
- const utils_1 = require("./utils");
14
- const logger_1 = require("./logger");
15
- const peer_repository_1 = require("./peer-repository");
16
- const constants_1 = require("./constants");
17
- const session_manager_1 = require("./session-manager");
18
- const session_repository_1 = require("./session-repository");
19
- const websocket_server_1 = require("./websocket-server");
20
- class SymmetryServer {
21
- constructor(configPath) {
22
- logger_1.logger.info(`🔗 Initializing server using config file: ${configPath}`);
23
- this._config = (0, config_manager_1.createConfigManager)(configPath, false);
24
- if (!this._config.isServerConfig()) {
25
- throw new Error("Invalid configuration for server");
26
- }
27
- this._peerRepository = new peer_repository_1.PeerRepository();
28
- this._sessionRepository = new session_repository_1.SessionRepository();
29
- this._sessionManager = new session_manager_1.SessionManager(this._sessionRepository, 5);
30
- }
31
- async init() {
32
- var _a, _b;
33
- const corePath = path_1.default.join(this._config.get("path"), "symmetry-core");
34
- const store = new corestore_1.default(corePath);
35
- const core = new hyperdrive_1.default(store);
36
- const swarm = new hyperswarm_1.default();
37
- await core.ready();
38
- const discovery = swarm.join(core.discoveryKey, { server: true });
39
- await discovery.flushed();
40
- swarm.on("connection", (peer) => {
41
- logger_1.logger.info(`🔗 New Connection: ${peer.rawStream.remoteHost}`);
42
- store.replicate(peer);
43
- this.listeners(peer);
44
- });
45
- this._wsServer = new websocket_server_1.WsServer(this._config.get("webSocketPort"), this._peerRepository, swarm);
46
- logger_1.logger.info(`🔑 Discovery key: ${(_a = core.discoveryKey) === null || _a === void 0 ? void 0 : _a.toString("hex")}`);
47
- logger_1.logger.info(`🔑 Drive key: ${(_b = core.key) === null || _b === void 0 ? void 0 : _b.toString("hex")}`);
48
- logger_1.logger.info(chalk_1.default.green(`\u2713 Websocket server started: ws://localhost:${this._config.get("webSocketPort")}`));
49
- logger_1.logger.info(chalk_1.default.green(`\u2713 Symmetry server started, waiting for connections...`));
50
- }
51
- listeners(peer) {
52
- peer.on("error", (err) => err);
53
- peer.on("close", () => {
54
- const peerKey = peer.publicKey.toString("hex");
55
- this._peerRepository.updateLastSeen(peerKey);
56
- logger_1.logger.info(`🔗 Connection Closed: Peer ${peerKey.slice(0, 6)}...${peerKey.slice(-6)}`);
57
- });
58
- peer.on("data", (message) => {
59
- const data = (0, utils_1.safeParseJson)(message.toString());
60
- if (!data)
61
- return;
62
- if (data.key) {
63
- switch (data === null || data === void 0 ? void 0 : data.key) {
64
- case constants_1.serverMessageKeys.join:
65
- this.join(peer, data.data);
66
- break;
67
- case constants_1.serverMessageKeys.requestProvider:
68
- this.handlePeerSession(peer, data.data);
69
- break;
70
- case constants_1.serverMessageKeys.verifySession:
71
- this.handlePeerSessionValidation(peer, data.data);
72
- break;
73
- }
74
- }
75
- });
76
- }
77
- async join(peer, message) {
78
- const peerKey = peer.publicKey.toString("hex");
79
- try {
80
- await this._peerRepository.upsert({
81
- ...message,
82
- key: peerKey,
83
- });
84
- logger_1.logger.info(`👋 Peer provider joined ${peer.rawStream.remoteHost}`);
85
- peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.joinAck, {
86
- status: "success",
87
- key: peerKey,
88
- }));
89
- }
90
- catch (error) {
91
- let errorMessage = "";
92
- if (error instanceof Error)
93
- errorMessage = error.message;
94
- logger_1.logger.error(`🚨 ${errorMessage}`);
95
- }
96
- }
97
- async handlePeerSession(peer, randomPeerRequest) {
98
- try {
99
- const providerPeer = await this._peerRepository.getPeer(randomPeerRequest);
100
- const sessionToken = await this._sessionManager.createSession(providerPeer.discovery_key);
101
- peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.providerDetails, {
102
- providerId: providerPeer.key,
103
- sessionToken,
104
- }));
105
- }
106
- catch (error) {
107
- let errorMessage = "";
108
- if (error instanceof Error)
109
- errorMessage = error.message;
110
- logger_1.logger.error(`🚨 ${errorMessage}`);
111
- }
112
- }
113
- async handlePeerSessionValidation(peer, message) {
114
- if (!message.sessionToken)
115
- return;
116
- try {
117
- const providerDiscoveryKey = await this._sessionManager.verifySession(message.sessionToken);
118
- if (!providerDiscoveryKey)
119
- return;
120
- const providerPeer = await this._peerRepository.getByDiscoveryKey(providerDiscoveryKey);
121
- if (!providerPeer)
122
- return;
123
- peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.sessionValid, {
124
- discoveryKey: providerPeer.discovery_key,
125
- }));
126
- await this._sessionManager.extendSession(message.sessionToken);
127
- }
128
- catch (error) {
129
- logger_1.logger.error(`Session verification error: ${error instanceof Error ? error.message : "Unknown error"}`);
130
- peer.write((0, utils_1.createMessage)(constants_1.serverMessageKeys.sessionValid, {
131
- valid: false,
132
- error: "Error verifying session",
133
- }));
134
- }
135
- }
136
- async cleanupSessions() {
137
- await this._sessionManager.cleanupExpiredSessions();
138
- }
139
- }
140
- exports.SymmetryServer = SymmetryServer;
141
- module.exports = {
142
- SymmetryServer,
143
- };
@@ -1,68 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SessionManager = void 0;
7
- const logger_1 = require("./logger");
8
- const crypto_1 = __importDefault(require("crypto"));
9
- class SessionManager {
10
- constructor(sessionRepository, sessionDurationMinutes = 60) {
11
- this.sessionRepository = sessionRepository;
12
- this.sessionDuration = sessionDurationMinutes * 60 * 1000;
13
- }
14
- async createSession(providerId) {
15
- const sessionId = crypto_1.default.randomUUID();
16
- const now = new Date();
17
- const session = {
18
- id: sessionId,
19
- providerId,
20
- createdAt: now,
21
- expiresAt: new Date(now.getTime() + this.sessionDuration),
22
- };
23
- await this.sessionRepository.create(session);
24
- logger_1.logger.info(`🖇️ Session created for provider: ${providerId}`);
25
- return sessionId;
26
- }
27
- async verifySession(sessionId) {
28
- const session = await this.sessionRepository.get(sessionId);
29
- if (!session) {
30
- logger_1.logger.warning(`❌ Session not found: ${sessionId}`);
31
- return null;
32
- }
33
- if (new Date() > session.expiresAt) {
34
- logger_1.logger.warning(`🕛 Session expired: ${sessionId}`);
35
- await this.sessionRepository.delete(sessionId);
36
- return null;
37
- }
38
- return session.providerId;
39
- }
40
- async extendSession(sessionId) {
41
- const session = await this.sessionRepository.get(sessionId);
42
- if (!session) {
43
- logger_1.logger.warning(`🚨 Cannot extend non-existent session: ${sessionId}`);
44
- return false;
45
- }
46
- session.expiresAt = new Date(Date.now() + this.sessionDuration);
47
- await this.sessionRepository.update(session);
48
- logger_1.logger.info(`🎟️ Session extended: ${sessionId}`);
49
- return true;
50
- }
51
- async deleteSession(sessionId) {
52
- const result = await this.sessionRepository.delete(sessionId);
53
- if (result) {
54
- // cross bin emoji
55
- logger_1.logger.info(`🗑 Session deleted: ${sessionId}`);
56
- }
57
- else {
58
- logger_1.logger.warning(`🚨 Failed to delete session: ${sessionId}`);
59
- }
60
- return result;
61
- }
62
- async cleanupExpiredSessions() {
63
- const deletedCount = await this.sessionRepository.deleteExpired();
64
- logger_1.logger.info(`🕛 Cleaned up ${deletedCount} expired sessions`);
65
- return deletedCount;
66
- }
67
- }
68
- exports.SessionManager = SessionManager;