@lyxa.ai/core 1.3.76 → 1.3.80
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.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/libraries/socket/PushNotificationEvent.d.ts +1 -1
- package/dist/libraries/socket/PushNotificationEvent.js.map +1 -1
- package/dist/libraries/socket/adapters/socket-subscription.d.ts +2 -0
- package/dist/libraries/socket/adapters/socket-subscription.js +4 -2
- package/dist/libraries/socket/adapters/socket-subscription.js.map +1 -1
- package/dist/libraries/socket/connections/batch.d.ts +12 -0
- package/dist/libraries/socket/connections/batch.js +58 -0
- package/dist/libraries/socket/connections/batch.js.map +1 -0
- package/dist/libraries/socket/connections/cache.d.ts +9 -0
- package/dist/libraries/socket/connections/cache.js +36 -0
- package/dist/libraries/socket/connections/cache.js.map +1 -0
- package/dist/libraries/socket/connections/constants.d.ts +2 -0
- package/dist/libraries/socket/connections/constants.js +6 -0
- package/dist/libraries/socket/connections/constants.js.map +1 -0
- package/dist/libraries/socket/connections/event-subscribers.d.ts +5 -0
- package/dist/libraries/socket/connections/event-subscribers.js +60 -0
- package/dist/libraries/socket/connections/event-subscribers.js.map +1 -0
- package/dist/libraries/socket/connections/index.d.ts +7 -0
- package/dist/libraries/socket/connections/index.js +24 -0
- package/dist/libraries/socket/connections/index.js.map +1 -0
- package/dist/libraries/socket/connections/instance-disconnect.d.ts +2 -0
- package/dist/libraries/socket/connections/instance-disconnect.js +43 -0
- package/dist/libraries/socket/connections/instance-disconnect.js.map +1 -0
- package/dist/libraries/socket/connections/keys.d.ts +10 -0
- package/dist/libraries/socket/connections/keys.js +23 -0
- package/dist/libraries/socket/connections/keys.js.map +1 -0
- package/dist/libraries/socket/connections/presence.d.ts +4 -0
- package/dist/libraries/socket/connections/presence.js +23 -0
- package/dist/libraries/socket/connections/presence.js.map +1 -0
- package/dist/libraries/socket/connections/redis-helpers.d.ts +2 -0
- package/dist/libraries/socket/connections/redis-helpers.js +14 -0
- package/dist/libraries/socket/connections/redis-helpers.js.map +1 -0
- package/dist/libraries/socket/connections/subscription.d.ts +13 -0
- package/dist/libraries/socket/connections/subscription.js +73 -0
- package/dist/libraries/socket/connections/subscription.js.map +1 -0
- package/dist/libraries/socket/core/index.d.ts +0 -1
- package/dist/libraries/socket/core/index.js +0 -1
- package/dist/libraries/socket/core/index.js.map +1 -1
- package/dist/libraries/socket/core/local-subscription-registry.d.ts +1 -1
- package/dist/libraries/socket/core/local-subscription-registry.js.map +1 -1
- package/dist/libraries/socket/core/socket-event-publisher.d.ts +1 -1
- package/dist/libraries/socket/core/socket-event-publisher.js +9 -15
- package/dist/libraries/socket/core/socket-event-publisher.js.map +1 -1
- package/dist/types/README.md +1 -1
- package/dist/types/package.json +1 -1
- package/package.json +1 -1
- package/dist/libraries/socket/core/socket-redis-connections.d.ts +0 -36
- package/dist/libraries/socket/core/socket-redis-connections.js +0 -412
- package/dist/libraries/socket/core/socket-redis-connections.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence.js","sourceRoot":"/","sources":["libraries/socket/connections/presence.ts"],"names":[],"mappings":";;AAQA,sCAGC;AAKD,wCAGC;AAKD,wCAUC;AAlCD,gCAAwC;AAExC,iCAAyC;AAMlC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,IAAoB,EAAE,YAAoB,IAAI,CAAC,GAAG,EAAE;IACvG,MAAM,KAAK,GAAG,IAAA,gBAAY,GAAE,CAAC,eAAe,EAAE,CAAC,WAAoB,CAAC;IACpE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAA,sBAAe,EAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC;AAKM,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,IAAoB;IACxE,MAAM,KAAK,GAAG,IAAA,gBAAY,GAAE,CAAC,eAAe,EAAE,CAAC,WAAoB,CAAC;IACpE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAA,sBAAe,EAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC;AAKM,KAAK,UAAU,cAAc,CACnC,IAAoB,EACpB,OAAe,CAAC,EAChB,WAAmB,GAAG;IAEtB,MAAM,KAAK,GAAG,IAAA,gBAAY,GAAE,CAAC,eAAe,EAAE,CAAC,WAAoB,CAAC;IACpE,MAAM,OAAO,GAAG,IAAA,sBAAe,EAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,GAAG,QAAQ,GAAG,CAAC,CAAC;IACjC,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC","sourcesContent":["import { getLibraries } from '../../..';\nimport { AuthEntityType } from '../../auth';\nimport { kOnlineEntities } from './keys';\nimport type { Redis } from 'ioredis';\n\n/**\n * Add or update a user as online in the type-based ZSET.\n */\nexport async function setUserOnline(userId: string, type: AuthEntityType, timestamp: number = Date.now()) {\n\tconst redis = getLibraries().getRedisService().redisClient as Redis;\n\tawait redis.zadd(kOnlineEntities(type), timestamp, userId);\n}\n\n/**\n * Remove a user from the type-based online ZSET (on disconnect).\n */\nexport async function setUserOffline(userId: string, type: AuthEntityType) {\n\tconst redis = getLibraries().getRedisService().redisClient as Redis;\n\tawait redis.zrem(kOnlineEntities(type), userId);\n}\n\n/**\n * Paginate online users for a given entity type (deep pagination, scalable).\n */\nexport async function getOnlineUsers(\n\ttype: AuthEntityType,\n\tpage: number = 1,\n\tpageSize: number = 100\n): Promise<string[]> {\n\tconst redis = getLibraries().getRedisService().redisClient as Redis;\n\tconst zsetKey = kOnlineEntities(type);\n\tconst start = (page - 1) * pageSize;\n\tconst end = start + pageSize - 1;\n\treturn await redis.zrange(zsetKey, start, end);\n}\n/**\n * Example usage:\n *\n * import { getConnectedEntityByType } from './type-queries';\n *\n * // For entity type 'user', get page 2, 100 per page:\n * const users = await getConnectedEntityByType('user', 2, 100);\n */\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scanKeys = scanKeys;
|
|
4
|
+
async function scanKeys(redis, pattern) {
|
|
5
|
+
const keys = [];
|
|
6
|
+
let cursor = '0';
|
|
7
|
+
do {
|
|
8
|
+
const [newCursor, foundKeys] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
9
|
+
cursor = newCursor;
|
|
10
|
+
keys.push(...foundKeys);
|
|
11
|
+
} while (cursor !== '0');
|
|
12
|
+
return keys;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=redis-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-helpers.js","sourceRoot":"/","sources":["libraries/socket/connections/redis-helpers.ts"],"names":[],"mappings":";;AAGA,4BASC;AATM,KAAK,UAAU,QAAQ,CAAC,KAAY,EAAE,OAAe;IAC3D,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,GAAG,CAAC;QACH,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QACxF,MAAM,GAAG,SAAS,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IACzB,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;IACzB,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["// Redis set helpers for socket logic\nimport type { Redis } from 'ioredis';\n\nexport async function scanKeys(redis: Redis, pattern: string): Promise<string[]> {\n\tconst keys: string[] = [];\n\tlet cursor = '0';\n\tdo {\n\t\tconst [newCursor, foundKeys] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\n\t\tcursor = newCursor;\n\t\tkeys.push(...foundKeys);\n\t} while (cursor !== '0');\n\treturn keys;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EntitySubscription } from './keys';
|
|
2
|
+
export interface SocketRedisEventInformation {
|
|
3
|
+
eventKey: string;
|
|
4
|
+
instanceId: string;
|
|
5
|
+
socketId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function connectEntityToSocketEvent(entity: EntitySubscription, socketRedisEventInformation: SocketRedisEventInformation): Promise<void>;
|
|
8
|
+
export declare function disconnectEntityFromSocketEvent(entity: EntitySubscription, socketRedisEventInformation: SocketRedisEventInformation): Promise<{
|
|
9
|
+
removed: boolean;
|
|
10
|
+
socketsRemoved: number;
|
|
11
|
+
subscribersRemoved: number;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function refreshEntityEventTTL(entity: EntitySubscription): Promise<void>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectEntityToSocketEvent = connectEntityToSocketEvent;
|
|
4
|
+
exports.disconnectEntityFromSocketEvent = disconnectEntityFromSocketEvent;
|
|
5
|
+
exports.refreshEntityEventTTL = refreshEntityEventTTL;
|
|
6
|
+
const __1 = require("../../..");
|
|
7
|
+
const keys_1 = require("./keys");
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
const cache_1 = require("./cache");
|
|
10
|
+
const subscriptionCache = new cache_1.LRUCache(10000);
|
|
11
|
+
const eventSubscribersCache = new cache_1.LRUCache(5000);
|
|
12
|
+
async function connectEntityToSocketEvent(entity, socketRedisEventInformation) {
|
|
13
|
+
const redis = (0, __1.getLibraries)().getRedisService();
|
|
14
|
+
const entityKeyStr = (0, keys_1.entityKey)(entity);
|
|
15
|
+
const { instanceId, socketId, eventKey } = socketRedisEventInformation;
|
|
16
|
+
const socketData = `${instanceId}|${socketId}`;
|
|
17
|
+
const subscriberData = `${entityKeyStr}|${instanceId}|${socketId}`;
|
|
18
|
+
const entityEventKey = (0, keys_1.kEntityEventSockets)(entity, eventKey);
|
|
19
|
+
const eventSubsKey = (0, keys_1.kEventEntity)(eventKey);
|
|
20
|
+
const ledgerKey = (0, keys_1.kEntityEvent)(entity);
|
|
21
|
+
await Promise.all([
|
|
22
|
+
redis.addToSet(entityEventKey, socketData),
|
|
23
|
+
redis.addToSet(eventSubsKey, subscriberData),
|
|
24
|
+
redis.addToSet(ledgerKey, eventKey),
|
|
25
|
+
]);
|
|
26
|
+
await Promise.all([
|
|
27
|
+
redis.redisClient.expire(entityEventKey, constants_1.REDIS_KEY_TTL_SECONDS),
|
|
28
|
+
redis.redisClient.expire(eventSubsKey, constants_1.REDIS_KEY_TTL_SECONDS),
|
|
29
|
+
redis.redisClient.expire(ledgerKey, constants_1.REDIS_KEY_TTL_SECONDS),
|
|
30
|
+
]);
|
|
31
|
+
subscriptionCache.delete(`${entityKeyStr}:${eventKey}`);
|
|
32
|
+
eventSubscribersCache.delete(eventKey);
|
|
33
|
+
}
|
|
34
|
+
async function disconnectEntityFromSocketEvent(entity, socketRedisEventInformation) {
|
|
35
|
+
const redis = (0, __1.getLibraries)().getRedisService();
|
|
36
|
+
const entityKeyStr = (0, keys_1.entityKey)(entity);
|
|
37
|
+
const { instanceId, socketId, eventKey } = socketRedisEventInformation;
|
|
38
|
+
const entityEventKey = (0, keys_1.kEntityEventSockets)(entity, eventKey);
|
|
39
|
+
const eventSubsKey = (0, keys_1.kEventEntity)(eventKey);
|
|
40
|
+
const ledgerKey = (0, keys_1.kEntityEvent)(entity);
|
|
41
|
+
const socketData = `${instanceId}|${socketId}`;
|
|
42
|
+
const subscriberData = `${entityKeyStr}|${instanceId}|${socketId}`;
|
|
43
|
+
await Promise.all([
|
|
44
|
+
redis.removeFromSet(entityEventKey, socketData),
|
|
45
|
+
redis.removeFromSet(eventSubsKey, subscriberData),
|
|
46
|
+
]);
|
|
47
|
+
const entitySockets = await redis.getSetMembers(entityEventKey);
|
|
48
|
+
if (entitySockets.length === 0) {
|
|
49
|
+
await Promise.all([redis.deleteCachedObject(entityEventKey), redis.removeFromSet(ledgerKey, eventKey)]);
|
|
50
|
+
}
|
|
51
|
+
subscriptionCache.delete(`${entityKeyStr}:${eventKey}`);
|
|
52
|
+
eventSubscribersCache.delete(eventKey);
|
|
53
|
+
return {
|
|
54
|
+
removed: true,
|
|
55
|
+
socketsRemoved: 1,
|
|
56
|
+
subscribersRemoved: 1,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function refreshEntityEventTTL(entity) {
|
|
60
|
+
const redis = (0, __1.getLibraries)().getRedisService();
|
|
61
|
+
const ledgerKey = (0, keys_1.kEntityEvent)(entity);
|
|
62
|
+
const activeEvents = await redis.getSetMembers(ledgerKey);
|
|
63
|
+
if (!activeEvents.length)
|
|
64
|
+
return;
|
|
65
|
+
const pipeline = redis.redisClient.pipeline();
|
|
66
|
+
pipeline.expire(ledgerKey, constants_1.REDIS_KEY_TTL_SECONDS);
|
|
67
|
+
for (const eventKey of activeEvents) {
|
|
68
|
+
pipeline.expire((0, keys_1.kEntityEventSockets)(entity, eventKey), constants_1.REDIS_KEY_TTL_SECONDS);
|
|
69
|
+
pipeline.expire((0, keys_1.kEventEntity)(eventKey), constants_1.REDIS_KEY_TTL_SECONDS);
|
|
70
|
+
}
|
|
71
|
+
await pipeline.exec();
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"/","sources":["libraries/socket/connections/subscription.ts"],"names":[],"mappings":"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","sourcesContent":["// Subscription management logic for socket Redis\nimport { getLibraries } from '../../..';\nimport { kEntityEventSockets, kEventEntity, kEntityEvent, entityKey, EntitySubscription } from './keys';\nimport { REDIS_KEY_TTL_SECONDS } from './constants';\nimport { LRUCache } from './cache';\n\nexport interface SocketRedisEventInformation {\n\teventKey: string;\n\tinstanceId: string;\n\tsocketId: string;\n}\n\nconst subscriptionCache = new LRUCache<\n\tstring,\n\t{ isSubscribed: boolean; instances: string[]; timestamp: number }\n>(10000);\nconst eventSubscribersCache = new LRUCache<string, { subscribers: EntitySubscription[]; timestamp: number }>(\n\t5000\n);\n\nexport async function connectEntityToSocketEvent(\n\tentity: EntitySubscription,\n\tsocketRedisEventInformation: SocketRedisEventInformation\n) {\n\tconst redis = getLibraries().getRedisService();\n\tconst entityKeyStr = entityKey(entity);\n\tconst { instanceId, socketId, eventKey } = socketRedisEventInformation;\n\tconst socketData = `${instanceId}|${socketId}`;\n\tconst subscriberData = `${entityKeyStr}|${instanceId}|${socketId}`;\n\tconst entityEventKey = kEntityEventSockets(entity, eventKey);\n\tconst eventSubsKey = kEventEntity(eventKey);\n\tconst ledgerKey = kEntityEvent(entity);\n\tawait Promise.all([\n\t\tredis.addToSet(entityEventKey, socketData),\n\t\tredis.addToSet(eventSubsKey, subscriberData),\n\t\tredis.addToSet(ledgerKey, eventKey),\n\t]);\n\tawait Promise.all([\n\t\tredis.redisClient.expire(entityEventKey, REDIS_KEY_TTL_SECONDS),\n\t\tredis.redisClient.expire(eventSubsKey, REDIS_KEY_TTL_SECONDS),\n\t\tredis.redisClient.expire(ledgerKey, REDIS_KEY_TTL_SECONDS),\n\t]);\n\tsubscriptionCache.delete(`${entityKeyStr}:${eventKey}`);\n\teventSubscribersCache.delete(eventKey);\n}\n\nexport async function disconnectEntityFromSocketEvent(\n\tentity: EntitySubscription,\n\tsocketRedisEventInformation: SocketRedisEventInformation\n) {\n\tconst redis = getLibraries().getRedisService();\n\tconst entityKeyStr = entityKey(entity);\n\tconst { instanceId, socketId, eventKey } = socketRedisEventInformation;\n\tconst entityEventKey = kEntityEventSockets(entity, eventKey);\n\tconst eventSubsKey = kEventEntity(eventKey);\n\tconst ledgerKey = kEntityEvent(entity);\n\tconst socketData = `${instanceId}|${socketId}`;\n\tconst subscriberData = `${entityKeyStr}|${instanceId}|${socketId}`;\n\tawait Promise.all([\n\t\tredis.removeFromSet(entityEventKey, socketData),\n\t\tredis.removeFromSet(eventSubsKey, subscriberData),\n\t]);\n\tconst entitySockets = await redis.getSetMembers(entityEventKey);\n\tif (entitySockets.length === 0) {\n\t\tawait Promise.all([redis.deleteCachedObject(entityEventKey), redis.removeFromSet(ledgerKey, eventKey)]);\n\t}\n\tsubscriptionCache.delete(`${entityKeyStr}:${eventKey}`);\n\teventSubscribersCache.delete(eventKey);\n\treturn {\n\t\tremoved: true,\n\t\tsocketsRemoved: 1,\n\t\tsubscribersRemoved: 1,\n\t};\n}\n\nexport async function refreshEntityEventTTL(entity: EntitySubscription) {\n\tconst redis = getLibraries().getRedisService();\n\tconst ledgerKey = kEntityEvent(entity);\n\tconst activeEvents = await redis.getSetMembers(ledgerKey);\n\tif (!activeEvents.length) return;\n\tconst pipeline = redis.redisClient.pipeline();\n\tpipeline.expire(ledgerKey, REDIS_KEY_TTL_SECONDS);\n\tfor (const eventKey of activeEvents) {\n\t\tpipeline.expire(kEntityEventSockets(entity, eventKey), REDIS_KEY_TTL_SECONDS);\n\t\tpipeline.expire(kEventEntity(eventKey), REDIS_KEY_TTL_SECONDS);\n\t}\n\tawait pipeline.exec();\n}\n"]}
|
|
@@ -2,6 +2,5 @@ export * from '../BaseSocketEvent';
|
|
|
2
2
|
export * from './local-subscription-registry';
|
|
3
3
|
export * from './socket-event-registry';
|
|
4
4
|
export * from './zAsyncIterable';
|
|
5
|
-
export * from './socket-redis-connections';
|
|
6
5
|
export * from './socket-event-publisher';
|
|
7
6
|
export * from './socket-event-consumer';
|
|
@@ -18,7 +18,6 @@ __exportStar(require("../BaseSocketEvent"), exports);
|
|
|
18
18
|
__exportStar(require("./local-subscription-registry"), exports);
|
|
19
19
|
__exportStar(require("./socket-event-registry"), exports);
|
|
20
20
|
__exportStar(require("./zAsyncIterable"), exports);
|
|
21
|
-
__exportStar(require("./socket-redis-connections"), exports);
|
|
22
21
|
__exportStar(require("./socket-event-publisher"), exports);
|
|
23
22
|
__exportStar(require("./socket-event-consumer"), exports);
|
|
24
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/socket/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,gEAA8C;AAC9C,0DAAwC;AACxC,mDAAiC;AACjC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/socket/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,gEAA8C;AAC9C,0DAAwC;AACxC,mDAAiC;AACjC,2DAAyC;AACzC,0DAAwC","sourcesContent":["export * from '../BaseSocketEvent';\nexport * from './local-subscription-registry';\nexport * from './socket-event-registry';\nexport * from './zAsyncIterable';\nexport * from './socket-event-publisher';\nexport * from './socket-event-consumer';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-subscription-registry.js","sourceRoot":"/","sources":["libraries/socket/core/local-subscription-registry.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAkC;AAOlC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC3C,MAAM,SAAS,GAAG,CAAC,MAA0B,EAAU,EAAE;IACxD,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;IACvD,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAGF,MAAa,iBAAiB;IACpB,EAAE,CAAe;IACjB,QAAQ,CAAW;IAE5B,YAAY,QAAkB;QAC7B,IAAI,CAAC,EAAE,GAAG,IAAI,gBAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AATD,8CASC;AAED,MAAM,yBAAyB;IAEtB,SAAS,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE9D,IAAI,CAAC,MAA0B,EAAE,QAAkB,EAAE,EAAqB;QACzE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACtC,CAAC;QAED,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,MAA0B,EAAE,QAAkB,EAAE,EAAqB;QAC3E,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,WAAW,EAAE,CAAC;YACjB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACF,CAAC;IACF,CAAC;IAGD,IAAI,CAAC,MAA0B,EAAE,QAAkB,EAAE,OAAgB;QACpE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,SAAS;YAAE,OAAO;QAGvB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;CACD;AAEY,QAAA,SAAS,GAAG,IAAI,yBAAyB,EAAE,CAAC","sourcesContent":["import EventEmitter from 'events';\nimport { EntitySubscription } from '
|
|
1
|
+
{"version":3,"file":"local-subscription-registry.js","sourceRoot":"/","sources":["libraries/socket/core/local-subscription-registry.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAkC;AAOlC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC3C,MAAM,SAAS,GAAG,CAAC,MAA0B,EAAU,EAAE;IACxD,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;IACvD,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAGF,MAAa,iBAAiB;IACpB,EAAE,CAAe;IACjB,QAAQ,CAAW;IAE5B,YAAY,QAAkB;QAC7B,IAAI,CAAC,EAAE,GAAG,IAAI,gBAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AATD,8CASC;AAED,MAAM,yBAAyB;IAEtB,SAAS,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE9D,IAAI,CAAC,MAA0B,EAAE,QAAkB,EAAE,EAAqB;QACzE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACtC,CAAC;QAED,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,MAA0B,EAAE,QAAkB,EAAE,EAAqB;QAC3E,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,WAAW,EAAE,CAAC;YACjB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACF,CAAC;IACF,CAAC;IAGD,IAAI,CAAC,MAA0B,EAAE,QAAkB,EAAE,OAAgB;QACpE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,SAAS;YAAE,OAAO;QAGvB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;CACD;AAEY,QAAA,SAAS,GAAG,IAAI,yBAAyB,EAAE,CAAC","sourcesContent":["import EventEmitter from 'events';\nimport { EntitySubscription } from '../connections';\n\ntype EventKey = string;\ntype SocketId = string;\n\n// Zero-overhead key with memoization\nconst keyCache = new Map<string, string>();\nconst entityKey = (entity: EntitySubscription): string => {\n\tconst raw = `${entity.type ?? 'default'}:${entity.id}`;\n\tlet cached = keyCache.get(raw);\n\tif (!cached) {\n\t\tcached = raw;\n\t\tkeyCache.set(raw, cached);\n\t}\n\treturn cached;\n};\n\n// Remove wrapper class - direct EventEmitter usage\nexport class LocalEventEmitter {\n\treadonly ee: EventEmitter;\n\treadonly socketId: SocketId;\n\n\tconstructor(socketId: SocketId) {\n\t\tthis.ee = new EventEmitter();\n\t\tthis.ee.setMaxListeners(0); // Unlimited listeners\n\t\tthis.socketId = socketId;\n\t}\n}\n\nclass LocalSubscriptionRegistry {\n\t// Direct map for O(1) lookups with minimal overhead\n\tprivate listeners = new Map<string, Set<LocalEventEmitter>>();\n\n\tbind(entity: EntitySubscription, eventKey: EventKey, ee: LocalEventEmitter): void {\n\t\tconst key = `${entityKey(entity)}:${eventKey}`;\n\t\tlet listenerSet = this.listeners.get(key);\n\n\t\tif (!listenerSet) {\n\t\t\tlistenerSet = new Set();\n\t\t\tthis.listeners.set(key, listenerSet);\n\t\t}\n\n\t\tlistenerSet.add(ee);\n\t}\n\n\tunbind(entity: EntitySubscription, eventKey: EventKey, ee: LocalEventEmitter): void {\n\t\tconst key = `${entityKey(entity)}:${eventKey}`;\n\t\tconst listenerSet = this.listeners.get(key);\n\n\t\tif (listenerSet) {\n\t\t\tlistenerSet.delete(ee);\n\t\t\tif (listenerSet.size === 0) {\n\t\t\t\tthis.listeners.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Zero-overhead emit - inline fast path\n\temit(entity: EntitySubscription, eventKey: EventKey, payload: unknown): void {\n\t\tconst key = `${entityKey(entity)}:${eventKey}`;\n\t\tconst listeners = this.listeners.get(key);\n\n\t\tif (!listeners) return;\n\n\t\t// Direct iteration - fastest possible\n\t\tfor (const listener of listeners) {\n\t\t\tlistener.ee.emit(eventKey, payload);\n\t\t}\n\t}\n}\n\nexport const LocalSubs = new LocalSubscriptionRegistry();\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseSocketEvent } from '../BaseSocketEvent';
|
|
2
|
-
import { EntitySubscription } from './socket-redis-connections';
|
|
3
2
|
import { SocketNotificationEvent } from '../events';
|
|
4
3
|
import type { ZodTypeAny } from 'zod';
|
|
4
|
+
import { EntitySubscription } from '../connections';
|
|
5
5
|
export declare function publishSocketEvent(event: BaseSocketEvent<ZodTypeAny, ZodTypeAny, ZodTypeAny | undefined>, recipients: EntitySubscription[]): Promise<void>;
|
|
6
6
|
export declare function publishNotificationSocketEvent(event: SocketNotificationEvent, recipients: EntitySubscription[]): Promise<void>;
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.publishSocketEvent = publishSocketEvent;
|
|
4
4
|
exports.publishNotificationSocketEvent = publishNotificationSocketEvent;
|
|
5
5
|
const __1 = require("../../..");
|
|
6
|
-
const socket_redis_connections_1 = require("./socket-redis-connections");
|
|
7
6
|
const event_1 = require("../../event");
|
|
8
7
|
const PushNotificationEvent_1 = require("../PushNotificationEvent");
|
|
8
|
+
const connections_1 = require("../connections");
|
|
9
9
|
const PUBLISH_OPTIONS = {
|
|
10
10
|
contentType: 'application/json',
|
|
11
11
|
persistent: true,
|
|
@@ -38,16 +38,13 @@ async function getActiveSubscribedRecipients(recipients, localKey) {
|
|
|
38
38
|
const subscribed = [];
|
|
39
39
|
const unsubscribed = [];
|
|
40
40
|
await Promise.all(recipients.map(async (recipient) => {
|
|
41
|
-
const sockets = await redis.getSetMembers((0,
|
|
41
|
+
const sockets = await redis.getSetMembers((0, connections_1.kEntityEventSockets)(recipient, localKey));
|
|
42
42
|
if (sockets.length > 0) {
|
|
43
43
|
const instanceSet = new Set();
|
|
44
44
|
for (let i = 0; i < sockets.length; i++) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
instanceSet.add(
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
}
|
|
45
|
+
const [instanceId] = sockets[i].split('|');
|
|
46
|
+
if (instanceId)
|
|
47
|
+
instanceSet.add(instanceId);
|
|
51
48
|
}
|
|
52
49
|
if (instanceSet.size > 0) {
|
|
53
50
|
subscribed.push({ recipient, instances: Array.from(instanceSet) });
|
|
@@ -94,16 +91,13 @@ async function publishNotificationSocketEvent(event, recipients) {
|
|
|
94
91
|
const redis = (0, __1.getLibraries)().getRedisService();
|
|
95
92
|
const validInstances = [];
|
|
96
93
|
await Promise.all(recipients.map(async (recipient) => {
|
|
97
|
-
const sockets = await redis.getSetMembers((0,
|
|
94
|
+
const sockets = await redis.getSetMembers((0, connections_1.kEntityEventSockets)(recipient, eventKey));
|
|
98
95
|
if (sockets.length > 0) {
|
|
99
96
|
const instanceSet = new Set();
|
|
100
97
|
for (let i = 0; i < sockets.length; i++) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
instanceSet.add(
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
}
|
|
98
|
+
const [instanceId] = sockets[i].split('|');
|
|
99
|
+
if (instanceId)
|
|
100
|
+
instanceSet.add(instanceId);
|
|
107
101
|
}
|
|
108
102
|
if (instanceSet.size > 0) {
|
|
109
103
|
validInstances.push({ recipient, instances: Array.from(instanceSet) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-event-publisher.js","sourceRoot":"/","sources":["libraries/socket/core/socket-event-publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLibraries } from '../../..';\nimport { BaseSocketEvent } from '../BaseSocketEvent';\nimport { EntitySubscription, getEntityEventSocketsKey } from './socket-redis-connections';\nimport { SocketNotificationEvent } from '../events';\nimport { EXCHANGE_NAME, getChannel, INSTANCE_ROUTE_PREFIX, publishEvent } from '../../event';\nimport { PushNotificationEvent } from '../PushNotificationEvent';\nimport type { ZodTypeAny } from 'zod';\n\n// Reusable publish options\nconst PUBLISH_OPTIONS = {\n\tcontentType: 'application/json',\n\tpersistent: true,\n} as const;\n\n// Zero-overhead publishing - minimal allocations\nfunction publishToInstances(\n\trecipientsWithInstances: Array<{ recipient: EntitySubscription; instances: string[] }>,\n\tlocalKey: string,\n\tpayload: unknown\n): void {\n\tif (recipientsWithInstances.length === 0) return;\n\n\tconst channel = getChannel().pubChannel;\n\n\t// Pre-serialize message once\n\tconst message = { localKey, payload, recipient: null as any };\n\n\t// Fire-and-forget with minimal overhead\n\tfor (let i = 0; i < recipientsWithInstances.length; i++) {\n\t\tconst { recipient, instances } = recipientsWithInstances[i];\n\t\tmessage.recipient = recipient;\n\t\tconst messageStr = JSON.stringify(message);\n\n\t\tfor (let j = 0; j < instances.length; j++) {\n\t\t\tconst routingKey = `${INSTANCE_ROUTE_PREFIX}.${instances[j]}`;\n\n\t\t\ttry {\n\t\t\t\t// Direct publish - Buffer.from creates minimal overhead\n\t\t\t\tchannel.publish(EXCHANGE_NAME, routingKey, Buffer.from(messageStr, 'utf8'), PUBLISH_OPTIONS);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`[Socket] Publish failed: ${routingKey}`, error);\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Ultra-simple: Direct Redis lookups, no batch/cache/parsing!\nasync function getActiveSubscribedRecipients(\n\trecipients: EntitySubscription[],\n\tlocalKey: string\n): Promise<{\n\tsubscribed: Array<{ recipient: EntitySubscription; instances: string[] }>;\n\tunsubscribed: EntitySubscription[];\n}> {\n\tif (recipients.length === 0) {\n\t\treturn { subscribed: [], unsubscribed: [] };\n\t}\n\n\tconst redis = getLibraries().getRedisService();\n\tconst subscribed: Array<{ recipient: EntitySubscription; instances: string[] }> = [];\n\tconst unsubscribed: EntitySubscription[] = [];\n\n\t// Parallel lookups - one key per recipient\n\tawait Promise.all(\n\t\trecipients.map(async recipient => {\n\t\t\tconst sockets = await redis.getSetMembers(getEntityEventSocketsKey(recipient, localKey));\n\n\t\t\tif (sockets.length > 0) {\n\t\t\t\t// Extract instances\n\t\t\t\tconst instanceSet = new Set<string>();\n\t\t\t\tfor (let i = 0; i < sockets.length; i++) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst socketInfo = JSON.parse(sockets[i]);\n\t\t\t\t\t\tinstanceSet.add(socketInfo.instanceId);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Skip malformed socket data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (instanceSet.size > 0) {\n\t\t\t\t\tsubscribed.push({ recipient, instances: Array.from(instanceSet) });\n\t\t\t\t} else {\n\t\t\t\t\tunsubscribed.push(recipient);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tunsubscribed.push(recipient);\n\t\t\t}\n\t\t})\n\t);\n\n\treturn { subscribed, unsubscribed };\n}\n\n// Minimal overhead publish - early returns, lazy evaluation\nexport async function publishSocketEvent(\n\tevent: BaseSocketEvent<ZodTypeAny, ZodTypeAny, ZodTypeAny | undefined>,\n\trecipients: EntitySubscription[]\n): Promise<void> {\n\tconst logger = getLibraries().getLogger().logger;\n\tif (recipients.length === 0) return;\n\n\tconst localKey = event.getSubscriptionKey();\n\tconst payload = event.payload();\n\n\tconst { subscribed, unsubscribed } = await getActiveSubscribedRecipients(recipients, localKey);\n\n\tlogger.debug({ subscribed }, '[Socket] Subscribed recipients:');\n\tlogger.debug({ unsubscribed }, '[Socket] Unsubscribed recipients:');\n\n\tif (subscribed.length > 0) publishToInstances(subscribed, localKey, payload);\n\n\tif (unsubscribed.length > 0) {\n\t\tlogger.debug({ unsubscribed }, '[Socket] Processing unsubscribed recipients');\n\t\tif (event.notificationSettings?.isPushNotification) {\n\t\t\tconst pushNotificationPayload = event.getPushNotificationPayload();\n\t\t\tconst settings = event.notificationSettings;\n\t\t\tawait publishEvent(\n\t\t\t\tnew PushNotificationEvent(event.eventType(), pushNotificationPayload, unsubscribed, settings)\n\t\t\t).catch(err => console.error('[Socket] Push notification failed:', err));\n\t\t}\n\n\t\tconst socketNotificationPayload = event.getSocketNotificationEvent();\n\n\t\tlogger.debug({ socketNotificationPayload }, '[Socket] Socket notification payload');\n\n\t\tif (event.getSocketNotificationEvent()) {\n\t\t\tawait publishNotificationSocketEvent(socketNotificationPayload!, unsubscribed);\n\t\t}\n\t}\n}\n\nexport async function publishNotificationSocketEvent(\n\tevent: SocketNotificationEvent,\n\trecipients: EntitySubscription[]\n): Promise<void> {\n\tif (recipients.length === 0) return;\n\n\tconst eventKey = event.getSubscriptionKey();\n\tconst redis = getLibraries().getRedisService();\n\tconst validInstances: Array<{ recipient: EntitySubscription; instances: string[] }> = [];\n\n\t// Parallel direct lookups\n\tawait Promise.all(\n\t\trecipients.map(async recipient => {\n\t\t\tconst sockets = await redis.getSetMembers(getEntityEventSocketsKey(recipient, eventKey));\n\n\t\t\tif (sockets.length > 0) {\n\t\t\t\tconst instanceSet = new Set<string>();\n\t\t\t\tfor (let i = 0; i < sockets.length; i++) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst socketInfo = JSON.parse(sockets[i]);\n\t\t\t\t\t\tinstanceSet.add(socketInfo.instanceId);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Skip malformed socket data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (instanceSet.size > 0) {\n\t\t\t\t\tvalidInstances.push({ recipient, instances: Array.from(instanceSet) });\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t);\n\n\tif (validInstances.length > 0) {\n\t\tpublishToInstances(validInstances, eventKey, event.payload());\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"socket-event-publisher.js","sourceRoot":"/","sources":["libraries/socket/core/socket-event-publisher.ts"],"names":[],"mappings":";;AAuFA,gDAmCC;AAED,wEA8BC;AA1JD,gCAAwC;AAGxC,uCAA6F;AAC7F,oEAAiE;AAEjE,gDAAyE;AAGzE,MAAM,eAAe,GAAG;IACvB,WAAW,EAAE,kBAAkB;IAC/B,UAAU,EAAE,IAAI;CACP,CAAC;AAGX,SAAS,kBAAkB,CAC1B,uBAAsF,EACtF,QAAgB,EAChB,OAAgB;IAEhB,IAAI,uBAAuB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjD,MAAM,OAAO,GAAG,IAAA,kBAAU,GAAE,CAAC,UAAU,CAAC;IAGxC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,IAAW,EAAE,CAAC;IAG9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzD,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAE3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,GAAG,6BAAqB,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YAE9D,IAAI,CAAC;gBAEJ,OAAO,CAAC,OAAO,CAAC,qBAAa,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC;YAC9F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,4BAA4B,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;YAChE,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAGD,KAAK,UAAU,6BAA6B,CAC3C,UAAgC,EAChC,QAAgB;IAKhB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,KAAK,GAAG,IAAA,gBAAY,GAAE,CAAC,eAAe,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAkE,EAAE,CAAC;IACrF,MAAM,YAAY,GAAyB,EAAE,CAAC;IAG9C,MAAM,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAC,SAAS,EAAC,EAAE;QAChC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,IAAA,iCAAmB,EAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QACpF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3C,IAAI,UAAU;oBAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC1B,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACP,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,CAAC;QACF,CAAC;aAAM,CAAC;YACP,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACrC,CAAC;AAGM,KAAK,UAAU,kBAAkB,CACvC,KAAsE,EACtE,UAAgC;IAEhC,MAAM,MAAM,GAAG,IAAA,gBAAY,GAAE,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;IACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEpC,MAAM,QAAQ,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAEhC,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,MAAM,6BAA6B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE/F,MAAM,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,iCAAiC,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,EAAE,mCAAmC,CAAC,CAAC;IAEpE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE7E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,EAAE,6CAA6C,CAAC,CAAC;QAC9E,IAAI,KAAK,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,CAAC;YACpD,MAAM,uBAAuB,GAAG,KAAK,CAAC,0BAA0B,EAAE,CAAC;YACnE,MAAM,QAAQ,GAAG,KAAK,CAAC,oBAAoB,CAAC;YAC5C,MAAM,IAAA,oBAAY,EACjB,IAAI,6CAAqB,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,uBAAuB,EAAE,YAAY,EAAE,QAAQ,CAAC,CAC7F,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,yBAAyB,GAAG,KAAK,CAAC,0BAA0B,EAAE,CAAC;QAErE,MAAM,CAAC,KAAK,CAAC,EAAE,yBAAyB,EAAE,EAAE,sCAAsC,CAAC,CAAC;QAEpF,IAAI,KAAK,CAAC,0BAA0B,EAAE,EAAE,CAAC;YACxC,MAAM,8BAA8B,CAAC,yBAA0B,EAAE,YAAY,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;AACF,CAAC;AAEM,KAAK,UAAU,8BAA8B,CACnD,KAA8B,EAC9B,UAAgC;IAEhC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEpC,MAAM,QAAQ,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAA,gBAAY,GAAE,CAAC,eAAe,EAAE,CAAC;IAC/C,MAAM,cAAc,GAAkE,EAAE,CAAC;IAGzF,MAAM,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAC,SAAS,EAAC,EAAE;QAChC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,IAAA,iCAAmB,EAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QACpF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3C,IAAI,UAAU;oBAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC1B,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACF,CAAC;IACF,CAAC,CAAC,CACF,CAAC;IAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,kBAAkB,CAAC,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;AACF,CAAC","sourcesContent":["import { getLibraries } from '../../..';\nimport { BaseSocketEvent } from '../BaseSocketEvent';\nimport { SocketNotificationEvent } from '../events';\nimport { EXCHANGE_NAME, getChannel, INSTANCE_ROUTE_PREFIX, publishEvent } from '../../event';\nimport { PushNotificationEvent } from '../PushNotificationEvent';\nimport type { ZodTypeAny } from 'zod';\nimport { EntitySubscription, kEntityEventSockets } from '../connections';\n\n// Reusable publish options\nconst PUBLISH_OPTIONS = {\n\tcontentType: 'application/json',\n\tpersistent: true,\n} as const;\n\n// Zero-overhead publishing - minimal allocations\nfunction publishToInstances(\n\trecipientsWithInstances: Array<{ recipient: EntitySubscription; instances: string[] }>,\n\tlocalKey: string,\n\tpayload: unknown\n): void {\n\tif (recipientsWithInstances.length === 0) return;\n\n\tconst channel = getChannel().pubChannel;\n\n\t// Pre-serialize message once\n\tconst message = { localKey, payload, recipient: null as any };\n\n\t// Fire-and-forget with minimal overhead\n\tfor (let i = 0; i < recipientsWithInstances.length; i++) {\n\t\tconst { recipient, instances } = recipientsWithInstances[i];\n\t\tmessage.recipient = recipient;\n\t\tconst messageStr = JSON.stringify(message);\n\n\t\tfor (let j = 0; j < instances.length; j++) {\n\t\t\tconst routingKey = `${INSTANCE_ROUTE_PREFIX}.${instances[j]}`;\n\n\t\t\ttry {\n\t\t\t\t// Direct publish - Buffer.from creates minimal overhead\n\t\t\t\tchannel.publish(EXCHANGE_NAME, routingKey, Buffer.from(messageStr, 'utf8'), PUBLISH_OPTIONS);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(`[Socket] Publish failed: ${routingKey}`, error);\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Ultra-simple: Direct Redis lookups, no batch/cache/parsing!\nasync function getActiveSubscribedRecipients(\n\trecipients: EntitySubscription[],\n\tlocalKey: string\n): Promise<{\n\tsubscribed: Array<{ recipient: EntitySubscription; instances: string[] }>;\n\tunsubscribed: EntitySubscription[];\n}> {\n\tif (recipients.length === 0) {\n\t\treturn { subscribed: [], unsubscribed: [] };\n\t}\n\n\tconst redis = getLibraries().getRedisService();\n\tconst subscribed: Array<{ recipient: EntitySubscription; instances: string[] }> = [];\n\tconst unsubscribed: EntitySubscription[] = [];\n\n\t// Parallel lookups - one key per recipient\n\tawait Promise.all(\n\t\trecipients.map(async recipient => {\n\t\t\tconst sockets = await redis.getSetMembers(kEntityEventSockets(recipient, localKey));\n\t\t\tif (sockets.length > 0) {\n\t\t\t\tconst instanceSet = new Set<string>();\n\t\t\t\tfor (let i = 0; i < sockets.length; i++) {\n\t\t\t\t\tconst [instanceId] = sockets[i].split('|');\n\t\t\t\t\tif (instanceId) instanceSet.add(instanceId);\n\t\t\t\t}\n\t\t\t\tif (instanceSet.size > 0) {\n\t\t\t\t\tsubscribed.push({ recipient, instances: Array.from(instanceSet) });\n\t\t\t\t} else {\n\t\t\t\t\tunsubscribed.push(recipient);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tunsubscribed.push(recipient);\n\t\t\t}\n\t\t})\n\t);\n\n\treturn { subscribed, unsubscribed };\n}\n\n// Minimal overhead publish - early returns, lazy evaluation\nexport async function publishSocketEvent(\n\tevent: BaseSocketEvent<ZodTypeAny, ZodTypeAny, ZodTypeAny | undefined>,\n\trecipients: EntitySubscription[]\n): Promise<void> {\n\tconst logger = getLibraries().getLogger().logger;\n\tif (recipients.length === 0) return;\n\n\tconst localKey = event.getSubscriptionKey();\n\tconst payload = event.payload();\n\n\tconst { subscribed, unsubscribed } = await getActiveSubscribedRecipients(recipients, localKey);\n\n\tlogger.debug({ subscribed }, '[Socket] Subscribed recipients:');\n\tlogger.debug({ unsubscribed }, '[Socket] Unsubscribed recipients:');\n\n\tif (subscribed.length > 0) publishToInstances(subscribed, localKey, payload);\n\n\tif (unsubscribed.length > 0) {\n\t\tlogger.debug({ unsubscribed }, '[Socket] Processing unsubscribed recipients');\n\t\tif (event.notificationSettings?.isPushNotification) {\n\t\t\tconst pushNotificationPayload = event.getPushNotificationPayload();\n\t\t\tconst settings = event.notificationSettings;\n\t\t\tawait publishEvent(\n\t\t\t\tnew PushNotificationEvent(event.eventType(), pushNotificationPayload, unsubscribed, settings)\n\t\t\t).catch(err => console.error('[Socket] Push notification failed:', err));\n\t\t}\n\n\t\tconst socketNotificationPayload = event.getSocketNotificationEvent();\n\n\t\tlogger.debug({ socketNotificationPayload }, '[Socket] Socket notification payload');\n\n\t\tif (event.getSocketNotificationEvent()) {\n\t\t\tawait publishNotificationSocketEvent(socketNotificationPayload!, unsubscribed);\n\t\t}\n\t}\n}\n\nexport async function publishNotificationSocketEvent(\n\tevent: SocketNotificationEvent,\n\trecipients: EntitySubscription[]\n): Promise<void> {\n\tif (recipients.length === 0) return;\n\n\tconst eventKey = event.getSubscriptionKey();\n\tconst redis = getLibraries().getRedisService();\n\tconst validInstances: Array<{ recipient: EntitySubscription; instances: string[] }> = [];\n\n\t// Parallel direct lookups\n\tawait Promise.all(\n\t\trecipients.map(async recipient => {\n\t\t\tconst sockets = await redis.getSetMembers(kEntityEventSockets(recipient, eventKey));\n\t\t\tif (sockets.length > 0) {\n\t\t\t\tconst instanceSet = new Set<string>();\n\t\t\t\tfor (let i = 0; i < sockets.length; i++) {\n\t\t\t\t\tconst [instanceId] = sockets[i].split('|');\n\t\t\t\t\tif (instanceId) instanceSet.add(instanceId);\n\t\t\t\t}\n\t\t\t\tif (instanceSet.size > 0) {\n\t\t\t\t\tvalidInstances.push({ recipient, instances: Array.from(instanceSet) });\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t);\n\n\tif (validInstances.length > 0) {\n\t\tpublishToInstances(validInstances, eventKey, event.payload());\n\t}\n}\n"]}
|
package/dist/types/README.md
CHANGED
package/dist/types/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { AuthEntityType } from '../../auth';
|
|
2
|
-
export type EntitySubscription = {
|
|
3
|
-
id: string;
|
|
4
|
-
type?: AuthEntityType;
|
|
5
|
-
};
|
|
6
|
-
export interface SocketRedisEventInformation {
|
|
7
|
-
eventKey: string;
|
|
8
|
-
instanceId: string;
|
|
9
|
-
socketId: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const entityKey: (entity: EntitySubscription) => string;
|
|
12
|
-
export declare const getEntityEventSocketsKey: (entity: EntitySubscription, eventKey: string) => string;
|
|
13
|
-
export declare function connectEntityToSocketEvent(entity: EntitySubscription, socketRedisEventInformation: SocketRedisEventInformation): Promise<void>;
|
|
14
|
-
export declare function getConnectedEntityByType(type: AuthEntityType): Promise<string[]>;
|
|
15
|
-
export declare function disconnectEntityFromSocketEvent(entity: EntitySubscription, socketRedisEventInformation: SocketRedisEventInformation): Promise<{
|
|
16
|
-
removed: boolean;
|
|
17
|
-
socketsRemoved: number;
|
|
18
|
-
subscribersRemoved: number;
|
|
19
|
-
}>;
|
|
20
|
-
export declare function getEntitySubscriptionInfo(entity: EntitySubscription, eventKey: string): Promise<{
|
|
21
|
-
isSubscribed: boolean;
|
|
22
|
-
instances: string[];
|
|
23
|
-
}>;
|
|
24
|
-
export declare function getEntitySubscriptionInfoBatch(entities: Array<{
|
|
25
|
-
entity: EntitySubscription;
|
|
26
|
-
eventKey: string;
|
|
27
|
-
}>): Promise<Map<string, {
|
|
28
|
-
isSubscribed: boolean;
|
|
29
|
-
instances: string[];
|
|
30
|
-
}>>;
|
|
31
|
-
export declare function isEntityConnected(entity: EntitySubscription, eventKey: string): Promise<boolean>;
|
|
32
|
-
export declare function disconnectAllEntitiesFromInstance(entityType?: AuthEntityType): Promise<void>;
|
|
33
|
-
export declare function getEventSubscribers(eventKey: string): Promise<EntitySubscription[]>;
|
|
34
|
-
export declare function getEventSubscribersBatch(eventKeys: string[]): Promise<Map<string, EntitySubscription[]>>;
|
|
35
|
-
export declare function getEventSubscribersByType(eventKey: string, entityType: AuthEntityType): Promise<EntitySubscription[]>;
|
|
36
|
-
export declare function getEventSubscriberCount(eventKey: string): Promise<number>;
|