@jsm-mit/chat-motoko-package 0.4.0 → 0.6.0

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/README.md CHANGED
@@ -10,23 +10,29 @@ import { RoomsActor, ChatsActor, MessagesActor, ChatPoller } from "@jsm-mit/chat
10
10
  // A canister admin creates the project with its accounts canister — the one asked
11
11
  // `isUser(principal)` before a non-admin opens a chat (Sultana: sultana-core-motoko).
12
12
  // A project admin defines a room: who receives the customer's messages.
13
+ // One room per thing the app wants a conversation about (Sultana: per salon), closed to
14
+ // the people who may open it — an empty allowedCustomers means everybody with an account.
13
15
  await new RoomsActor(canisterId, adminIdentity).createRoomAsyncUnsafe({
14
- projectId: "sultana-stage", id: "assistant", name: "Asystent",
16
+ projectId: "sultana-stage", id: `salon-${salonId}`, name: "Asystent salonu",
15
17
  recipients: [{ principal: villagePrincipal, role: "agent", displayName: "Asystentka Ola" }],
18
+ allowedCustomers: [ownerPrincipal],
16
19
  });
17
20
 
18
- // A customer opens the room at a desk (what the chat is about — here a salon); the same
19
- // call returns the same chat next time, another desk opens another chat.
20
- const chat = await new ChatsActor(canisterId, identity).openChatAsyncUnsafe({ projectId: "sultana-stage", roomId: "assistant", desk: salonId, customerName: "Michał" });
21
+ // The customer opens the room; the same call returns the same chat next time.
22
+ const chat = await new ChatsActor(canisterId, identity).openChatAsyncUnsafe({ projectId: "sultana-stage", roomId: `salon-${salonId}`, customerName: "Michał" });
21
23
 
22
24
  const messages = new MessagesActor(canisterId, identity);
23
25
  await messages.postAsyncUnsafe({ chatId: chat.id, text: "dodaj usługę strzyżenie" });
26
+
27
+ // The page carries the thread AND what the others are doing: `presence[].typing` while
28
+ // somebody is writing (a room's recipients report it with setTypingAsyncUnsafe, and their
29
+ // own post clears it), `presence[].lastReadSeq` for "read up to here".
24
30
  const page = await messages.getMessagesAsyncUnsafe({ chatId: chat.id, sinceSeq: 0 });
25
31
 
26
32
  // An agent host: every new message in every chat this identity is a recipient of, with
27
33
  // the room and the customer on each message — route by (projectId, roomId).
28
34
  const poller = new ChatPoller(messages, 1000, { onError: console.error });
29
- poller.messages$.subscribe((m) => console.log(m.roomId, m.desk, m.customer, m.kind, m.text));
35
+ poller.messages$.subscribe((m) => console.log(m.roomId, m.customer, m.kind, m.text));
30
36
  poller.run();
