@ermis-network/ermis-chat-sdk 1.0.5 → 1.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ermis-network/ermis-chat-sdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Ermis Chat SDK",
5
5
  "author": "Ermis",
6
6
  "homepage": "https://ermis.network/",
package/src/channel.ts CHANGED
@@ -132,13 +132,16 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
132
132
 
133
133
  // 3. Call API — don't update status on success (WS message.new will handle it)
134
134
  try {
135
- return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(
136
- this._channelURL() + '/message',
137
- { message: { ...message } },
138
- );
135
+ return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(this._channelURL() + '/message', {
136
+ message: { ...message },
137
+ });
139
138
  } catch (error: any) {
140
139
  // 4. On error: check if it's an offline/network error
141
- const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;
140
+ const isOfflineError =
141
+ !error.response ||
142
+ error.code === 'ERR_NETWORK' ||
143
+ error.isWSFailure ||
144
+ !this.getClient().wsConnection?.isHealthy;
142
145
  const statusToSet = isOfflineError ? 'failed_offline' : 'error';
143
146
  this.state.updateMessageStatus(messageId, statusToSet);
144
147
  throw error;
@@ -166,12 +169,15 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
166
169
  }
167
170
 
168
171
  try {
169
- return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(
170
- this._channelURL() + '/message',
171
- { message: messagePayload },
172
- );
172
+ return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(this._channelURL() + '/message', {
173
+ message: messagePayload,
174
+ });
173
175
  } catch (error: any) {
174
- const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;
176
+ const isOfflineError =
177
+ !error.response ||
178
+ error.code === 'ERR_NETWORK' ||
179
+ error.isWSFailure ||
180
+ !this.getClient().wsConnection?.isHealthy;
175
181
  this.state.updateMessageStatus(messageId, isOfflineError ? 'failed_offline' : 'error');
176
182
  throw error;
177
183
  }
@@ -263,9 +269,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
263
269
 
264
270
  // 2. Upload all files in parallel
265
271
  const uploadResults = await Promise.allSettled(
266
- processedFiles.map((file) =>
267
- this.sendFile(file, file.name, file.type),
268
- ),
272
+ processedFiles.map((file) => this.sendFile(file, file.name, file.type)),
269
273
  );
270
274
 
271
275
  // 3. For successful video uploads, generate and upload thumbnails
@@ -280,11 +284,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
280
284
  try {
281
285
  const thumbBlob = await this.getThumbBlobVideo(files[i]);
282
286
  if (thumbBlob) {
283
- const thumbFile = new File(
284
- [thumbBlob],
285
- `thumb_${processedFiles[i].name}.jpg`,
286
- { type: 'image/jpeg' },
287
- );
287
+ const thumbFile = new File([thumbBlob], `thumb_${processedFiles[i].name}.jpg`, { type: 'image/jpeg' });
288
288
  const thumbResp = await this.sendFile(thumbFile, thumbFile.name, 'image/jpeg');
289
289
  thumbUrls.set(i, thumbResp.file);
290
290
  }
@@ -306,9 +306,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
306
306
  const uploadedUrl = result.value.file;
307
307
  const thumbUrl = thumbUrls.get(i);
308
308
  const voiceMeta = options?.voiceMetadata?.get(i);
309
- attachments.push(
310
- buildAttachmentPayload(processedFiles[i], uploadedUrl, thumbUrl, voiceMeta),
311
- );
309
+ attachments.push(buildAttachmentPayload(processedFiles[i], uploadedUrl, thumbUrl, voiceMeta));
312
310
  } else {
313
311
  failedFiles.push({
314
312
  file: files[i],
@@ -756,7 +754,7 @@ export class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGener
756
754
  if (this.id) {
757
755
  queryURL += `/${this.id}`;
758
756
  } else {
759
- if (this.type === 'team') {
757
+ if (this.type === 'team' || this.type === 'meeting') {
760
758
  const uuid = randomId();
761
759
  this.id = `${project_id}:${uuid}`;
762
760
  queryURL += `/${this.id}`;
package/src/client.ts CHANGED
@@ -1358,6 +1358,56 @@ export class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGen
1358
1358
  return channel;
1359
1359
  };
1360
1360
 
1361
+ /**
1362
+ * Creates an interactive `meeting` Channel locally, and immediately creates it on the server.
1363
+ * Consumers can customize the `name` field. `members` and `public` fields are constrained.
1364
+ *
1365
+ * @param name - The custom name for the meeting channel.
1366
+ * @returns A promise that resolves to the created `Channel` object.
1367
+ */
1368
+ async createMeetingChannel(name?: string): Promise<Channel<ErmisChatGenerics>> {
1369
+ if (!this.userID) {
1370
+ throw Error('Call connectUser before creating a channel');
1371
+ }
1372
+
1373
+ const payload = {
1374
+ name: name || `Meeting Public - ${new Date().toISOString()}`,
1375
+ members: [this.userID],
1376
+ public: true,
1377
+ } as unknown as ChannelData<ErmisChatGenerics>;
1378
+
1379
+ const meetingChannel = this.channel('meeting', payload);
1380
+ await meetingChannel.create();
1381
+
1382
+ return meetingChannel;
1383
+ }
1384
+
1385
+ /**
1386
+ * Joins a `meeting` channel.
1387
+ * It queries/watches the channel to see if caller is already a member.
1388
+ * If not, it accepts the invite to join the channel, then watches it again to reflect changes.
1389
+ *
1390
+ * @param channelId - The ID of the meeting channel to join.
1391
+ * @returns A promise that resolves to the joined `Channel` object.
1392
+ */
1393
+ async joinMeetingChannel(channelId: string): Promise<Channel<ErmisChatGenerics>> {
1394
+ if (!this.userID) {
1395
+ throw Error('Call connectUser before joining a channel');
1396
+ }
1397
+
1398
+ const meetingChannel = this.channel('meeting', channelId);
1399
+ await meetingChannel.watch();
1400
+
1401
+ const isMember = meetingChannel.state.members && meetingChannel.state.members[this.userID];
1402
+
1403
+ if (!isMember) {
1404
+ await meetingChannel.acceptInvite('join');
1405
+ await meetingChannel.watch();
1406
+ }
1407
+
1408
+ return meetingChannel;
1409
+ }
1410
+
1361
1411
  _normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {
1362
1412
  let pinExpires: null | string = null;
1363
1413
  if (typeof timeoutOrExpirationDate === 'number') {