@fabriktor/fx 0.0.54 → 0.0.56

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,9 +1,10 @@
1
1
  import type { ChatOperator, UsersOperator, WSCloseHandler, WSConnection, WSErrorHandler, WSMessageHandler } from "@fabriktor/client";
2
- import type { Chat, ChatRoom, ChatRoomMember, User } from "@fabriktor/schema";
2
+ import { type Chat, type ChatRoom, type ChatRoomMember, type 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];
6
6
  export type CreateChatOptions = ChatInsertOptions;
7
+ export type EnsureChatRoomOptions = Parameters<ChatOperator["ensureChatRoom"]>[0];
7
8
  export type MarkChatObjectsUploadedOptions = {
8
9
  id: ChatReplaceOptions["id"];
9
10
  };
@@ -58,6 +59,9 @@ export type SearchChatRoomMembersPage = SearchPage<ChatRoomMember>;
58
59
  export type ChatRoomMembersOptions = {
59
60
  chat_room_id: string;
60
61
  };
62
+ export type ChatRoomsOptions = {
63
+ ids: string[];
64
+ };
61
65
  export type MyChatRoomMembersOptions = {
62
66
  owner_id: string;
63
67
  };
@@ -99,11 +103,13 @@ export type ChatRoomSession = {
99
103
  export type GlobalChatRoomsSession = {
100
104
  chat_rooms_ws: WSConnection;
101
105
  members: ChatRoomMember[];
106
+ rooms: ChatRoom[];
102
107
  closeNormal(reason?: string): void;
103
108
  closeLeavingPage(reason?: string): void;
104
109
  };
105
110
  export interface ChatFXOperator {
106
111
  createChat(opts: CreateChatOptions): Promise<Chat>;
112
+ ensureChatRoom(opts: EnsureChatRoomOptions): Promise<string>;
107
113
  markChatObjectsUploaded(opts: MarkChatObjectsUploadedOptions): Promise<Chat>;
108
114
  searchChats(opts: SearchChatsOptions): Promise<SearchChatsPage>;
109
115
  newLatestChatsCursor(opts: LatestChatsOptions): LatestChatsCursor;
@@ -111,6 +117,7 @@ export interface ChatFXOperator {
111
117
  nextLatestChats(opts: NextLatestChatsOptions): Promise<LatestChatsPage>;
112
118
  searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
113
119
  chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
120
+ chatRooms(opts: ChatRoomsOptions): Promise<ChatRoom[]>;
114
121
  myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
115
122
  chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipantsByRoom>;
116
123
  openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
@@ -122,6 +129,7 @@ export declare class ChatFX implements ChatFXOperator {
122
129
  private users;
123
130
  constructor(opts: ChatFXOptions);
124
131
  createChat(opts: CreateChatOptions): Promise<Chat>;
132
+ ensureChatRoom(opts: EnsureChatRoomOptions): Promise<string>;
125
133
  markChatObjectsUploaded(opts: MarkChatObjectsUploadedOptions): Promise<Chat>;
126
134
  searchChats(opts: SearchChatsOptions): Promise<SearchChatsPage>;
127
135
  newLatestChatsCursor(opts: LatestChatsOptions): LatestChatsCursor;
@@ -129,6 +137,7 @@ export declare class ChatFX implements ChatFXOperator {
129
137
  nextLatestChats(opts: NextLatestChatsOptions): Promise<LatestChatsPage>;
130
138
  searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
131
139
  chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
140
+ chatRooms(opts: ChatRoomsOptions): Promise<ChatRoom[]>;
132
141
  myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
133
142
  chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipantsByRoom>;
134
143
  openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
@@ -136,6 +145,7 @@ export declare class ChatFX implements ChatFXOperator {
136
145
  reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
137
146
  private openChatRoomConnections;
138
147
  private openGlobalChatRoomsConnection;
148
+ private allChatRoomMembers;
139
149
  private findUser;
140
150
  private findChat;
141
151
  }
@@ -3,15 +3,18 @@
3
3
  // Licensed under the Apache License, Version 2.0 (the "License"); you may
4
4
  // not use this file except in compliance with the License. You may obtain
5
5
  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ import { IDKey, } from "@fabriktor/schema";
6
7
  import { errRequired, errResolveFailed, errValidation } from "../core/err.js";
7
8
  import { requiredOperationID } from "../core/id.js";
8
9
  import { normalizeSearchPage, normalizeSearchPerPage, normalizeSearchQuery, runSearch, } from "../core/search.js";
9
10
  const closeCodeNormal = 1000;
11
+ const closeCodeLeavingPage = 1001;
10
12
  const wsRefreshMilliseconds = 40 * 60 * 1000;
11
13
  const wsRefreshRetryMilliseconds = 30 * 1000;
12
14
  const resourceChat = "chat";
13
15
  const resourceUser = "user";
14
16
  const msgCreatedChatIDMissing = "Created chat response did not contain an ID.";
17
+ const msgEnsuredChatRoomIDMissing = "Ensured chat room response did not contain an ID.";
15
18
  const msgChatMissing = "Chat could not be resolved after the mutation.";
16
19
  const msgSearchQueryRequired = "Search query is required.";
17
20
  const msgChatObjectsUploading = "Cannot react to a chat while objects are still uploading.";
@@ -28,6 +31,10 @@ export class ChatFX {
28
31
  const id = requiredOperationID(out, msgCreatedChatIDMissing);
29
32
  return await this.findChat(id);
30
33
  }
34
+ async ensureChatRoom(opts) {
35
+ const out = await this.chat.ensureChatRoom(opts);
36
+ return requiredOperationID(out, msgEnsuredChatRoomIDMissing);
37
+ }
31
38
  async markChatObjectsUploaded(opts) {
32
39
  await this.chat.replaceOneChat({
33
40
  id: opts.id,
@@ -107,6 +114,18 @@ export class ChatFX {
107
114
  });
108
115
  return out.value ?? [];
109
116
  }
117
+ async chatRooms(opts) {
118
+ const ids = [...new Set(opts.ids.map((id) => id.trim()))].filter((id) => id !== "");
119
+ if (ids.length === 0) {
120
+ return [];
121
+ }
122
+ const out = await this.chat.queryChatRooms({
123
+ query: {
124
+ [IDKey]: ids,
125
+ },
126
+ });
127
+ return out.value ?? [];
128
+ }
110
129
  async myChatRoomMembers(opts) {
111
130
  const out = await this.chat.queryChatRoomMembers({
112
131
  query: {
@@ -119,37 +138,22 @@ export class ChatFX {
119
138
  const roomIDs = [
120
139
  ...new Set(opts.chat_room_ids.map((id) => id.trim())),
121
140
  ].filter((id) => id !== "");
122
- if (roomIDs.length === 0) {
123
- return {};
124
- }
125
- const result = await this.chat.queryChatRoomMembers({
126
- query: {
127
- chat_room_id: roomIDs,
128
- },
129
- });
130
- const members = result.value ?? [];
131
- const membersByRoom = new Map(roomIDs.map((id) => [id, []]));
132
- for (const member of members) {
133
- membersByRoom.get(member.chat_room_id)?.push(member);
134
- }
141
+ const entries = await Promise.all(roomIDs.map(async (chatRoomID) => [chatRoomID, await this.allChatRoomMembers(chatRoomID)]));
135
142
  const ownerIDs = [
136
- ...new Set(members.map((member) => member.owner_id)),
143
+ ...new Set(entries.flatMap(([, members]) => members.map((member) => member.owner_id))),
137
144
  ];
138
145
  const userResults = await Promise.allSettled(ownerIDs.map(async (id) => [id, await this.findUser(id)]));
139
146
  const usersByID = new Map(userResults.flatMap((result) => result.status === "fulfilled" ? [result.value] : []));
140
- return Object.fromEntries(roomIDs.map((chatRoomID) => {
141
- const roomMembers = membersByRoom.get(chatRoomID) ?? [];
142
- return [
143
- chatRoomID,
144
- {
145
- members: roomMembers,
146
- users: roomMembers.flatMap((member) => {
147
- const user = usersByID.get(member.owner_id);
148
- return user ? [user] : [];
149
- }),
150
- },
151
- ];
152
- }));
147
+ return Object.fromEntries(entries.map(([chatRoomID, members]) => [
148
+ chatRoomID,
149
+ {
150
+ members,
151
+ users: members.flatMap((member) => {
152
+ const user = usersByID.get(member.owner_id);
153
+ return user ? [user] : [];
154
+ }),
155
+ },
156
+ ]));
153
157
  }
154
158
  async openChatRoom(opts) {
155
159
  const latest = await this.latestChats({
@@ -215,7 +219,7 @@ export class ChatFX {
215
219
  closeSession(closeCodeNormal, reason);
216
220
  },
217
221
  closeLeavingPage(reason) {
218
- closeSession(closeCodeNormal, reason);
222
+ closeSession(closeCodeLeavingPage, reason);
219
223
  },
220
224
  };
221
225
  }
@@ -223,6 +227,9 @@ export class ChatFX {
223
227
  const members = await this.myChatRoomMembers({
224
228
  owner_id: opts.owner_id,
225
229
  });
230
+ const rooms = await this.chatRooms({
231
+ ids: members.map((member) => member.chat_room_id),
232
+ });
226
233
  const fx = this;
227
234
  let current = await fx.openGlobalChatRoomsConnection(opts);
228
235
  let refresh_timer = null;
@@ -272,6 +279,7 @@ export class ChatFX {
272
279
  }
273
280
  return {
274
281
  members,
282
+ rooms,
275
283
  get chat_rooms_ws() {
276
284
  return current.chat_rooms_ws;
277
285
  },
@@ -279,7 +287,7 @@ export class ChatFX {
279
287
  closeSession(closeCodeNormal, reason);
280
288
  },
281
289
  closeLeavingPage(reason) {
282
- closeSession(closeCodeNormal, reason);
290
+ closeSession(closeCodeLeavingPage, reason);
283
291
  },
284
292
  };
285
293
  }
@@ -412,6 +420,21 @@ export class ChatFX {
412
420
  },
413
421
  };
414
422
  }
423
+ async allChatRoomMembers(chatRoomID) {
424
+ const out = [];
425
+ let page = 1;
426
+ for (;;) {
427
+ const next = await this.searchChatRoomMembers({
428
+ chat_room_id: chatRoomID,
429
+ page,
430
+ });
431
+ out.push(...next.results);
432
+ if (next.done) {
433
+ return out;
434
+ }
435
+ page = next.next_page;
436
+ }
437
+ }
415
438
  async findUser(id) {
416
439
  const out = await this.users.findOneUser({ id });
417
440
  const user = out.value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabriktor/fx",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "description": "![Fabriktor Logo](./img/fabriktor-character.gif)",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,7 +17,7 @@
17
17
  "typescript": "^6.0.3"
18
18
  },
19
19
  "dependencies": {
20
- "@fabriktor/client": "0.0.52",
20
+ "@fabriktor/client": "0.0.54",
21
21
  "@fabriktor/schema": "0.0.34"
22
22
  }
23
23
  }