31
37
  ```
32
38
 
@@ -1,5 +1,6 @@
1
1
  type UpdateRoomArgs =
2
2
  record {
3
+ allowedCustomers: opt vec principal;
3
4
  name: opt text;
4
5
  projectId: ProjectId;
5
6
  recipients: opt vec Recipient;
@@ -12,11 +13,13 @@ type UpdateProjectArgs =
12
13
  projectId: ProjectId;
13
14
  };
14
15
  type SystemEvent = variant {chatCreated;};
16
+ type SetTypingArgs = record {chatId: ChatId;};
15
17
  type SetQuotaLimitsArgs = record {limits: QuotaLimits;};
16
18
  type SetLoggingEnabledArgs = record {enabled: bool;};
17
19
  type RoomId = text;
18
20
  type Room =
19
21
  record {
22
+ allowedCustomers: vec principal;
20
23
  createdAt: int;
21
24
  createdBy: principal;
22
25
  id: RoomId;
@@ -63,12 +66,12 @@ type Result_4 =
63
66
  type Result_3 =
64
67
  variant {
65
68
  err: Error;
66
- ok: bool;
69
+ ok: QuotaLimits;
67
70
  };
68
71
  type Result_2 =
69
72
  variant {
70
73
  err: Error;
71
- ok: QuotaLimits;
74
+ ok: bool;
72
75
  };
73
76
  type Result_13 =
74
77
  variant {
@@ -127,6 +130,12 @@ type Project =
127
130
  createdBy: principal;
128
131
  id: ProjectId;
129
132
  };
133
+ type Presence =
134
+ record {
135
+ lastReadSeq: nat;
136
+ "principal": principal;
137
+ typingUntil: int;
138
+ };
130
139
  type PostKind =
131
140
  variant {
132
141
  "text";
@@ -161,7 +170,6 @@ type Participant =
161
170
  type OpenChatArgs =
162
171
  record {
163
172
  customerName: opt text;
164
- desk: opt text;
165
173
  projectId: ProjectId;
166
174
  roomId: RoomId;
167
175
  };
@@ -169,6 +177,7 @@ type MessagesPage =
169
177
  record {
170
178
  lastSeq: nat;
171
179
  messages: vec Message;
180
+ presence: vec Presence;
172
181
  };
173
182
  type MessageKind =
174
183
  variant {
@@ -182,7 +191,6 @@ type Message =
182
191
  chatId: ChatId;
183
192
  createdAt: int;
184
193
  customer: principal;
185
- desk: opt text;
186
194
  globalSeq: nat;
187
195
  kind: MessageKind;
188
196
  projectId: ProjectId;
@@ -198,12 +206,12 @@ type MarkReadArgs =
198
206
  type ListRoomsArgs =
199
207
  record {
200
208
  limit: opt nat;
209
+ offset: opt nat;
201
210
  projectId: ProjectId;
202
211
  };
203
212
  type ListProjectsArgs = record {limit: opt nat;};
204
213
  type ListProjectChatsArgs =
205
214
  record {
206
- desk: opt text;
207
215
  limit: opt nat;
208
216
  projectId: ProjectId;
209
217
  roomId: opt RoomId;
@@ -216,7 +224,6 @@ type GetRoomArgs =
216
224
  type GetProjectArgs = record {projectId: ProjectId;};
217
225
  type GetMyChatsArgs =
218
226
  record {
219
- desk: opt text;
220
227
  limit: opt nat;
221
228
  projectId: ProjectId;
222
229
  roomId: opt RoomId;
@@ -245,6 +252,7 @@ type Error =
245
252
  };
246
253
  type CreateRoomArgs =
247
254
  record {
255
+ allowedCustomers: vec principal;
248
256
  id: RoomId;
249
257
  name: text;
250
258
  projectId: ProjectId;
@@ -260,7 +268,6 @@ type ChatSummary =
260
268
  record {
261
269
  createdAt: int;
262
270
  customer: principal;
263
- desk: opt text;
264
271
  id: ChatId;
265
272
  lastMessageAt: int;
266
273
  messageCount: nat;
@@ -273,7 +280,6 @@ type Chat =
273
280
  record {
274
281
  createdAt: int;
275
282
  customer: principal;
276
- desk: opt text;
277
283
  id: ChatId;
278
284
  lastMessageAt: int;
279
285
  lastSeq: nat;
@@ -283,7 +289,7 @@ type Chat =
283
289
  };
284
290
  type AddAdminArgs = record {"principal": principal;};
285
291
  service : {
286
- addAdmin: (args: AddAdminArgs) -> (Result_3);
292
+ addAdmin: (args: AddAdminArgs) -> (Result_2);
287
293
  clearLogs: () -> ();
288
294
  createProject: (args: CreateProjectArgs) -> (Result_1);
289
295
  createRoom: (args: CreateRoomArgs) -> (Result);
@@ -293,20 +299,22 @@ service : {
293
299
  getMessages: (args: GetMessagesArgs) -> (Result_12) query;
294
300
  getMyChats: (args: GetMyChatsArgs) -> (Result_11) query;
295
301
  getProject: (args: GetProjectArgs) -> (Result_1) query;
296
- getQuotaLimits: () -> (Result_2) query;
302
+ getQuotaLimits: () -> (Result_3) query;
297
303
  getRoom: (args: GetRoomArgs) -> (Result) query;
298
304
  listProjectChats: (args: ListProjectChatsArgs) -> (Result_10) query;
299
305
  listProjects: (args: ListProjectsArgs) -> (Result_9) query;
300
306
  listRooms: (args: ListRoomsArgs) -> (Result_8) query;
301
- markRead: (args: MarkReadArgs) -> (Result_3);
307
+ markRead: (args: MarkReadArgs) -> (Result_2);
302
308
  openChat: (args: OpenChatArgs) -> (Result_7);
303
309
  pollNewMessages: (args: PollNewMessagesArgs) -> (Result_6) query;
304
310
  post: (args: PostArgs) -> (Result_5);
305
- purgeChat: (args: PurgeChatArgs) -> (Result_3);
311
+ purgeChat: (args: PurgeChatArgs) -> (Result_2);
306
312
  registerAsAdmin: () -> (Result_4);
307
- removeAdmin: (args: RemoveAdminArgs) -> (Result_3);
308
- setLoggingEnabled: (args: SetLoggingEnabledArgs) -> (Result_3);
309
- setQuotaLimits: (args: SetQuotaLimitsArgs) -> (Result_2);
313
+ removeAdmin: (args: RemoveAdminArgs) -> (Result_2);
314
+ setLoggingEnabled: (args: SetLoggingEnabledArgs) -> (Result_2);
315
+ setQuotaLimits: (args: SetQuotaLimitsArgs) -> (Result_3);
316
+ /// "I am writing" — a room's recipients only; it expires by itself and a post clears it.
317
+ setTyping: (args: SetTypingArgs) -> (Result_2);
310
318
  updateProject: (args: UpdateProjectArgs) -> (Result_1);
311
319
  updateRoom: (args: UpdateRoomArgs) -> (Result);
312
320
  whoAmI: () -> (principal) query;
@@ -8,7 +8,6 @@ export interface Chat {
8
8
  'participants' : Array<Participant>,
9
9
  'lastMessageAt' : bigint,
10
10
  'customer' : Principal,
11
- 'desk' : [] | [string],
12
11
  'createdAt' : bigint,
13
12
  'projectId' : ProjectId,
14
13
  'roomId' : RoomId,
@@ -19,7 +18,6 @@ export interface ChatSummary {
19
18
  'id' : ChatId,
20
19
  'lastMessageAt' : bigint,
21
20
  'customer' : Principal,
22
- 'desk' : [] | [string],
23
21
  'createdAt' : bigint,
24
22
  'projectId' : ProjectId,
25
23
  'messageCount' : bigint,
@@ -36,6 +34,7 @@ export interface CreateRoomArgs {
36
34
  'name' : string,
37
35
  'recipients' : Array<Recipient>,
38
36
  'projectId' : ProjectId,
37
+ 'allowedCustomers' : Array<Principal>,
39
38
  }
40
39
  export interface Error { 'details' : ErrorDetails, 'logsJson' : string }
41
40
  export type ErrorDetails = { 'InterCanisterConnectionError' : null } |
@@ -52,7 +51,6 @@ export interface GetMessagesArgs {
52
51
  'sinceSeq' : bigint,
53
52
  }
54
53
  export interface GetMyChatsArgs {
55
- 'desk' : [] | [string],
56
54
  'limit' : [] | [bigint],
57
55
  'projectId' : ProjectId,
58
56
  'roomId' : [] | [RoomId],
@@ -60,13 +58,13 @@ export interface GetMyChatsArgs {
60
58
  export interface GetProjectArgs { 'projectId' : ProjectId }
61
59
  export interface GetRoomArgs { 'projectId' : ProjectId, 'roomId' : RoomId }
62
60
  export interface ListProjectChatsArgs {
63
- 'desk' : [] | [string],
64
61
  'limit' : [] | [bigint],
65
62
  'projectId' : ProjectId,
66
63
  'roomId' : [] | [RoomId],
67
64
  }
68
65
  export interface ListProjectsArgs { 'limit' : [] | [bigint] }
69
66
  export interface ListRoomsArgs {
67
+ 'offset' : [] | [bigint],
70
68
  'limit' : [] | [bigint],
71
69
  'projectId' : ProjectId,
72
70
  }
@@ -74,7 +72,6 @@ export interface MarkReadArgs { 'seq' : bigint, 'chatId' : ChatId }
74
72
  export interface Message {
75
73
  'seq' : bigint,
76
74
  'customer' : Principal,
77
- 'desk' : [] | [string],
78
75
  'kind' : MessageKind,
79
76
  'createdAt' : bigint,
80
77
  'text' : string,
@@ -89,11 +86,11 @@ export type MessageKind = { 'toolTrace' : null } |
89
86
  { 'event' : SystemEvent };
90
87
  export interface MessagesPage {
91
88
  'messages' : Array<Message>,
89
+ 'presence' : Array<Presence>,
92
90
  'lastSeq' : bigint,
93
91
  }
94
92
  export interface OpenChatArgs {
95
93
  'customerName' : [] | [string],
96
- 'desk' : [] | [string],
97
94
  'projectId' : ProjectId,
98
95
  'roomId' : RoomId,
99
96
  }
@@ -121,6 +118,11 @@ export interface PostArgs {
121
118
  }
122
119
  export type PostKind = { 'toolTrace' : null } |
123
120
  { 'text' : null };
121
+ export interface Presence {
122
+ 'principal' : Principal,
123
+ 'typingUntil' : bigint,
124
+ 'lastReadSeq' : bigint,
125
+ }
124
126
  export interface Project {
125
127
  'id' : ProjectId,
126
128
  'createdAt' : bigint,
@@ -151,9 +153,9 @@ export type Result_12 = { 'ok' : MessagesPage } |
151
153
  { 'err' : Error };
152
154
  export type Result_13 = { 'ok' : Array<Principal> } |
153
155
  { 'err' : Error };
154
- export type Result_2 = { 'ok' : QuotaLimits } |
156
+ export type Result_2 = { 'ok' : boolean } |
155
157
  { 'err' : Error };
156
- export type Result_3 = { 'ok' : boolean } |
158
+ export type Result_3 = { 'ok' : QuotaLimits } |
157
159
  { 'err' : Error };
158
160
  export type Result_4 = { 'ok' : Principal } |
159
161
  { 'err' : Error };
@@ -177,10 +179,12 @@ export interface Room {
177
179
  'createdBy' : Principal,
178
180
  'recipients' : Array<Recipient>,
179
181
  'projectId' : ProjectId,
182
+ 'allowedCustomers' : Array<Principal>,
180
183
  }
181
184
  export type RoomId = string;
182
185
  export interface SetLoggingEnabledArgs { 'enabled' : boolean }
183
186
  export interface SetQuotaLimitsArgs { 'limits' : QuotaLimits }
187
+ export interface SetTypingArgs { 'chatId' : ChatId }
184
188
  export type SystemEvent = { 'chatCreated' : null };
185
189
  export interface UpdateProjectArgs {
186
190
  'accountsCanister' : [] | [Principal],
@@ -192,9 +196,10 @@ export interface UpdateRoomArgs {
192
196
  'recipients' : [] | [Array<Recipient>],
193
197
  'projectId' : ProjectId,
194
198
  'roomId' : RoomId,
199
+ 'allowedCustomers' : [] | [Array<Principal>],
195
200
  }
196
201
  export interface _SERVICE {
197
- 'addAdmin' : ActorMethod<[AddAdminArgs], Result_3>,
202
+ 'addAdmin' : ActorMethod<[AddAdminArgs], Result_2>,
198
203
  'clearLogs' : ActorMethod<[], undefined>,
199
204
  'createProject' : ActorMethod<[CreateProjectArgs], Result_1>,
200
205
  'createRoom' : ActorMethod<[CreateRoomArgs], Result>,
@@ -204,20 +209,24 @@ export interface _SERVICE {
204
209
  'getMessages' : ActorMethod<[GetMessagesArgs], Result_12>,
205
210
  'getMyChats' : ActorMethod<[GetMyChatsArgs], Result_11>,
206
211
  'getProject' : ActorMethod<[GetProjectArgs], Result_1>,
207
- 'getQuotaLimits' : ActorMethod<[], Result_2>,
212
+ 'getQuotaLimits' : ActorMethod<[], Result_3>,
208
213
  'getRoom' : ActorMethod<[GetRoomArgs], Result>,
209
214
  'listProjectChats' : ActorMethod<[ListProjectChatsArgs], Result_10>,
210
215
  'listProjects' : ActorMethod<[ListProjectsArgs], Result_9>,
211
216
  'listRooms' : ActorMethod<[ListRoomsArgs], Result_8>,
212
- 'markRead' : ActorMethod<[MarkReadArgs], Result_3>,
217
+ 'markRead' : ActorMethod<[MarkReadArgs], Result_2>,
213
218
  'openChat' : ActorMethod<[OpenChatArgs], Result_7>,
214
219
  'pollNewMessages' : ActorMethod<[PollNewMessagesArgs], Result_6>,
215
220
  'post' : ActorMethod<[PostArgs], Result_5>,
216
- 'purgeChat' : ActorMethod<[PurgeChatArgs], Result_3>,
221
+ 'purgeChat' : ActorMethod<[PurgeChatArgs], Result_2>,
217
222
  'registerAsAdmin' : ActorMethod<[], Result_4>,
218
- 'removeAdmin' : ActorMethod<[RemoveAdminArgs], Result_3>,
219
- 'setLoggingEnabled' : ActorMethod<[SetLoggingEnabledArgs], Result_3>,
220
- 'setQuotaLimits' : ActorMethod<[SetQuotaLimitsArgs], Result_2>,
223
+ 'removeAdmin' : ActorMethod<[RemoveAdminArgs], Result_2>,
224
+ 'setLoggingEnabled' : ActorMethod<[SetLoggingEnabledArgs], Result_2>,
225
+ 'setQuotaLimits' : ActorMethod<[SetQuotaLimitsArgs], Result_3>,
226
+ /**
227
+ * / "I am writing" — a room's recipients only; it expires by itself and a post clears it.
228
+ */
229
+ 'setTyping' : ActorMethod<[SetTypingArgs], Result_2>,
221
230
  'updateProject' : ActorMethod<[UpdateProjectArgs], Result_1>,
222
231
  'updateRoom' : ActorMethod<[UpdateRoomArgs], Result>,
223
232
  'whoAmI' : ActorMethod<[], Principal>,
@@ -10,7 +10,7 @@ export const idlFactory = ({ IDL }) => {
10
10
  'ReturnsNull' : IDL.Null,
11
11
  });
12
12
  const Error = IDL.Record({ 'details' : ErrorDetails, 'logsJson' : IDL.Text });
13
- const Result_3 = IDL.Variant({ 'ok' : IDL.Bool, 'err' : Error });
13
+ const Result_2 = IDL.Variant({ 'ok' : IDL.Bool, 'err' : Error });
14
14
  const ProjectId = IDL.Text;
15
15
  const CreateProjectArgs = IDL.Record({
16
16
  'id' : ProjectId,
@@ -40,6 +40,7 @@ export const idlFactory = ({ IDL }) => {
40
40
  'name' : IDL.Text,
41
41
  'recipients' : IDL.Vec(Recipient),
42
42
  'projectId' : ProjectId,
43
+ 'allowedCustomers' : IDL.Vec(IDL.Principal),
43
44
  });
44
45
  const Room = IDL.Record({
45
46
  'id' : RoomId,
@@ -48,6 +49,7 @@ export const idlFactory = ({ IDL }) => {
48
49
  'createdBy' : IDL.Principal,
49
50
  'recipients' : IDL.Vec(Recipient),
50
51
  'projectId' : ProjectId,
52
+ 'allowedCustomers' : IDL.Vec(IDL.Principal),
51
53
  });
52
54
  const Result = IDL.Variant({ 'ok' : Room, 'err' : Error });
53
55
  const Result_13 = IDL.Variant({
@@ -74,7 +76,6 @@ export const idlFactory = ({ IDL }) => {
74
76
  'participants' : IDL.Vec(Participant),
75
77
  'lastMessageAt' : IDL.Int,
76
78
  'customer' : IDL.Principal,
77
- 'desk' : IDL.Opt(IDL.Text),
78
79
  'createdAt' : IDL.Int,
79
80
  'projectId' : ProjectId,
80
81
  'roomId' : RoomId,
@@ -95,7 +96,6 @@ export const idlFactory = ({ IDL }) => {
95
96
  const Message = IDL.Record({
96
97
  'seq' : IDL.Nat,
97
98
  'customer' : IDL.Principal,
98
- 'desk' : IDL.Opt(IDL.Text),
99
99
  'kind' : MessageKind,
100
100
  'createdAt' : IDL.Int,
101
101
  'text' : IDL.Text,
@@ -105,13 +105,18 @@ export const idlFactory = ({ IDL }) => {
105
105
  'chatId' : ChatId,
106
106
  'roomId' : RoomId,
107
107
  });
108
+ const Presence = IDL.Record({
109
+ 'principal' : IDL.Principal,
110
+ 'typingUntil' : IDL.Int,
111
+ 'lastReadSeq' : IDL.Nat,
112
+ });
108
113
  const MessagesPage = IDL.Record({
109
114
  'messages' : IDL.Vec(Message),
115
+ 'presence' : IDL.Vec(Presence),
110
116
  'lastSeq' : IDL.Nat,
111
117
  });
112
118
  const Result_12 = IDL.Variant({ 'ok' : MessagesPage, 'err' : Error });
113
119
  const GetMyChatsArgs = IDL.Record({
114
- 'desk' : IDL.Opt(IDL.Text),
115
120
  'limit' : IDL.Opt(IDL.Nat),
116
121
  'projectId' : ProjectId,
117
122
  'roomId' : IDL.Opt(RoomId),
@@ -119,13 +124,12 @@ export const idlFactory = ({ IDL }) => {
119
124
  const Result_11 = IDL.Variant({ 'ok' : IDL.Vec(Chat), 'err' : Error });
120
125
  const GetProjectArgs = IDL.Record({ 'projectId' : ProjectId });
121
126
  const QuotaLimits = IDL.Record({ 'chats' : IDL.Nat, 'posts' : IDL.Nat });
122
- const Result_2 = IDL.Variant({ 'ok' : QuotaLimits, 'err' : Error });
127
+ const Result_3 = IDL.Variant({ 'ok' : QuotaLimits, 'err' : Error });
123
128
  const GetRoomArgs = IDL.Record({
124
129
  'projectId' : ProjectId,
125
130
  'roomId' : RoomId,
126
131
  });
127
132
  const ListProjectChatsArgs = IDL.Record({
128
- 'desk' : IDL.Opt(IDL.Text),
129
133
  'limit' : IDL.Opt(IDL.Nat),
130
134
  'projectId' : ProjectId,
131
135
  'roomId' : IDL.Opt(RoomId),
@@ -134,7 +138,6 @@ export const idlFactory = ({ IDL }) => {
134
138
  'id' : ChatId,
135
139
  'lastMessageAt' : IDL.Int,
136
140
  'customer' : IDL.Principal,
137
- 'desk' : IDL.Opt(IDL.Text),
138
141
  'createdAt' : IDL.Int,
139
142
  'projectId' : ProjectId,
140
143
  'messageCount' : IDL.Nat,
@@ -145,6 +148,7 @@ export const idlFactory = ({ IDL }) => {
145
148
  const ListProjectsArgs = IDL.Record({ 'limit' : IDL.Opt(IDL.Nat) });
146
149
  const Result_9 = IDL.Variant({ 'ok' : IDL.Vec(Project), 'err' : Error });
147
150
  const ListRoomsArgs = IDL.Record({
151
+ 'offset' : IDL.Opt(IDL.Nat),
148
152
  'limit' : IDL.Opt(IDL.Nat),
149
153
  'projectId' : ProjectId,
150
154
  });
@@ -152,7 +156,6 @@ export const idlFactory = ({ IDL }) => {
152
156
  const MarkReadArgs = IDL.Record({ 'seq' : IDL.Nat, 'chatId' : ChatId });
153
157
  const OpenChatArgs = IDL.Record({
154
158
  'customerName' : IDL.Opt(IDL.Text),
155
- 'desk' : IDL.Opt(IDL.Text),
156
159
  'projectId' : ProjectId,
157
160
  'roomId' : RoomId,
158
161
  });
@@ -178,6 +181,7 @@ export const idlFactory = ({ IDL }) => {
178
181
  const RemoveAdminArgs = IDL.Record({ 'principal' : IDL.Principal });
179
182
  const SetLoggingEnabledArgs = IDL.Record({ 'enabled' : IDL.Bool });
180
183
  const SetQuotaLimitsArgs = IDL.Record({ 'limits' : QuotaLimits });
184
+ const SetTypingArgs = IDL.Record({ 'chatId' : ChatId });
181
185
  const UpdateProjectArgs = IDL.Record({
182
186
  'accountsCanister' : IDL.Opt(IDL.Principal),
183
187
  'projectId' : ProjectId,
@@ -188,9 +192,10 @@ export const idlFactory = ({ IDL }) => {
188
192
  'recipients' : IDL.Opt(IDL.Vec(Recipient)),
189
193
  'projectId' : ProjectId,
190
194
  'roomId' : RoomId,
195
+ 'allowedCustomers' : IDL.Opt(IDL.Vec(IDL.Principal)),
191
196
  });
192
197
  return IDL.Service({
193
- 'addAdmin' : IDL.Func([AddAdminArgs], [Result_3], []),
198
+ 'addAdmin' : IDL.Func([AddAdminArgs], [Result_2], []),
194
199
  'clearLogs' : IDL.Func([], [], []),
195
200
  'createProject' : IDL.Func([CreateProjectArgs], [Result_1], []),
196
201
  'createRoom' : IDL.Func([CreateRoomArgs], [Result], []),
@@ -200,7 +205,7 @@ export const idlFactory = ({ IDL }) => {
200
205
  'getMessages' : IDL.Func([GetMessagesArgs], [Result_12], ['query']),
201
206
  'getMyChats' : IDL.Func([GetMyChatsArgs], [Result_11], ['query']),
202
207
  'getProject' : IDL.Func([GetProjectArgs], [Result_1], ['query']),
203
- 'getQuotaLimits' : IDL.Func([], [Result_2], ['query']),
208
+ 'getQuotaLimits' : IDL.Func([], [Result_3], ['query']),
204
209
  'getRoom' : IDL.Func([GetRoomArgs], [Result], ['query']),
205
210
  'listProjectChats' : IDL.Func(
206
211
  [ListProjectChatsArgs],
@@ -209,15 +214,16 @@ export const idlFactory = ({ IDL }) => {
209
214
  ),
210
215
  'listProjects' : IDL.Func([ListProjectsArgs], [Result_9], ['query']),
211
216
  'listRooms' : IDL.Func([ListRoomsArgs], [Result_8], ['query']),
212
- 'markRead' : IDL.Func([MarkReadArgs], [Result_3], []),
217
+ 'markRead' : IDL.Func([MarkReadArgs], [Result_2], []),
213
218
  'openChat' : IDL.Func([OpenChatArgs], [Result_7], []),
214
219
  'pollNewMessages' : IDL.Func([PollNewMessagesArgs], [Result_6], ['query']),
215
220
  'post' : IDL.Func([PostArgs], [Result_5], []),
216
- 'purgeChat' : IDL.Func([PurgeChatArgs], [Result_3], []),
221
+ 'purgeChat' : IDL.Func([PurgeChatArgs], [Result_2], []),
217
222
  'registerAsAdmin' : IDL.Func([], [Result_4], []),
218
- 'removeAdmin' : IDL.Func([RemoveAdminArgs], [Result_3], []),
219
- 'setLoggingEnabled' : IDL.Func([SetLoggingEnabledArgs], [Result_3], []),
220
- 'setQuotaLimits' : IDL.Func([SetQuotaLimitsArgs], [Result_2], []),
223
+ 'removeAdmin' : IDL.Func([RemoveAdminArgs], [Result_2], []),
224
+ 'setLoggingEnabled' : IDL.Func([SetLoggingEnabledArgs], [Result_2], []),
225
+ 'setQuotaLimits' : IDL.Func([SetQuotaLimitsArgs], [Result_3], []),
226
+ 'setTyping' : IDL.Func([SetTypingArgs], [Result_2], []),
221
227
  'updateProject' : IDL.Func([UpdateProjectArgs], [Result_1], []),
222
228
  'updateRoom' : IDL.Func([UpdateRoomArgs], [Result], []),
223
229
  'whoAmI' : IDL.Func([], [IDL.Principal], ['query']),
@@ -7,10 +7,11 @@ export declare class ChatsActor extends ActorBase {
7
7
  /**
8
8
  * Opens the caller's chat in a room: the caller becomes the `customer`, the room's
9
9
  * recipients are copied in, the canister writes the `chatCreated` event. One chat per
10
- * (room, customer, recipients, desk) — calling again returns the same chat unchanged. A NEW
11
- * chat is created only once the project's accounts canister confirms the caller
12
- * (`isUser`); admins of the canister and of the project skip that.
13
- * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` also when the accounts canister does not know the caller, `NotFound` for the room, `InvalidData` when the caller is a recipient of the room, the name is too long or the daily chat limit is reached, `InterCanisterConnectionError` when the accounts canister cannot be asked). Examine "cause" for {errorKey, errorMessage, logs}.
10
+ * (room, customer, recipients) — calling again returns the same chat unchanged. A NEW
11
+ * chat needs the room to allow the caller (its allowed-customer list, when it has one)
12
+ * and the project's accounts canister to confirm the caller (`isUser`); admins of the
13
+ * canister and of the project skip the accounts call but not the allowed list.
14
+ * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` when the room's allowed-customer list does not name the caller or the accounts canister does not know them, `NotFound` for the room, `InvalidData` when the caller is a recipient of the room, the name is too long or the daily chat limit is reached, `InterCanisterConnectionError` when the accounts canister cannot be asked). Examine "cause" for {errorKey, errorMessage, logs}.
14
15
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
15
16
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution (anonymous, or today's chat quota used up).
16
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"chats-actor.d.ts","sourceRoot":"","sources":["../../src/actors/chats-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGzH,gFAAgF;AAChF,qBAAa,UAAW,SAAQ,SAAS;gBAEzB,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;;;;OASG;IACU,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAYzE;;;;;OAKG;IACU,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKlE;;;;;;OAMG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAY/E;;;;;;OAMG;IACU,2BAA2B,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAYlG;;;;;;;OAOG;IACU,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGtE"}
1
+ {"version":3,"file":"chats-actor.d.ts","sourceRoot":"","sources":["../../src/actors/chats-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGzH,gFAAgF;AAChF,qBAAa,UAAW,SAAQ,SAAS;gBAEzB,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;;;;;OAUG;IACU,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWzE;;;;;OAKG;IACU,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKlE;;;;;;OAMG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAW/E;;;;;;OAMG;IACU,2BAA2B,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAWlG;;;;;;;OAOG;IACU,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGtE"}
@@ -9,10 +9,11 @@ export class ChatsActor extends ActorBase {
9
9
  /**
10
10
  * Opens the caller's chat in a room: the caller becomes the `customer`, the room's
11
11
  * recipients are copied in, the canister writes the `chatCreated` event. One chat per
12
- * (room, customer, recipients, desk) — calling again returns the same chat unchanged. A NEW
13
- * chat is created only once the project's accounts canister confirms the caller
14
- * (`isUser`); admins of the canister and of the project skip that.
15
- * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` also when the accounts canister does not know the caller, `NotFound` for the room, `InvalidData` when the caller is a recipient of the room, the name is too long or the daily chat limit is reached, `InterCanisterConnectionError` when the accounts canister cannot be asked). Examine "cause" for {errorKey, errorMessage, logs}.
12
+ * (room, customer, recipients) — calling again returns the same chat unchanged. A NEW
13
+ * chat needs the room to allow the caller (its allowed-customer list, when it has one)
14
+ * and the project's accounts canister to confirm the caller (`isUser`); admins of the
15
+ * canister and of the project skip the accounts call but not the allowed list.
16
+ * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` when the room's allowed-customer list does not name the caller or the accounts canister does not know them, `NotFound` for the room, `InvalidData` when the caller is a recipient of the room, the name is too long or the daily chat limit is reached, `InterCanisterConnectionError` when the accounts canister cannot be asked). Examine "cause" for {errorKey, errorMessage, logs}.
16
17
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
17
18
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution (anonymous, or today's chat quota used up).
18
19
  */
@@ -20,7 +21,6 @@ export class ChatsActor extends ActorBase {
20
21
  const chat = await this.executeFunctionAsyncUnsafe(() => this.actor.openChat({
21
22
  projectId: input.projectId,
22
23
  roomId: input.roomId,
23
- desk: toOpt(input.desk),
24
24
  customerName: toOpt(input.customerName),
25
25
  }));
26
26
  return mapChatView(chat);
@@ -46,7 +46,6 @@ export class ChatsActor extends ActorBase {
46
46
  const chats = await this.executeFunctionAsyncUnsafe(() => this.actor.getMyChats({
47
47
  projectId: input.projectId,
48
48
  roomId: toOpt(input.roomId),
49
- desk: toOpt(input.desk),
50
49
  limit: toOptBigInt(input.limit),
51
50
  }));
52
51
  return chats.map(mapChatView);
@@ -62,7 +61,6 @@ export class ChatsActor extends ActorBase {
62
61
  const summaries = await this.executeFunctionAsyncUnsafe(() => this.actor.listProjectChats({
63
62
  projectId: input.projectId,
64
63
  roomId: toOpt(input.roomId),
65
- desk: toOpt(input.desk),
66
64
  limit: toOptBigInt(input.limit),
67
65
  }));
68
66
  return summaries.map(mapChatSummaryView);
@@ -22,7 +22,18 @@ export declare class MessagesActor extends ActorBase {
22
22
  */
23
23
  markReadAsyncUnsafe(chatId: string, seq: number): Promise<boolean>;
24
24
  /**
25
- * A chat's messages with seq > sinceSeq, oldest first (max 200 per call).
25
+ * Reports that the caller is writing: true for 30 seconds, cleared by their own next
26
+ * post, and gone by itself afterwards — so a client that dies mid-turn leaves no
27
+ * indicator hanging. A ROOM'S RECIPIENTS ONLY (a person or an agent); a customer is
28
+ * refused. Send it once at the start of a turn, not per keystroke.
29
+ * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` for a customer or a non-participant, `NotFound` for the chat). Examine "cause" for {errorKey, errorMessage, logs}.
30
+ * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
31
+ * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
32
+ */
33
+ setTypingAsyncUnsafe(chatId: string): Promise<boolean>;
34
+ /**
35
+ * A chat's messages with seq > sinceSeq, oldest first (max 200 per call), together
36
+ * with `presence`: who is typing and how far each other participant has read.
26
37
  * Participants only.
27
38
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound`). Examine "cause" for {errorKey, errorMessage, logs}.
28
39
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
@@ -1 +1 @@
1
- {"version":3,"file":"messages-actor.d.ts","sourceRoot":"","sources":["../../src/actors/messages-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGzI,yDAAyD;AACzD,qBAAa,aAAc,SAAQ,SAAS;gBAE5B,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;OAMG;IACU,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAWpE,2EAA2E;IAC9D,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAQzE;;;;;OAKG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/E;;;;;;OAMG;IACU,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWvF;;;;;;;OAOG;IACU,0BAA0B,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAU7F,sFAAsF;IACzE,wBAAwB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAOrG"}
1
+ {"version":3,"file":"messages-actor.d.ts","sourceRoot":"","sources":["../../src/actors/messages-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGzI,yDAAyD;AACzD,qBAAa,aAAc,SAAQ,SAAS;gBAE5B,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;OAMG;IACU,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAWpE,2EAA2E;IAC9D,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAQzE;;;;;OAKG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/E;;;;;;;;OAQG;IACU,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAInE;;;;;;;OAOG;IACU,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWvF;;;;;;;OAOG;IACU,0BAA0B,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAU7F,sFAAsF;IACzE,wBAAwB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAOrG"}
@@ -40,7 +40,20 @@ export class MessagesActor extends ActorBase {
40
40
  return this.executeFunctionAsyncUnsafe(() => this.actor.markRead({ chatId, seq: BigInt(seq) }));
41
41
  }
42
42
  /**
43
- * A chat's messages with seq > sinceSeq, oldest first (max 200 per call).
43
+ * Reports that the caller is writing: true for 30 seconds, cleared by their own next
44
+ * post, and gone by itself afterwards — so a client that dies mid-turn leaves no
45
+ * indicator hanging. A ROOM'S RECIPIENTS ONLY (a person or an agent); a customer is
46
+ * refused. Send it once at the start of a turn, not per keystroke.
47
+ * @throws Error with message `CanisterError` when the canister returns a business error (`NotAuthorized` for a customer or a non-participant, `NotFound` for the chat). Examine "cause" for {errorKey, errorMessage, logs}.
48
+ * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
49
+ * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
50
+ */
51
+ async setTypingAsyncUnsafe(chatId) {
52
+ return this.executeFunctionAsyncUnsafe(() => this.actor.setTyping({ chatId }));
53
+ }
54
+ /**
55
+ * A chat's messages with seq > sinceSeq, oldest first (max 200 per call), together
56
+ * with `presence`: who is typing and how far each other participant has read.
44
57
  * Participants only.
45
58
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound`). Examine "cause" for {errorKey, errorMessage, logs}.
46
59
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
@@ -7,7 +7,7 @@ export declare class RoomsActor extends ActorBase {
7
7
  constructor(canisterId: string, identity?: Identity);
8
8
  /**
9
9
  * Creates a room. Project admins and canister admins.
10
- * @param input - id (max 50 chars, unique in the project, no '/' or '|'), name (max 100), 1–10 recipients (no anonymous, no duplicates, display names present).
10
+ * @param input - id (max 50 chars, unique in the project, no '/' or '|'), name (max 100), 1–10 recipients (no anonymous, no duplicates, display names present), and optionally the allowed customers (max 50; empty = every account of the project may open a chat here).
11
11
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound` for the project, `AlreadyExists`, `InvalidData`). Examine "cause" for {errorKey, errorMessage, logs}.
12
12
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
13
13
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
@@ -29,7 +29,8 @@ export declare class RoomsActor extends ActorBase {
29
29
  */
