@fabriktor/fx 0.0.51 → 0.0.52

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,5 +1,5 @@
1
- import type { ChatOperator, WSCloseHandler, WSConnection, WSErrorHandler, WSMessageHandler } from "@fabriktor/client";
2
- import type { Chat, ChatRoom, ChatRoomMember } from "@fabriktor/schema";
1
+ import type { ChatOperator, UsersOperator, WSCloseHandler, WSConnection, WSErrorHandler, WSMessageHandler } from "@fabriktor/client";
2
+ import type { Chat, ChatRoom, ChatRoomMember, User } from "@fabriktor/schema";
3
3
  import { type SearchPage } from "../core/search.js";
4
4
  type ChatInsertOptions = Parameters<ChatOperator["insertOneChat"]>[0];
5
5
  type ChatReplaceOptions = Parameters<ChatOperator["replaceOneChat"]>[0];
@@ -10,6 +10,7 @@ export type MarkChatObjectsUploadedOptions = {
10
10
  export type ReactChatOptions = Parameters<ChatOperator["reactChat"]>[0];
11
11
  export type ChatFXOptions = {
12
12
  chat: ChatOperator;
13
+ users: UsersOperator;
13
14
  };
14
15
  type SearchChatsScope = {
15
16
  chat_room_id: string;
@@ -60,6 +61,15 @@ export type ChatRoomMembersOptions = {
60
61
  export type MyChatRoomMembersOptions = {
61
62
  owner_id: string;
62
63
  };
64
+ export type ChatRoomParticipantsOptions = {
65
+ chat_room_ids: string[];
66
+ };
67
+ export type ChatRoomParticipant = Pick<User, "id" | "full_name" | "username">;
68
+ export type ChatRoomParticipants = {
69
+ members: ChatRoomMember[];
70
+ users: ChatRoomParticipant[];
71
+ };
72
+ export type ChatRoomParticipantsByRoom = Record<string, ChatRoomParticipants>;
63
73
  export type OpenChatRoomOptions = {
64
74
  owner_id: string;
65
75
  chat_room_id: string;
@@ -102,12 +112,14 @@ export interface ChatFXOperator {
102
112
  searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
103
113
  chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
104
114
  myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
115
+ chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipantsByRoom>;
105
116
  openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
106
117
  openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
107
118
  reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
108
119
  }
109
120
  export declare class ChatFX implements ChatFXOperator {
110
121
  private chat;
122
+ private users;
111
123
  constructor(opts: ChatFXOptions);
112
124
  createChat(opts: CreateChatOptions): Promise<Chat>;
113
125
  markChatObjectsUploaded(opts: MarkChatObjectsUploadedOptions): Promise<Chat>;
@@ -118,11 +130,14 @@ export declare class ChatFX implements ChatFXOperator {
118
130
  searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
119
131
  chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
120
132
  myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
133
+ chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipantsByRoom>;
121
134
  openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
122
135
  openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
123
136
  reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
124
137
  private openChatRoomConnections;
125
138
  private openGlobalChatRoomsConnection;
139
+ private allChatRoomMembers;
140
+ private findUser;
126
141
  private findChat;
127
142
  }
128
143
  export declare function newChatFX(opts: ChatFXOptions): ChatFX;
@@ -10,14 +10,18 @@ const closeCodeNormal = 1000;
10
10
  const wsRefreshMilliseconds = 40 * 60 * 1000;
11
11
  const wsRefreshRetryMilliseconds = 30 * 1000;
12
12
  const resourceChat = "chat";
13
+ const resourceUser = "user";
13
14
  const msgCreatedChatIDMissing = "Created chat response did not contain an ID.";
14
15
  const msgChatMissing = "Chat could not be resolved after the mutation.";
15
16
  const msgSearchQueryRequired = "Search query is required.";
16
17
  const msgChatObjectsUploading = "Cannot react to a chat while objects are still uploading.";
18
+ const msgParticipantMissing = "Chat room participant could not be resolved.";
17
19
  export class ChatFX {
18
20
  chat;
21
+ users;
19
22
  constructor(opts) {
20
23
  this.chat = opts.chat;
24
+ this.users = opts.users;
21
25
  }
22
26
  async createChat(opts) {
23
27
  const out = await this.chat.insertOneChat(opts);
@@ -111,6 +115,27 @@ export class ChatFX {
111
115
  });
112
116
  return out.value ?? [];
113
117
  }
118
+ async chatRoomParticipants(opts) {
119
+ const roomIDs = [
120
+ ...new Set(opts.chat_room_ids.map((id) => id.trim())),
121
+ ].filter((id) => id !== "");
122
+ const entries = await Promise.all(roomIDs.map(async (chatRoomID) => [chatRoomID, await this.allChatRoomMembers(chatRoomID)]));
123
+ const ownerIDs = [
124
+ ...new Set(entries.flatMap(([, members]) => members.map((member) => member.owner_id))),
125
+ ];
126
+ const userResults = await Promise.allSettled(ownerIDs.map(async (id) => [id, await this.findUser(id)]));
127
+ const usersByID = new Map(userResults.flatMap((result) => result.status === "fulfilled" ? [result.value] : []));
128
+ return Object.fromEntries(entries.map(([chatRoomID, members]) => [
129
+ chatRoomID,
130
+ {
131
+ members,
132
+ users: members.flatMap((member) => {
133
+ const user = usersByID.get(member.owner_id);
134
+ return user ? [user] : [];
135
+ }),
136
+ },
137
+ ]));
138
+ }
114
139
  async openChatRoom(opts) {
115
140
  const latest = await this.latestChats({
116
141
  chat_room_id: opts.chat_room_id,
@@ -372,6 +397,36 @@ export class ChatFX {
372
397
  },
373
398
  };
374
399
  }
400
+ async allChatRoomMembers(chatRoomID) {
401
+ const out = [];
402
+ let page = 1;
403
+ for (;;) {
404
+ const next = await this.searchChatRoomMembers({
405
+ chat_room_id: chatRoomID,
406
+ page,
407
+ });
408
+ out.push(...next.results);
409
+ if (next.done) {
410
+ return out;
411
+ }
412
+ page = next.next_page;
413
+ }
414
+ }
415
+ async findUser(id) {
416
+ const out = await this.users.findOneUser({ id });
417
+ const user = out.value;
418
+ if (!user) {
419
+ throw errResolveFailed({
420
+ resource: resourceUser,
421
+ msg: msgParticipantMissing,
422
+ });
423
+ }
424
+ return {
425
+ id: user.id,
426
+ full_name: user.full_name,
427
+ username: user.username,
428
+ };
429
+ }
375
430
  async findChat(id) {
376
431
  const out = await this.chat.findOneChat({
377
432
  id,
package/dist/src/fx.js CHANGED
@@ -53,6 +53,7 @@ export class FX {
53
53
  });
54
54
  this.chat = newChatFX({
55
55
  chat: opts.chat,
56
+ users: opts.users,
56
57
  });
57
58
  this.contacts = newContactsFX({
58
59
  contacts: opts.contacts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabriktor/fx",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "![Fabriktor Logo](./img/fabriktor-character.gif)",
5
5
  "type": "module",
6
6
  "exports": {