@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.
@@ -0,0 +1,3 @@
1
+ export { MemorySessionStoreAdapter } from './memory-session-store-adapter';
2
+ import { MemorySessionStoreAdapter } from './memory-session-store-adapter';
3
+ export declare const sessionStore: MemorySessionStoreAdapter;
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
+ }