30
30
  getRoomAsyncUnsafe(input: RoomRefInput): Promise<RoomView>;
31
31
  /**
32
- * A project's rooms in creation order. Project admins and canister admins.
32
+ * A project's rooms in creation order, one page at a time (max 100). Project admins
33
+ * and canister admins.
33
34
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound`). Examine "cause" for {errorKey, errorMessage, logs}.
34
35
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
35
36
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
@@ -1 +1 @@
1
- {"version":3,"file":"rooms-actor.d.ts","sourceRoot":"","sources":["../../src/actors/rooms-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGjH;iEACiE;AACjE,qBAAa,UAAW,SAAQ,SAAS;gBAEzB,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;OAMG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAY7E;;;;;OAKG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAY7E;;;;;;OAMG;IACU,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKvE;;;;;OAKG;IACU,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAIhF"}
1
+ {"version":3,"file":"rooms-actor.d.ts","sourceRoot":"","sources":["../../src/actors/rooms-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGjH;iEACiE;AACjE,qBAAa,UAAW,SAAQ,SAAS;gBAEzB,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAInD;;;;;;OAMG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAa7E;;;;;OAKG;IACU,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAa7E;;;;;;OAMG;IACU,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKvE;;;;;;OAMG;IACU,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAIhF"}
@@ -1,4 +1,5 @@
1
1
  import {} from "@icp-sdk/core/agent";
2
+ import { Principal } from "@icp-sdk/core/principal";
2
3
  import { ActorBase } from "../actor-base.js";
3
4
  import { mapRoomView, toCandidRecipient, toOpt, toOptBigInt } from "../mappers.js";
4
5
  /** 1:1 wrapper for the canister's RoomsController — a room is the template a chat is
@@ -9,7 +10,7 @@ export class RoomsActor extends ActorBase {
9
10
  }
10
11
  /**
11
12
  * Creates a room. Project admins and canister admins.
12
- * @param input - id (max 50 chars, unique in the project, no '/' or '|'), name (max 100), 1–10 recipients (no anonymous, no duplicates, display names present).
13
+ * @param input - id (max 50 chars, unique in the project, no '/' or '|'), name (max 100), 1–10 recipients (no anonymous, no duplicates, display names present), and optionally the allowed customers (max 50; empty = every account of the project may open a chat here).
13
14
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound` for the project, `AlreadyExists`, `InvalidData`). Examine "cause" for {errorKey, errorMessage, logs}.
14
15
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
15
16
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
@@ -20,6 +21,7 @@ export class RoomsActor extends ActorBase {
20
21
  id: input.id,
21
22
  name: input.name,
22
23
  recipients: input.recipients.map(toCandidRecipient),
24
+ allowedCustomers: (input.allowedCustomers ?? []).map((principal) => Principal.fromText(principal)),
23
25
  }));
24
26
  return mapRoomView(room);
25
27
  }
@@ -35,6 +37,7 @@ export class RoomsActor extends ActorBase {
35
37
  roomId: input.roomId,
36
38
  name: toOpt(input.name),
37
39
  recipients: toOpt(input.recipients?.map(toCandidRecipient)),
40
+ allowedCustomers: toOpt(input.allowedCustomers?.map((principal) => Principal.fromText(principal))),
38
41
  }));
39
42
  return mapRoomView(room);
40
43
  }
@@ -50,13 +53,14 @@ export class RoomsActor extends ActorBase {
50
53
  return mapRoomView(room);
51
54
  }
52
55
  /**
53
- * A project's rooms in creation order. Project admins and canister admins.
56
+ * A project's rooms in creation order, one page at a time (max 100). Project admins
57
+ * and canister admins.
54
58
  * @throws Error with message `CanisterError` when the canister returns a business error (not authorized, `NotFound`). Examine "cause" for {errorKey, errorMessage, logs}.
55
59
  * @throws Error with message `CriticalCanisterError` when there is no communication with the canister or the canister code traps during execution.
56
60
  * @throws Error with message `CallRefusedAtInspectionStage` when the canister's `inspect` rejects the call before execution.
57
61
  */
