@jsm-mit/chat-motoko-package 0.1.0 → 0.3.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 +21 -9
- package/declarations/chat-motoko-backend/chat-motoko-backend.did +141 -109
- package/declarations/chat-motoko-backend/chat-motoko-backend.did.d.ts +115 -92
- package/declarations/chat-motoko-backend/chat-motoko-backend.did.js +131 -109
- package/dist/actors/admin-actor.d.ts +15 -0
- package/dist/actors/admin-actor.d.ts.map +1 -1
- package/dist/actors/admin-actor.js +21 -0
- package/dist/actors/chats-actor.d.ts +24 -50
- package/dist/actors/chats-actor.d.ts.map +1 -1
- package/dist/actors/chats-actor.js +40 -82
- package/dist/actors/messages-actor.d.ts +7 -6
- package/dist/actors/messages-actor.d.ts.map +1 -1
- package/dist/actors/messages-actor.js +7 -6
- package/dist/actors/projects-actor.d.ts +6 -5
- package/dist/actors/projects-actor.d.ts.map +1 -1
- package/dist/actors/projects-actor.js +8 -11
- package/dist/actors/rooms-actor.d.ts +39 -0
- package/dist/actors/rooms-actor.d.ts.map +1 -0
- package/dist/actors/rooms-actor.js +62 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/interfaces.d.ts +81 -65
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/mappers.d.ts +12 -7
- package/dist/mappers.d.ts.map +1 -1
- package/dist/mappers.js +61 -44
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -5,23 +5,32 @@ multi-project, multi-party chat on the Internet Computer — plus the integratio
|
|
|
5
5
|
that prove it.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
import { ChatsActor, MessagesActor, ChatPoller } from "@jsm-mit/chat-motoko-package";
|
|
8
|
+
import { RoomsActor, ChatsActor, MessagesActor, ChatPoller } from "@jsm-mit/chat-motoko-package";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// A canister admin creates the project with its accounts canister — the one asked
|
|
11
|
+
// `isUser(principal)` before a non-admin opens a chat (Sultana: sultana-core-motoko).
|
|
12
|
+
// A project admin defines a room: who receives the customer's messages.
|
|
13
|
+
await new RoomsActor(canisterId, adminIdentity).createRoomAsyncUnsafe({
|
|
14
|
+
projectId: "sultana-stage", id: "assistant", name: "Asystent",
|
|
15
|
+
recipients: [{ principal: villagePrincipal, role: "agent", displayName: "Asystentka Ola" }],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// A customer opens the room — the same call returns the same chat next time.
|
|
19
|
+
const chat = await new ChatsActor(canisterId, identity).openChatAsyncUnsafe({ projectId: "sultana-stage", roomId: "assistant", customerName: "Michał" });
|
|
12
20
|
|
|
13
21
|
const messages = new MessagesActor(canisterId, identity);
|
|
14
22
|
await messages.postAsyncUnsafe({ chatId: chat.id, text: "dodaj usługę strzyżenie" });
|
|
15
23
|
const page = await messages.getMessagesAsyncUnsafe({ chatId: chat.id, sinceSeq: 0 });
|
|
16
24
|
|
|
17
|
-
// An agent host: every new message in every chat this identity
|
|
25
|
+
// An agent host: every new message in every chat this identity is a recipient of, with
|
|
26
|
+
// the room and the customer on each message — route by (projectId, roomId).
|
|
18
27
|
const poller = new ChatPoller(messages, 1000, { onError: console.error });
|
|
19
|
-
poller.messages$.subscribe((m) => console.log(m.
|
|
28
|
+
poller.messages$.subscribe((m) => console.log(m.roomId, m.customer, m.kind, m.text));
|
|
20
29
|
poller.run();
|
|
21
30
|
```
|
|
22
31
|
|
|
23
|
-
One class per canister controller (`AdminActor`, `ProjectsActor`, `
|
|
24
|
-
`MessagesActor`), every method `…AsyncUnsafe` (throws one of `CanisterError`,
|
|
32
|
+
One class per canister controller (`AdminActor`, `ProjectsActor`, `RoomsActor`,
|
|
33
|
+
`ChatsActor`, `MessagesActor`), every method `…AsyncUnsafe` (throws one of `CanisterError`,
|
|
25
34
|
`CriticalCanisterError`, `CallRefusedAtInspectionStage`) or `…AsyncSafe` (never
|
|
26
35
|
throws). Views translate `Principal` → text, `opt` → optional, variants → string
|
|
27
36
|
unions; sequence numbers are plain `number`s, timestamps `bigint` nanoseconds.
|
|
@@ -29,8 +38,11 @@ unions; sequence numbers are plain `number`s, timestamps `bigint` nanoseconds.
|
|
|
29
38
|
`src/` is browser-safe — the same package serves the agent host and a web panel.
|
|
30
39
|
|
|
31
40
|
Scripts: `build`, `typecheck`, `sync-declarations`, `test-suite`,
|
|
32
|
-
`test-access-restrictions`, `
|
|
33
|
-
|
|
41
|
+
`test-access-restrictions`, `user1` / `user2` (an interactive admin/chat console, one
|
|
42
|
+
person per terminal: the key comes from `USER1_PEM` / `USER2_PEM` in `.env`; another
|
|
43
|
+
canister: `npm run user2 -- <canister-id>`), `redeploy` (build `../chat-motoko` and install it
|
|
44
|
+
on `CANISTER_ID` without tests; `npm run redeploy -- reinstall` or `-- upgrade`; after a
|
|
45
|
+
reinstall claim the admin role yourself in the sandbox). See `CLAUDE.md` for who runs what.
|
|
34
46
|
|
|
35
47
|
## Publishing
|
|
36
48
|
|
|
@@ -1,110 +1,130 @@
|
|
|
1
|
+
type UpdateRoomArgs =
|
|
2
|
+
record {
|
|
3
|
+
name: opt text;
|
|
4
|
+
projectId: ProjectId;
|
|
5
|
+
recipients: opt vec Recipient;
|
|
6
|
+
roomId: RoomId;
|
|
7
|
+
};
|
|
1
8
|
type UpdateProjectArgs =
|
|
2
9
|
record {
|
|
10
|
+
accountsCanister: opt principal;
|
|
3
11
|
admins: opt vec principal;
|
|
4
|
-
agents: opt vec principal;
|
|
5
|
-
agentsMayInvite: opt bool;
|
|
6
|
-
defaultPolicy: opt Policy;
|
|
7
12
|
projectId: ProjectId;
|
|
8
13
|
};
|
|
9
|
-
type SystemEvent =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
by: principal;
|
|
15
|
-
"principal": principal;
|
|
16
|
-
role: Role;
|
|
17
|
-
};
|
|
18
|
-
memberJoined: record {
|
|
19
|
-
"principal": principal;
|
|
20
|
-
role: Role;
|
|
21
|
-
};
|
|
22
|
-
memberLeft: record {"principal": principal;};
|
|
23
|
-
memberRemoved: record {
|
|
24
|
-
by: principal;
|
|
25
|
-
"principal": principal;
|
|
26
|
-
};
|
|
27
|
-
policyChanged: Policy;
|
|
28
|
-
};
|
|
29
|
-
type SetPolicyArgs =
|
|
14
|
+
type SystemEvent = variant {chatCreated;};
|
|
15
|
+
type SetQuotaLimitsArgs = record {limits: QuotaLimits;};
|
|
16
|
+
type SetLoggingEnabledArgs = record {enabled: bool;};
|
|
17
|
+
type RoomId = text;
|
|
18
|
+
type Room =
|
|
30
19
|
record {
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
createdAt: int;
|
|
21
|
+
createdBy: principal;
|
|
22
|
+
id: RoomId;
|
|
23
|
+
name: text;
|
|
24
|
+
projectId: ProjectId;
|
|
25
|
+
recipients: vec Recipient;
|
|
33
26
|
};
|
|
34
|
-
type SetLoggingEnabledArgs = record {enabled: bool;};
|
|
35
27
|
type Role =
|
|
36
28
|
variant {
|
|
37
|
-
admin;
|
|
38
29
|
agent;
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
customer;
|
|
31
|
+
worker;
|
|
41
32
|
};
|
|
42
33
|
type Result_9 =
|
|
43
34
|
variant {
|
|
44
35
|
err: Error;
|
|
45
|
-
ok: vec
|
|
36
|
+
ok: vec Project;
|
|
46
37
|
};
|
|
47
38
|
type Result_8 =
|
|
48
39
|
variant {
|
|
49
40
|
err: Error;
|
|
50
|
-
ok:
|
|
41
|
+
ok: vec Room;
|
|
51
42
|
};
|
|
52
43
|
type Result_7 =
|
|
53
44
|
variant {
|
|
54
45
|
err: Error;
|
|
55
|
-
ok:
|
|
46
|
+
ok: Chat;
|
|
56
47
|
};
|
|
57
48
|
type Result_6 =
|
|
58
49
|
variant {
|
|
59
50
|
err: Error;
|
|
60
|
-
ok:
|
|
51
|
+
ok: PollResult;
|
|
61
52
|
};
|
|
62
53
|
type Result_5 =
|
|
63
54
|
variant {
|
|
64
55
|
err: Error;
|
|
65
|
-
ok:
|
|
56
|
+
ok: Message;
|
|
66
57
|
};
|
|
67
58
|
type Result_4 =
|
|
68
59
|
variant {
|
|
69
60
|
err: Error;
|
|
70
|
-
ok:
|
|
61
|
+
ok: principal;
|
|
71
62
|
};
|
|
72
63
|
type Result_3 =
|
|
73
64
|
variant {
|
|
74
65
|
err: Error;
|
|
75
|
-
ok:
|
|
66
|
+
ok: bool;
|
|
76
67
|
};
|
|
77
68
|
type Result_2 =
|
|
78
69
|
variant {
|
|
79
70
|
err: Error;
|
|
80
|
-
ok:
|
|
71
|
+
ok: QuotaLimits;
|
|
72
|
+
};
|
|
73
|
+
type Result_13 =
|
|
74
|
+
variant {
|
|
75
|
+
err: Error;
|
|
76
|
+
ok: vec principal;
|
|
77
|
+
};
|
|
78
|
+
type Result_12 =
|
|
79
|
+
variant {
|
|
80
|
+
err: Error;
|
|
81
|
+
ok: MessagesPage;
|
|
82
|
+
};
|
|
83
|
+
type Result_11 =
|
|
84
|
+
variant {
|
|
85
|
+
err: Error;
|
|
86
|
+
ok: vec Chat;
|
|
87
|
+
};
|
|
88
|
+
type Result_10 =
|
|
89
|
+
variant {
|
|
90
|
+
err: Error;
|
|
91
|
+
ok: vec ChatSummary;
|
|
81
92
|
};
|
|
82
93
|
type Result_1 =
|
|
83
94
|
variant {
|
|
84
95
|
err: Error;
|
|
85
|
-
ok:
|
|
96
|
+
ok: Project;
|
|
86
97
|
};
|
|
87
98
|
type Result =
|
|
88
99
|
variant {
|
|
89
100
|
err: Error;
|
|
90
|
-
ok:
|
|
101
|
+
ok: Room;
|
|
102
|
+
};
|
|
103
|
+
type RemoveAdminArgs = record {"principal": principal;};
|
|
104
|
+
type RecipientRole =
|
|
105
|
+
variant {
|
|
106
|
+
agent;
|
|
107
|
+
worker;
|
|
91
108
|
};
|
|
92
|
-
type
|
|
109
|
+
type Recipient =
|
|
93
110
|
record {
|
|
94
|
-
|
|
111
|
+
displayName: text;
|
|
95
112
|
"principal": principal;
|
|
113
|
+
role: RecipientRole;
|
|
114
|
+
};
|
|
115
|
+
type QuotaLimits =
|
|
116
|
+
record {
|
|
117
|
+
chats: nat;
|
|
118
|
+
posts: nat;
|
|
96
119
|
};
|
|
97
|
-
type RemoveAdminArgs = record {"principal": principal;};
|
|
98
120
|
type PurgeChatArgs = record {chatId: ChatId;};
|
|
99
121
|
type ProjectId = text;
|
|
100
122
|
type Project =
|
|
101
123
|
record {
|
|
124
|
+
accountsCanister: principal;
|
|
102
125
|
admins: vec principal;
|
|
103
|
-
agents: vec principal;
|
|
104
|
-
agentsMayInvite: bool;
|
|
105
126
|
createdAt: int;
|
|
106
127
|
createdBy: principal;
|
|
107
|
-
defaultPolicy: Policy;
|
|
108
128
|
id: ProjectId;
|
|
109
129
|
};
|
|
110
130
|
type PostKind =
|
|
@@ -129,7 +149,21 @@ type PollNewMessagesArgs =
|
|
|
129
149
|
limit: opt nat;
|
|
130
150
|
sinceGlobalSeq: nat;
|
|
131
151
|
};
|
|
132
|
-
type
|
|
152
|
+
type Participant =
|
|
153
|
+
record {
|
|
154
|
+
displayName: text;
|
|
155
|
+
firstPostSeq: opt nat;
|
|
156
|
+
joinedAt: int;
|
|
157
|
+
lastReadSeq: nat;
|
|
158
|
+
"principal": principal;
|
|
159
|
+
role: Role;
|
|
160
|
+
};
|
|
161
|
+
type OpenChatArgs =
|
|
162
|
+
record {
|
|
163
|
+
customerName: opt text;
|
|
164
|
+
projectId: ProjectId;
|
|
165
|
+
roomId: RoomId;
|
|
166
|
+
};
|
|
133
167
|
type MessagesPage =
|
|
134
168
|
record {
|
|
135
169
|
lastSeq: nat;
|
|
@@ -146,44 +180,42 @@ type Message =
|
|
|
146
180
|
author: principal;
|
|
147
181
|
chatId: ChatId;
|
|
148
182
|
createdAt: int;
|
|
183
|
+
customer: principal;
|
|
149
184
|
globalSeq: nat;
|
|
150
185
|
kind: MessageKind;
|
|
151
186
|
projectId: ProjectId;
|
|
187
|
+
roomId: RoomId;
|
|
152
188
|
seq: nat;
|
|
153
189
|
"text": text;
|
|
154
190
|
};
|
|
155
|
-
type MemberInput =
|
|
156
|
-
record {
|
|
157
|
-
"principal": principal;
|
|
158
|
-
role: Role;
|
|
159
|
-
};
|
|
160
|
-
type Member =
|
|
161
|
-
record {
|
|
162
|
-
joinedAt: int;
|
|
163
|
-
lastReadSeq: nat;
|
|
164
|
-
"principal": principal;
|
|
165
|
-
role: Role;
|
|
166
|
-
};
|
|
167
191
|
type MarkReadArgs =
|
|
168
192
|
record {
|
|
169
193
|
chatId: ChatId;
|
|
170
194
|
seq: nat;
|
|
171
195
|
};
|
|
196
|
+
type ListRoomsArgs =
|
|
197
|
+
record {
|
|
198
|
+
limit: opt nat;
|
|
199
|
+
projectId: ProjectId;
|
|
200
|
+
};
|
|
172
201
|
type ListProjectsArgs = record {limit: opt nat;};
|
|
173
|
-
type
|
|
174
|
-
type InviteMemberArgs =
|
|
202
|
+
type ListProjectChatsArgs =
|
|
175
203
|
record {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
204
|
+
limit: opt nat;
|
|
205
|
+
projectId: ProjectId;
|
|
206
|
+
roomId: opt RoomId;
|
|
207
|
+
};
|
|
208
|
+
type GetRoomArgs =
|
|
209
|
+
record {
|
|
210
|
+
projectId: ProjectId;
|
|
211
|
+
roomId: RoomId;
|
|
179
212
|
};
|
|
180
213
|
type GetProjectArgs = record {projectId: ProjectId;};
|
|
181
214
|
type GetMyChatsArgs =
|
|
182
215
|
record {
|
|
183
|
-
includeClosed: bool;
|
|
184
216
|
limit: opt nat;
|
|
185
217
|
projectId: ProjectId;
|
|
186
|
-
|
|
218
|
+
roomId: opt RoomId;
|
|
187
219
|
};
|
|
188
220
|
type GetMessagesArgs =
|
|
189
221
|
record {
|
|
@@ -207,69 +239,69 @@ type Error =
|
|
|
207
239
|
details: ErrorDetails;
|
|
208
240
|
logsJson: text;
|
|
209
241
|
};
|
|
242
|
+
type CreateRoomArgs =
|
|
243
|
+
record {
|
|
244
|
+
id: RoomId;
|
|
245
|
+
name: text;
|
|
246
|
+
projectId: ProjectId;
|
|
247
|
+
recipients: vec Recipient;
|
|
248
|
+
};
|
|
210
249
|
type CreateProjectArgs =
|
|
211
250
|
record {
|
|
251
|
+
accountsCanister: principal;
|
|
212
252
|
admins: vec principal;
|
|
213
|
-
agents: vec principal;
|
|
214
|
-
agentsMayInvite: bool;
|
|
215
|
-
defaultPolicy: Policy;
|
|
216
253
|
id: ProjectId;
|
|
217
254
|
};
|
|
218
|
-
type
|
|
255
|
+
type ChatSummary =
|
|
219
256
|
record {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
257
|
+
createdAt: int;
|
|
258
|
+
customer: principal;
|
|
259
|
+
id: ChatId;
|
|
260
|
+
lastMessageAt: int;
|
|
261
|
+
messageCount: nat;
|
|
262
|
+
participantCount: nat;
|
|
223
263
|
projectId: ProjectId;
|
|
224
|
-
|
|
225
|
-
title: opt text;
|
|
226
|
-
};
|
|
227
|
-
type CloseChatArgs = record {chatId: ChatId;};
|
|
228
|
-
type ChatStatus =
|
|
229
|
-
variant {
|
|
230
|
-
closed;
|
|
231
|
-
open;
|
|
264
|
+
roomId: RoomId;
|
|
232
265
|
};
|
|
233
266
|
type ChatId = text;
|
|
234
267
|
type Chat =
|
|
235
268
|
record {
|
|
236
269
|
createdAt: int;
|
|
237
|
-
|
|
270
|
+
customer: principal;
|
|
238
271
|
id: ChatId;
|
|
239
272
|
lastMessageAt: int;
|
|
240
273
|
lastSeq: nat;
|
|
241
|
-
|
|
242
|
-
policy: Policy;
|
|
274
|
+
participants: vec Participant;
|
|
243
275
|
projectId: ProjectId;
|
|
244
|
-
|
|
245
|
-
subject: opt text;
|
|
246
|
-
title: opt text;
|
|
276
|
+
roomId: RoomId;
|
|
247
277
|
};
|
|
248
278
|
type AddAdminArgs = record {"principal": principal;};
|
|
249
279
|
service : {
|
|
250
|
-
addAdmin: (args: AddAdminArgs) -> (
|
|
280
|
+
addAdmin: (args: AddAdminArgs) -> (Result_3);
|
|
251
281
|
clearLogs: () -> ();
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
getChat: (args: GetChatArgs) -> (Result_1) query;
|
|
282
|
+
createProject: (args: CreateProjectArgs) -> (Result_1);
|
|
283
|
+
createRoom: (args: CreateRoomArgs) -> (Result);
|
|
284
|
+
getAdmins: () -> (Result_13) query;
|
|
285
|
+
getChat: (args: GetChatArgs) -> (Result_7) query;
|
|
257
286
|
getLogs: () -> (text) query;
|
|
258
|
-
getMessages: (args: GetMessagesArgs) -> (
|
|
259
|
-
getMyChats: (args: GetMyChatsArgs) -> (
|
|
260
|
-
getProject: (args: GetProjectArgs) -> (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
287
|
+
getMessages: (args: GetMessagesArgs) -> (Result_12) query;
|
|
288
|
+
getMyChats: (args: GetMyChatsArgs) -> (Result_11) query;
|
|
289
|
+
getProject: (args: GetProjectArgs) -> (Result_1) query;
|
|
290
|
+
getQuotaLimits: () -> (Result_2) query;
|
|
291
|
+
getRoom: (args: GetRoomArgs) -> (Result) query;
|
|
292
|
+
listProjectChats: (args: ListProjectChatsArgs) -> (Result_10) query;
|
|
293
|
+
listProjects: (args: ListProjectsArgs) -> (Result_9) query;
|
|
294
|
+
listRooms: (args: ListRoomsArgs) -> (Result_8) query;
|
|
295
|
+
markRead: (args: MarkReadArgs) -> (Result_3);
|
|
296
|
+
openChat: (args: OpenChatArgs) -> (Result_7);
|
|
297
|
+
pollNewMessages: (args: PollNewMessagesArgs) -> (Result_6) query;
|
|
298
|
+
post: (args: PostArgs) -> (Result_5);
|
|
299
|
+
purgeChat: (args: PurgeChatArgs) -> (Result_3);
|
|
300
|
+
registerAsAdmin: () -> (Result_4);
|
|
301
|
+
removeAdmin: (args: RemoveAdminArgs) -> (Result_3);
|
|
302
|
+
setLoggingEnabled: (args: SetLoggingEnabledArgs) -> (Result_3);
|
|
303
|
+
setQuotaLimits: (args: SetQuotaLimitsArgs) -> (Result_2);
|
|
304
|
+
updateProject: (args: UpdateProjectArgs) -> (Result_1);
|
|
305
|
+
updateRoom: (args: UpdateRoomArgs) -> (Result);
|
|
274
306
|
whoAmI: () -> (principal) query;
|
|
275
307
|
}
|