@magek/adapter-session-store-memory 0.0.10
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/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessionStore = exports.MemorySessionStoreAdapter = void 0;
|
|
4
|
+
var memory_session_store_adapter_1 = require("./memory-session-store-adapter");
|
|
5
|
+
Object.defineProperty(exports, "MemorySessionStoreAdapter", { enumerable: true, get: function () { return memory_session_store_adapter_1.MemorySessionStoreAdapter; } });
|
|
6
|
+
// Export a default instance for easy usage
|
|
7
|
+
const memory_session_store_adapter_2 = require("./memory-session-store-adapter");
|
|
8
|
+
exports.sessionStore = new memory_session_store_adapter_2.MemorySessionStoreAdapter();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SessionStoreAdapter, MagekConfig, UUID, SubscriptionEnvelope } from '@magek/common';
|
|
2
|
+
export declare class MemorySessionStoreAdapter implements SessionStoreAdapter {
|
|
3
|
+
private connections;
|
|
4
|
+
private subscriptions;
|
|
5
|
+
private subscriptionsByConnection;
|
|
6
|
+
private subscriptionsByClassName;
|
|
7
|
+
storeConnection(config: MagekConfig, connectionId: UUID, connectionData: Record<string, any>): Promise<void>;
|
|
8
|
+
fetchConnection(config: MagekConfig, connectionId: UUID): Promise<Record<string, any> | undefined>;
|
|
9
|
+
deleteConnection(config: MagekConfig, connectionId: UUID): Promise<void>;
|
|
10
|
+
storeSubscription(config: MagekConfig, connectionId: UUID, subscriptionId: UUID, subscriptionData: Record<string, any>): Promise<void>;
|
|
11
|
+
fetchSubscription(config: MagekConfig, subscriptionId: UUID): Promise<Record<string, any> | undefined>;
|
|
12
|
+
deleteSubscription(config: MagekConfig, connectionId: UUID, subscriptionId: UUID): Promise<void>;
|
|
13
|
+
fetchSubscriptionsForConnection(config: MagekConfig, connectionId: UUID): Promise<Array<Record<string, any>>>;
|
|
14
|
+
fetchSubscriptionsByClassName(config: MagekConfig, className: string): Promise<Array<SubscriptionEnvelope>>;
|
|
15
|
+
deleteSubscriptionsForConnection(config: MagekConfig, connectionId: UUID): Promise<void>;
|
|
16
|
+
healthCheck: {
|
|
17
|
+
isUp: (config: MagekConfig) => Promise<boolean>;
|
|
18
|
+
details: (config: MagekConfig) => Promise<unknown>;
|
|
19
|
+
urls: (config: MagekConfig) => Promise<Array<string>>;
|
|
20
|
+
};
|
|
21
|
+
getConnectionsCount(): number;
|
|
22
|
+
getSubscriptionsCount(): number;
|
|
23
|
+
clear(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemorySessionStoreAdapter = void 0;
|
|
4
|
+
const common_1 = require("@magek/common");
|
|
5
|
+
class MemorySessionStoreAdapter {
|
|
6
|
+
connections = new Map();
|
|
7
|
+
subscriptions = new Map();
|
|
8
|
+
subscriptionsByConnection = new Map();
|
|
9
|
+
subscriptionsByClassName = new Map();
|
|
10
|
+
async storeConnection(config, connectionId, connectionData) {
|
|
11
|
+
const logger = (0, common_1.getLogger)(config, 'MemorySessionStoreAdapter#storeConnection');
|
|
12
|
+
logger.debug('Storing connection data:', { connectionId, connectionData });
|
|
13
|
+
this.connections.set(connectionId, {
|
|
14
|
+
...connectionData,
|
|
15
|
+
connectionID: connectionId,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async fetchConnection(config, connectionId) {
|
|
19
|
+
const data = this.connections.get(connectionId);
|
|
20
|
+
if (!data) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
// Remove internal fields before returning
|
|
24
|
+
const { connectionID, ...connectionData } = data;
|
|
25
|
+
return connectionData;
|
|
26
|
+
}
|
|
27
|
+
async deleteConnection(config, connectionId) {
|
|
28
|
+
const logger = (0, common_1.getLogger)(config, 'MemorySessionStoreAdapter#deleteConnection');
|
|
29
|
+
if (!this.connections.has(connectionId)) {
|
|
30
|
+
logger.info(`No connections found with connectionID=${connectionId}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.connections.delete(connectionId);
|
|
34
|
+
logger.debug('Deleted connection:', connectionId);
|
|
35
|
+
}
|
|
36
|
+
async storeSubscription(config, connectionId, subscriptionId, subscriptionData) {
|
|
37
|
+
const logger = (0, common_1.getLogger)(config, 'MemorySessionStoreAdapter#storeSubscription');
|
|
38
|
+
logger.debug('Storing subscription data:', { connectionId, subscriptionId, subscriptionData });
|
|
39
|
+
const data = {
|
|
40
|
+
...subscriptionData,
|
|
41
|
+
connectionID: connectionId,
|
|
42
|
+
subscriptionID: subscriptionId,
|
|
43
|
+
};
|
|
44
|
+
this.subscriptions.set(subscriptionId, data);
|
|
45
|
+
// Index by connection
|
|
46
|
+
if (!this.subscriptionsByConnection.has(connectionId)) {
|
|
47
|
+
this.subscriptionsByConnection.set(connectionId, new Set());
|
|
48
|
+
}
|
|
49
|
+
this.subscriptionsByConnection.get(connectionId).add(subscriptionId);
|
|
50
|
+
// Index by className if present
|
|
51
|
+
const className = subscriptionData.className;
|
|
52
|
+
if (className) {
|
|
53
|
+
if (!this.subscriptionsByClassName.has(className)) {
|
|
54
|
+
this.subscriptionsByClassName.set(className, new Set());
|
|
55
|
+
}
|
|
56
|
+
this.subscriptionsByClassName.get(className).add(subscriptionId);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async fetchSubscription(config, subscriptionId) {
|
|
60
|
+
const data = this.subscriptions.get(subscriptionId);
|
|
61
|
+
if (!data) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
// Remove internal fields before returning
|
|
65
|
+
const { connectionID, subscriptionID, ...subscriptionData } = data;
|
|
66
|
+
return subscriptionData;
|
|
67
|
+
}
|
|
68
|
+
async deleteSubscription(config, connectionId, subscriptionId) {
|
|
69
|
+
const logger = (0, common_1.getLogger)(config, 'MemorySessionStoreAdapter#deleteSubscription');
|
|
70
|
+
const data = this.subscriptions.get(subscriptionId);
|
|
71
|
+
if (!data) {
|
|
72
|
+
logger.info(`No subscription found with connectionID=${connectionId} and subscriptionID=${subscriptionId}`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Remove from className index
|
|
76
|
+
const className = data.className;
|
|
77
|
+
if (className) {
|
|
78
|
+
this.subscriptionsByClassName.get(className)?.delete(subscriptionId);
|
|
79
|
+
}
|
|
80
|
+
// Remove from connection index
|
|
81
|
+
this.subscriptionsByConnection.get(connectionId)?.delete(subscriptionId);
|
|
82
|
+
// Remove subscription
|
|
83
|
+
this.subscriptions.delete(subscriptionId);
|
|
84
|
+
logger.debug('Deleted subscription:', { connectionId, subscriptionId });
|
|
85
|
+
}
|
|
86
|
+
async fetchSubscriptionsForConnection(config, connectionId) {
|
|
87
|
+
const subscriptionIds = this.subscriptionsByConnection.get(connectionId);
|
|
88
|
+
if (!subscriptionIds) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const results = [];
|
|
92
|
+
for (const subscriptionId of Array.from(subscriptionIds)) {
|
|
93
|
+
const data = this.subscriptions.get(subscriptionId);
|
|
94
|
+
if (data) {
|
|
95
|
+
const { connectionID, subscriptionID, ...subscriptionData } = data;
|
|
96
|
+
results.push(subscriptionData);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
async fetchSubscriptionsByClassName(config, className) {
|
|
102
|
+
const subscriptionIds = this.subscriptionsByClassName.get(className);
|
|
103
|
+
if (!subscriptionIds) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const results = [];
|
|
107
|
+
for (const subscriptionId of Array.from(subscriptionIds)) {
|
|
108
|
+
const data = this.subscriptions.get(subscriptionId);
|
|
109
|
+
if (data) {
|
|
110
|
+
results.push(data);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
async deleteSubscriptionsForConnection(config, connectionId) {
|
|
116
|
+
const logger = (0, common_1.getLogger)(config, 'MemorySessionStoreAdapter#deleteSubscriptionsForConnection');
|
|
117
|
+
const subscriptionIds = this.subscriptionsByConnection.get(connectionId);
|
|
118
|
+
if (!subscriptionIds || subscriptionIds.size === 0) {
|
|
119
|
+
logger.debug(`No subscriptions found for connection: ${connectionId}`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
let removed = 0;
|
|
123
|
+
for (const subscriptionId of Array.from(subscriptionIds)) {
|
|
124
|
+
const data = this.subscriptions.get(subscriptionId);
|
|
125
|
+
if (data) {
|
|
126
|
+
// Remove from className index
|
|
127
|
+
const className = data.className;
|
|
128
|
+
if (className) {
|
|
129
|
+
this.subscriptionsByClassName.get(className)?.delete(subscriptionId);
|
|
130
|
+
}
|
|
131
|
+
this.subscriptions.delete(subscriptionId);
|
|
132
|
+
removed++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Clear the connection's subscription set
|
|
136
|
+
this.subscriptionsByConnection.delete(connectionId);
|
|
137
|
+
logger.debug(`Deleted ${removed} subscriptions for connection:`, connectionId);
|
|
138
|
+
}
|
|
139
|
+
healthCheck = {
|
|
140
|
+
isUp: async (config) => {
|
|
141
|
+
// In-memory store is always up if the process is running
|
|
142
|
+
return true;
|
|
143
|
+
},
|
|
144
|
+
details: async (config) => {
|
|
145
|
+
return {
|
|
146
|
+
type: 'memory',
|
|
147
|
+
status: 'healthy',
|
|
148
|
+
connections: {
|
|
149
|
+
count: this.connections.size,
|
|
150
|
+
},
|
|
151
|
+
subscriptions: {
|
|
152
|
+
count: this.subscriptions.size,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
urls: async (config) => {
|
|
157
|
+
return ['memory://in-memory-session-store'];
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
// Helper methods for testing
|
|
161
|
+
getConnectionsCount() {
|
|
162
|
+
return this.connections.size;
|
|
163
|
+
}
|
|
164
|
+
getSubscriptionsCount() {
|
|
165
|
+
return this.subscriptions.size;
|
|
166
|
+
}
|
|
167
|
+
clear() {
|
|
168
|
+
this.connections.clear();
|
|
169
|
+
this.subscriptions.clear();
|
|
170
|
+
this.subscriptionsByConnection.clear();
|
|
171
|
+
this.subscriptionsByClassName.clear();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.MemorySessionStoreAdapter = MemorySessionStoreAdapter;
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@magek/adapter-session-store-memory",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "In-memory session store adapter for the Magek framework",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"session-store",
|
|
7
|
+
"memory",
|
|
8
|
+
"in-memory",
|
|
9
|
+
"websocket",
|
|
10
|
+
"connections",
|
|
11
|
+
"subscriptions"
|
|
12
|
+
],
|
|
13
|
+
"author": "Boosterin Labs SLU",
|
|
14
|
+
"homepage": "https://magek.ai",
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"main": "dist/index.js",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/theam/magek.git"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.0.0 <23.0.0"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@magek/common": "workspace:^0.0.10",
|
|
32
|
+
"tslib": "2.8.1"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"format": "prettier --write --ext '.js,.ts' **/*.ts **/*/*.ts",
|
|
36
|
+
"lint:check": "eslint \"**/*.ts\"",
|
|
37
|
+
"lint:fix": "eslint --quiet --fix \"**/*.ts\"",
|
|
38
|
+
"build": "tsc -b tsconfig.json",
|
|
39
|
+
"clean": "rimraf ./dist tsconfig.tsbuildinfo",
|
|
40
|
+
"prepack": "tsc -b tsconfig.json",
|
|
41
|
+
"test": "tsc --noEmit -p tsconfig.test.json && c8 mocha --forbid-only \"test/**/*.test.ts\""
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/theam/magek/issues"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@magek/eslint-config": "workspace:^0.0.10",
|
|
48
|
+
"@types/chai": "5.2.3",
|
|
49
|
+
"@types/chai-as-promised": "8.0.2",
|
|
50
|
+
"@types/mocha": "10.0.10",
|
|
51
|
+
"@types/node": "22.19.8",
|
|
52
|
+
"@types/sinon": "21.0.0",
|
|
53
|
+
"@types/sinon-chai": "4.0.0",
|
|
54
|
+
"chai": "6.2.2",
|
|
55
|
+
"chai-as-promised": "8.0.2",
|
|
56
|
+
"@faker-js/faker": "10.2.0",
|
|
57
|
+
"mocha": "11.7.5",
|
|
58
|
+
"c8": "^10.1.3",
|
|
59
|
+
"rimraf": "6.1.2",
|
|
60
|
+
"sinon": "21.0.1",
|
|
61
|
+
"sinon-chai": "4.0.1",
|
|
62
|
+
"tsx": "^4.19.2",
|
|
63
|
+
"typescript": "5.9.3"
|
|
64
|
+
}
|
|
65
|
+
}
|