58
62
  async listRoomsAsyncUnsafe(input) {
59
- const rooms = await this.executeFunctionAsyncUnsafe(() => this.actor.listRooms({ projectId: input.projectId, limit: toOptBigInt(input.limit) }));
63
+ const rooms = await this.executeFunctionAsyncUnsafe(() => this.actor.listRooms({ projectId: input.projectId, offset: toOptBigInt(input.offset), limit: toOptBigInt(input.limit) }));
60
64
  return rooms.map(mapRoomView);
61
65
  }
62
66
  }
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { RoomsActor } from "./actors/rooms-actor.js";
5
5
  export { ChatsActor } from "./actors/chats-actor.js";
6
6
  export { MessagesActor } from "./actors/messages-actor.js";
7
7
  export { ChatPoller, type ChatPollerOptions } from "./chat-poller.js";
8
- export type { RoleView, RecipientRoleView, ProjectView, RecipientView, RoomView, ParticipantView, ChatView, ChatSummaryView, SystemEventView, MessageKindView, MessageView, MessagesPageView, PollResultView, QuotaLimitsView, CreateProjectInput, UpdateProjectInput, CreateRoomInput, UpdateRoomInput, RoomRefInput, ListRoomsInput, OpenChatInput, GetMyChatsInput, ListProjectChatsInput, PostInput, GetMessagesInput, PollNewMessagesInput, } from "./interfaces.js";
8
+ export type { RoleView, RecipientRoleView, ProjectView, RecipientView, RoomView, ParticipantView, ChatView, ChatSummaryView, SystemEventView, MessageKindView, MessageView, MessagesPageView, PresenceView, PollResultView, QuotaLimitsView, CreateProjectInput, UpdateProjectInput, CreateRoomInput, UpdateRoomInput, RoomRefInput, ListRoomsInput, OpenChatInput, GetMyChatsInput, ListProjectChatsInput, PostInput, GetMessagesInput, PollNewMessagesInput, } from "./interfaces.js";
9
9
  export { mapProjectView, mapRoomView, mapRecipientView, mapChatView, mapChatSummaryView, mapParticipantView, mapMessageView, mapMessagesPageView, mapPollResultView, mapSystemEventView, mapQuotaLimitsView, mapRoleView, mapRecipientRoleView, toCandidRecipient, toCandidRecipientRole, } from "./mappers.js";
