@jskit-ai/realtime 0.1.31 → 0.1.32
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/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/realtime",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.32",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Thin, generic realtime runtime wrappers for socket.io server and client.",
|
|
7
7
|
options: {
|
|
@@ -95,7 +95,7 @@ export default Object.freeze({
|
|
|
95
95
|
mutations: {
|
|
96
96
|
dependencies: {
|
|
97
97
|
runtime: {
|
|
98
|
-
"@jskit-ai/kernel": "0.1.
|
|
98
|
+
"@jskit-ai/kernel": "0.1.33",
|
|
99
99
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
100
100
|
"redis": "^5.8.2",
|
|
101
101
|
"socket.io": "^4.8.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/realtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
19
|
-
"@jskit-ai/kernel": "0.1.
|
|
19
|
+
"@jskit-ai/kernel": "0.1.33",
|
|
20
20
|
"redis": "^5.8.2",
|
|
21
21
|
"socket.io": "^4.8.3",
|
|
22
22
|
"socket.io-client": "^4.8.3"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizeRecordId, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
2
|
import { createProviderLogger as createSharedProviderLogger } from "@jskit-ai/kernel/shared/support/providerLogger";
|
|
3
3
|
import {
|
|
4
4
|
registerDomainEventListener,
|
|
@@ -41,15 +41,15 @@ function normalizeArray(value) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function roomForUser(userId) {
|
|
44
|
-
return `user:${
|
|
44
|
+
return `user:${String(userId || "").trim()}`;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function roomForWorkspace(workspaceId) {
|
|
48
|
-
return `workspace:${
|
|
48
|
+
return `workspace:${String(workspaceId || "").trim()}`;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function roomForWorkspaceUser(workspaceId, userId) {
|
|
52
|
-
return `workspace:${
|
|
52
|
+
return `workspace:${String(workspaceId || "").trim()}:user:${String(userId || "").trim()}`;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function parseCookieHeader(value = "") {
|
|
@@ -186,23 +186,23 @@ function mergeRealtimePayload(event, payloadPatch) {
|
|
|
186
186
|
function resolveScopeWorkspaceId(scope = {}) {
|
|
187
187
|
const source = scope && typeof scope === "object" && !Array.isArray(scope) ? scope : {};
|
|
188
188
|
if (String(source.kind || "").trim().toLowerCase() === "workspace") {
|
|
189
|
-
return
|
|
189
|
+
return normalizeRecordId(source.id, { fallback: null });
|
|
190
190
|
}
|
|
191
191
|
if (String(source.kind || "").trim().toLowerCase() === "workspace_user") {
|
|
192
|
-
return
|
|
192
|
+
return normalizeRecordId(source.workspaceId || source.id, { fallback: null });
|
|
193
193
|
}
|
|
194
|
-
return
|
|
194
|
+
return normalizeRecordId(source.workspaceId, { fallback: null });
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
function resolveScopeUserId(scope = {}) {
|
|
198
198
|
const source = scope && typeof scope === "object" && !Array.isArray(scope) ? scope : {};
|
|
199
199
|
if (String(source.kind || "").trim().toLowerCase() === "user") {
|
|
200
|
-
return
|
|
200
|
+
return normalizeRecordId(source.id, { fallback: null });
|
|
201
201
|
}
|
|
202
202
|
if (String(source.kind || "").trim().toLowerCase() === "workspace_user") {
|
|
203
|
-
return
|
|
203
|
+
return normalizeRecordId(source.userId, { fallback: null });
|
|
204
204
|
}
|
|
205
|
-
return
|
|
205
|
+
return normalizeRecordId(source.userId, { fallback: null });
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
function applyAudiencePreset(preset, { event, rooms, flags, logger } = {}) {
|
|
@@ -222,8 +222,8 @@ function applyAudiencePreset(preset, { event, rooms, flags, logger } = {}) {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
if (normalizedPreset === "actor_user") {
|
|
225
|
-
const actorId =
|
|
226
|
-
if (actorId
|
|
225
|
+
const actorId = normalizeRecordId(event?.actorId, { fallback: null });
|
|
226
|
+
if (actorId) {
|
|
227
227
|
rooms.add(roomForUser(actorId));
|
|
228
228
|
}
|
|
229
229
|
return;
|
|
@@ -231,7 +231,7 @@ function applyAudiencePreset(preset, { event, rooms, flags, logger } = {}) {
|
|
|
231
231
|
|
|
232
232
|
if (normalizedPreset === "all_workspace_users") {
|
|
233
233
|
const workspaceId = resolveScopeWorkspaceId(event?.scope);
|
|
234
|
-
if (workspaceId
|
|
234
|
+
if (workspaceId) {
|
|
235
235
|
rooms.add(roomForWorkspace(workspaceId));
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
@@ -249,7 +249,7 @@ function applyAudiencePreset(preset, { event, rooms, flags, logger } = {}) {
|
|
|
249
249
|
const scopeKind = normalizeText(event?.scope?.kind).toLowerCase();
|
|
250
250
|
if (scopeKind === "workspace") {
|
|
251
251
|
const workspaceId = resolveScopeWorkspaceId(event?.scope);
|
|
252
|
-
if (workspaceId
|
|
252
|
+
if (workspaceId) {
|
|
253
253
|
rooms.add(roomForWorkspace(workspaceId));
|
|
254
254
|
}
|
|
255
255
|
return;
|
|
@@ -257,14 +257,14 @@ function applyAudiencePreset(preset, { event, rooms, flags, logger } = {}) {
|
|
|
257
257
|
if (scopeKind === "workspace_user") {
|
|
258
258
|
const workspaceId = resolveScopeWorkspaceId(event?.scope);
|
|
259
259
|
const userId = resolveScopeUserId(event?.scope);
|
|
260
|
-
if (workspaceId
|
|
260
|
+
if (workspaceId && userId) {
|
|
261
261
|
rooms.add(roomForWorkspaceUser(workspaceId, userId));
|
|
262
262
|
}
|
|
263
263
|
return;
|
|
264
264
|
}
|
|
265
265
|
if (scopeKind === "user") {
|
|
266
266
|
const userId = resolveScopeUserId(event?.scope);
|
|
267
|
-
if (userId
|
|
267
|
+
if (userId) {
|
|
268
268
|
rooms.add(roomForUser(userId));
|
|
269
269
|
}
|
|
270
270
|
return;
|
|
@@ -309,33 +309,33 @@ function addAudienceRoomsFromObject(selection, { event, rooms, flags, logger } =
|
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
const userId =
|
|
313
|
-
if (userId
|
|
312
|
+
const userId = normalizeRecordId(selection.userId, { fallback: null });
|
|
313
|
+
if (userId) {
|
|
314
314
|
rooms.add(roomForUser(userId));
|
|
315
315
|
}
|
|
316
316
|
for (const entry of normalizeArray(selection.userIds)) {
|
|
317
|
-
const normalizedUserId =
|
|
318
|
-
if (normalizedUserId
|
|
317
|
+
const normalizedUserId = normalizeRecordId(entry, { fallback: null });
|
|
318
|
+
if (normalizedUserId) {
|
|
319
319
|
rooms.add(roomForUser(normalizedUserId));
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
const workspaceId =
|
|
324
|
-
if (workspaceId
|
|
323
|
+
const workspaceId = normalizeRecordId(selection.workspaceId, { fallback: null });
|
|
324
|
+
if (workspaceId) {
|
|
325
325
|
rooms.add(roomForWorkspace(workspaceId));
|
|
326
326
|
}
|
|
327
327
|
for (const entry of normalizeArray(selection.workspaceIds)) {
|
|
328
|
-
const normalizedWorkspaceId =
|
|
329
|
-
if (normalizedWorkspaceId
|
|
328
|
+
const normalizedWorkspaceId = normalizeRecordId(entry, { fallback: null });
|
|
329
|
+
if (normalizedWorkspaceId) {
|
|
330
330
|
rooms.add(roomForWorkspace(normalizedWorkspaceId));
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
const workspaceUser = selection.workspaceUser;
|
|
335
335
|
if (workspaceUser && typeof workspaceUser === "object") {
|
|
336
|
-
const targetWorkspaceId =
|
|
337
|
-
const targetUserId =
|
|
338
|
-
if (targetWorkspaceId
|
|
336
|
+
const targetWorkspaceId = normalizeRecordId(workspaceUser.workspaceId, { fallback: null });
|
|
337
|
+
const targetUserId = normalizeRecordId(workspaceUser.userId, { fallback: null });
|
|
338
|
+
if (targetWorkspaceId && targetUserId) {
|
|
339
339
|
rooms.add(roomForWorkspaceUser(targetWorkspaceId, targetUserId));
|
|
340
340
|
}
|
|
341
341
|
}
|
|
@@ -344,9 +344,9 @@ function addAudienceRoomsFromObject(selection, { event, rooms, flags, logger } =
|
|
|
344
344
|
if (!entry || typeof entry !== "object") {
|
|
345
345
|
continue;
|
|
346
346
|
}
|
|
347
|
-
const targetWorkspaceId =
|
|
348
|
-
const targetUserId =
|
|
349
|
-
if (targetWorkspaceId
|
|
347
|
+
const targetWorkspaceId = normalizeRecordId(entry.workspaceId, { fallback: null });
|
|
348
|
+
const targetUserId = normalizeRecordId(entry.userId, { fallback: null });
|
|
349
|
+
if (targetWorkspaceId && targetUserId) {
|
|
350
350
|
rooms.add(roomForWorkspaceUser(targetWorkspaceId, targetUserId));
|
|
351
351
|
}
|
|
352
352
|
}
|
|
@@ -356,8 +356,8 @@ function collectUserIdsFromQueryRows(rows = []) {
|
|
|
356
356
|
const result = new Set();
|
|
357
357
|
for (const row of normalizeArray(rows)) {
|
|
358
358
|
if (typeof row === "number") {
|
|
359
|
-
const directId =
|
|
360
|
-
if (directId
|
|
359
|
+
const directId = normalizeRecordId(row, { fallback: null });
|
|
360
|
+
if (directId) {
|
|
361
361
|
result.add(directId);
|
|
362
362
|
}
|
|
363
363
|
continue;
|
|
@@ -365,8 +365,8 @@ function collectUserIdsFromQueryRows(rows = []) {
|
|
|
365
365
|
if (!row || typeof row !== "object" || Array.isArray(row)) {
|
|
366
366
|
continue;
|
|
367
367
|
}
|
|
368
|
-
const userId =
|
|
369
|
-
if (userId
|
|
368
|
+
const userId = normalizeRecordId(row.userId || row.user_id || row.id, { fallback: null });
|
|
369
|
+
if (userId) {
|
|
370
370
|
result.add(userId);
|
|
371
371
|
}
|
|
372
372
|
}
|
|
@@ -447,7 +447,7 @@ async function resolveAudienceTargets(dispatcher, event, { scope, logger } = {})
|
|
|
447
447
|
|
|
448
448
|
async function resolveSocketActorId(authService, socket) {
|
|
449
449
|
if (!authService || typeof authService.authenticateRequest !== "function") {
|
|
450
|
-
return
|
|
450
|
+
return null;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
const cookies = parseCookieHeader(socket?.request?.headers?.cookie);
|
|
@@ -455,9 +455,9 @@ async function resolveSocketActorId(authService, socket) {
|
|
|
455
455
|
cookies
|
|
456
456
|
});
|
|
457
457
|
if (!authResult || authResult.authenticated !== true) {
|
|
458
|
-
return
|
|
458
|
+
return null;
|
|
459
459
|
}
|
|
460
|
-
return
|
|
460
|
+
return normalizeRecordId(authResult?.profile?.id, { fallback: null });
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
async function resolveActorWorkspaceIds(workspaceMembershipsRepository, actorId) {
|
|
@@ -467,8 +467,8 @@ async function resolveActorWorkspaceIds(workspaceMembershipsRepository, actorId)
|
|
|
467
467
|
|
|
468
468
|
const workspaceIds = await workspaceMembershipsRepository.listActiveWorkspaceIdsByUserId(actorId);
|
|
469
469
|
return normalizeArray(workspaceIds)
|
|
470
|
-
.map((entry) =>
|
|
471
|
-
.filter(
|
|
470
|
+
.map((entry) => normalizeRecordId(entry, { fallback: null }))
|
|
471
|
+
.filter(Boolean);
|
|
472
472
|
}
|
|
473
473
|
|
|
474
474
|
function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
@@ -496,7 +496,7 @@ function registerRealtimeSocketAudienceBootstrap(scope, io, logger) {
|
|
|
496
496
|
);
|
|
497
497
|
|
|
498
498
|
const actorId = await resolveSocketActorId(authService, socket);
|
|
499
|
-
if (actorId
|
|
499
|
+
if (!actorId) {
|
|
500
500
|
logger.debug(
|
|
501
501
|
{
|
|
502
502
|
listenerId: "runtime.realtime.domain-event-bridge",
|
|
@@ -471,7 +471,7 @@ test("RealtimeServiceProvider merges custom realtime payload with canonical doma
|
|
|
471
471
|
assert.equal(emitted[0].payload?.entity, "settings");
|
|
472
472
|
assert.equal(emitted[0].payload?.operation, "updated");
|
|
473
473
|
assert.equal(emitted[0].payload?.scope?.kind, "workspace");
|
|
474
|
-
assert.equal(emitted[0].payload?.scope?.id, 11);
|
|
474
|
+
assert.equal(emitted[0].payload?.scope?.id, "11");
|
|
475
475
|
});
|
|
476
476
|
|
|
477
477
|
test("RealtimeServiceProvider emits only the matching dispatcher event for each service method event", async () => {
|