@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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/realtime",
4
- version: "0.1.31",
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.32",
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.31",
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.32",
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 { normalizePositiveInteger, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
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:${Number(userId)}`;
44
+ return `user:${String(userId || "").trim()}`;
45
45
  }
46
46
 
47
47
  function roomForWorkspace(workspaceId) {
48
- return `workspace:${Number(workspaceId)}`;
48
+ return `workspace:${String(workspaceId || "").trim()}`;
49
49
  }
50
50
 
51
51
  function roomForWorkspaceUser(workspaceId, userId) {
52
- return `workspace:${Number(workspaceId)}:user:${Number(userId)}`;
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 normalizePositiveInteger(source.id);
189
+ return normalizeRecordId(source.id, { fallback: null });
190
190
  }
191
191
  if (String(source.kind || "").trim().toLowerCase() === "workspace_user") {
192
- return normalizePositiveInteger(source.workspaceId || source.id);
192
+ return normalizeRecordId(source.workspaceId || source.id, { fallback: null });
193
193
  }
194
- return normalizePositiveInteger(source.workspaceId);
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 normalizePositiveInteger(source.id);
200
+ return normalizeRecordId(source.id, { fallback: null });
201
201
  }
202
202
  if (String(source.kind || "").trim().toLowerCase() === "workspace_user") {
203
- return normalizePositiveInteger(source.userId);
203
+ return normalizeRecordId(source.userId, { fallback: null });
204
204
  }
205
- return normalizePositiveInteger(source.userId);
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 = normalizePositiveInteger(event?.actorId);
226
- if (actorId > 0) {
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 > 0) {
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 > 0) {
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 > 0 && userId > 0) {
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 > 0) {
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 = normalizePositiveInteger(selection.userId);
313
- if (userId > 0) {
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 = normalizePositiveInteger(entry);
318
- if (normalizedUserId > 0) {
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 = normalizePositiveInteger(selection.workspaceId);
324
- if (workspaceId > 0) {
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 = normalizePositiveInteger(entry);
329
- if (normalizedWorkspaceId > 0) {
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 = normalizePositiveInteger(workspaceUser.workspaceId);
337
- const targetUserId = normalizePositiveInteger(workspaceUser.userId);
338
- if (targetWorkspaceId > 0 && targetUserId > 0) {
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 = normalizePositiveInteger(entry.workspaceId);
348
- const targetUserId = normalizePositiveInteger(entry.userId);
349
- if (targetWorkspaceId > 0 && targetUserId > 0) {
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 = normalizePositiveInteger(row);
360
- if (directId > 0) {
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 = normalizePositiveInteger(row.userId || row.user_id || row.id);
369
- if (userId > 0) {
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 0;
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 0;
458
+ return null;
459
459
  }
460
- return normalizePositiveInteger(authResult?.profile?.id);
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) => normalizePositiveInteger(entry))
471
- .filter((entry) => entry > 0);
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 < 1) {
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 () => {