10
10
  export type { Chat, ChatId, ChatSummary, Message, MessageKind, MessagesPage, Participant, PollResult, Project, ProjectId, QuotaLimits, Recipient, RecipientRole, Role, Room, RoomId, SystemEvent, Error as CanisterErrorShape, ErrorDetails, } from "../declarations/chat-motoko-backend/chat-motoko-backend.did.js";
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,YAAY,EACR,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,eAAe,EACf,eAAe,EACf,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,gBAAgB,EAChB,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,IAAI,kBAAkB,EAC3B,YAAY,GACf,MAAM,gEAAgE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,YAAY,EACR,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,eAAe,EACf,eAAe,EACf,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,cAAc,EACd,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,gBAAgB,EAChB,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACR,IAAI,EACJ,MAAM,EACN,WAAW,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,WAAW,EACX,KAAK,IAAI,kBAAkB,EAC3B,YAAY,GACf,MAAM,gEAAgE,CAAC"}
@@ -29,6 +29,8 @@ export interface RoomView {
29
29
  createdBy: string;
30
30
  createdAt: bigint;
31
31
  recipients: RecipientView[];
32
+ /** Who may open a chat here. Empty = everybody with an account in the project. */
33
+ allowedCustomers: string[];
32
34
  }
33
35
  export interface ParticipantView {
34
36
  principal: string;
@@ -44,8 +46,6 @@ export interface ChatView {
44
46
  projectId: string;
45
47
  roomId: string;
46
48
  customer: string;
47
- /** The desk of the room the customer walked up to — the consumer's id of what the chat is about. */
48
- desk?: string;
49
49
  createdAt: bigint;
50
50
  participants: ParticipantView[];
51
51
  lastSeq: number;
@@ -57,7 +57,6 @@ export interface ChatSummaryView {
57
57
  projectId: string;
58
58
  roomId: string;
59
59
  customer: string;
60
- desk?: string;
61
60
  createdAt: bigint;
62
61
  participantCount: number;
63
62
  messageCount: number;
@@ -73,8 +72,6 @@ export interface MessageView {
73
72
  roomId: string;
74
73
  /** Whom the chat belongs to — so a recipient's poll routes without a lookup. */
75
74
  customer: string;
76
- /** The chat's desk, when it has one (Sultana: the salon). */
77
- desk?: string;
78
75
  /** Dense per-chat sequence starting at 1. */
79
76
  seq: number;
80
77
  /** Canister-wide sequence — the poll cursor. */
@@ -89,6 +86,21 @@ export interface MessageView {
89
86
  export interface MessagesPageView {
90
87
  messages: MessageView[];
91
88
  lastSeq: number;
89
+ /** What every OTHER participant is doing right now — the caller's own row is left out. */
90
+ presence: PresenceView[];
91
+ }
92
+ /** Who is typing and how far they have read, as of the moment the page was read. */
93
+ export interface PresenceView {
94
+ principal: string;
95
+ /**
96
+ * `true` while this participant's typing signal is still valid. Derived from the
97
+ * canister's instant and the clock at read time, so it needs no timer of its own.
98
+ */
99
+ typing: boolean;
100
+ /** Nanoseconds; 0 when the participant is not typing. */
101
+ typingUntil: bigint;
102
+ /** Highest per-chat seq this participant has marked read (0 = nothing). */
103
+ lastReadSeq: number;
92
104
  }
93
105
  export interface PollResultView {
94
106
  messages: MessageView[];
@@ -118,6 +130,8 @@ export interface CreateRoomInput {
118
130
  id: string;
119
131
  name: string;
120
132
  recipients: RecipientView[];
133
+ /** Who may open a chat here; omitted or empty = everybody with an account (max 50). */
134
+ allowedCustomers?: string[];
121
135
  }
122
136
  export interface UpdateRoomInput {
123
137
  projectId: string;
@@ -125,6 +139,8 @@ export interface UpdateRoomInput {
125
139
  name?: string;
126
140
  /** Replaces the whole list; chats already opened keep their recipients. */
127
141
  recipients?: RecipientView[];
142
+ /** Replaces the whole list; chats already opened stay open. Empty = open to everybody. */
143
+ allowedCustomers?: string[];
128
144
  }
129
145
  export interface RoomRefInput {
130
146
  projectId: string;
@@ -132,26 +148,25 @@ export interface RoomRefInput {
132
148
  }
133
149
  export interface ListRoomsInput {
134
150
  projectId: string;
151
+ /** Skip this many rooms of the project's creation order; defaults to 0. */
152
+ offset?: number;
153
+ /** Max 100 per page. */
135
154
  limit?: number;
136
155
  }
137
156
  export interface OpenChatInput {
138
157
  projectId: string;
139
158
  roomId: string;
140
- /** Which desk of the room (max 200 chars) — another desk is another chat. */
141
- desk?: string;
142
159
  /** How the recipients see the caller; omitted = the principal. */
143
160
  customerName?: string;
144
161
  }
145
162
  export interface GetMyChatsInput {
146
163
  projectId: string;
147
164
  roomId?: string;
148
- desk?: string;
149
165
  limit?: number;
150
166
  }
151
167
  export interface ListProjectChatsInput {
152
168
  projectId: string;
153
169
  roomId?: string;
154
- desk?: string;
155
170
  limit?: number;
156
171
  }
157
172
  export interface PostInput {
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACR,IAAI,EACJ,WAAW,EACX,OAAO,EACP,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,SAAS,EACT,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,WAAW,EACd,MAAM,gEAAgE,CAAC;AACxE,OAAO,KAAK,EACR,eAAe,EACf,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EAClB,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAEvD;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAE3E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAK5E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAMjE;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CAMpE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAQ5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAShD;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,eAAe,CAU5E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAYhD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAYxE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,CAEvE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAkB5D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAExE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CAMpE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAExE"}
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACR,IAAI,EACJ,WAAW,EACX,OAAO,EACP,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,SAAS,EACT,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,WAAW,EACd,MAAM,gEAAgE,CAAC;AACxE,OAAO,KAAK,EACR,eAAe,EACf,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,eAAe,EAClB,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAEvD;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAE3E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAK5E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAMjE;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CAMpE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAQ5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAUhD;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,eAAe,CAU5E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAWhD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAWxE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,CAEvE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAiB5D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAcxE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CAMpE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,CAExE"}
package/dist/mappers.js CHANGED
@@ -51,6 +51,7 @@ export function mapRoomView(room) {
51
51
  createdBy: room.createdBy.toText(),
52
52
  createdAt: room.createdAt,
53
53
  recipients: room.recipients.map(mapRecipientView),
54
+ allowedCustomers: room.allowedCustomers.map((principal) => principal.toText()),
54
55
  };
55
56
  }
56
57
  export function mapParticipantView(participant) {
@@ -70,7 +71,6 @@ export function mapChatView(chat) {
70
71
  projectId: chat.projectId,
71
72
  roomId: chat.roomId,
72
73
  customer: chat.customer.toText(),
73
- desk: fromOpt(chat.desk),
74
74
  createdAt: chat.createdAt,
75
75
  participants: chat.participants.map(mapParticipantView),
76
76
  lastSeq: Number(chat.lastSeq),
@@ -83,7 +83,6 @@ export function mapChatSummaryView(summary) {
83
83
  projectId: summary.projectId,
84
84
  roomId: summary.roomId,
85
85
  customer: summary.customer.toText(),
86
- desk: fromOpt(summary.desk),
87
86
  createdAt: summary.createdAt,
88
87
  participantCount: Number(summary.participantCount),
89
88
  messageCount: Number(summary.messageCount),
@@ -99,7 +98,6 @@ export function mapMessageView(message) {
99
98
  projectId: message.projectId,
100
99
  roomId: message.roomId,
101
100
  customer: message.customer.toText(),
102
- desk: fromOpt(message.desk),
103
101
  seq: Number(message.seq),
104
102
  globalSeq: Number(message.globalSeq),
105
103
  author: message.author.toText(),
@@ -112,7 +110,19 @@ export function mapMessageView(message) {
112
110
  return { ...base, kind: "toolTrace" in message.kind ? "toolTrace" : "text" };
113
111
  }
114
112
  export function mapMessagesPageView(page) {
115
- return { messages: page.messages.map(mapMessageView), lastSeq: Number(page.lastSeq) };
113
+ // The canister answers with the instant a signal expires; whether it still holds is a
114
+ // question about now, and the caller should not have to ask it themselves.
115
+ const nowNs = BigInt(Date.now()) * 1000000n;
116
+ return {
117
+ messages: page.messages.map(mapMessageView),
118
+ lastSeq: Number(page.lastSeq),
119
+ presence: page.presence.map((entry) => ({
120
+ principal: entry.principal.toText(),
121
+ typing: entry.typingUntil > nowNs,
122
+ typingUntil: entry.typingUntil,
123
+ lastReadSeq: Number(entry.lastReadSeq),
124
+ })),
125
+ };
116
126
  }
117
127
  export function mapPollResultView(result) {
118
128
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsm-mit/chat-motoko-package",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Wrapper TypeScript package for the chat-motoko canister: projects, multi-party chats, messages and a poller for agent hosts.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -58,6 +58,6 @@
58
58
  "chatMotoko": {
59
59
  "repo": "chat-motoko",
60
60
  "repoUrl": "https://github.com/JSM-Chat-Platform/chat-motoko",
61
- "commit": "e9c8a68daef59e8d4c9ceb1dd5089a7c008fa103"
61
+ "commit": "a5184ccd2c42aefd0b21dc0419cd24530e10de5b"
62
62
  }
63
63
  }