stream-chat 9.52.0 → 9.53.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/dist/cjs/index.browser.js +108 -48
- package/dist/cjs/index.browser.js.map +2 -2
- package/dist/cjs/index.node.js +108 -48
- package/dist/cjs/index.node.js.map +2 -2
- package/dist/esm/index.mjs +108 -48
- package/dist/esm/index.mjs.map +2 -2
- package/dist/types/channel.d.ts +4 -2
- package/dist/types/channel_batch_updater.d.ts +9 -2
- package/dist/types/client.d.ts +17 -0
- package/dist/types/types.d.ts +33 -0
- package/dist/types/utils.d.ts +9 -5
- package/package.json +1 -1
- package/src/channel.ts +26 -18
- package/src/channel_batch_updater.ts +28 -2
- package/src/client.ts +94 -23
- package/src/messageDelivery/MessageDeliveryReporter.ts +5 -4
- package/src/types.ts +37 -0
- package/src/utils.ts +30 -7
package/dist/esm/index.mjs
CHANGED
|
@@ -159,6 +159,7 @@ var Campaign = class {
|
|
|
159
159
|
};
|
|
160
160
|
|
|
161
161
|
// src/channel_batch_updater.ts
|
|
162
|
+
var isChannelBatchDataUpdateOptions = (update) => "data" in update || "custom_set" in update || "custom_unset" in update;
|
|
162
163
|
var ChannelBatchUpdater = class {
|
|
163
164
|
constructor(client) {
|
|
164
165
|
this.client = client;
|
|
@@ -297,19 +298,14 @@ var ChannelBatchUpdater = class {
|
|
|
297
298
|
filter
|
|
298
299
|
});
|
|
299
300
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
* updateData - Update data on channels matching the filter
|
|
303
|
-
*
|
|
304
|
-
* @param {UpdateChannelsBatchFilters} filter Filter to select channels
|
|
305
|
-
* @param {BatchChannelDataUpdate} data Data to update
|
|
306
|
-
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
|
|
307
|
-
*/
|
|
308
|
-
async updateData(filter, data) {
|
|
301
|
+
async updateData(filter, update) {
|
|
302
|
+
const { data, custom_set, custom_unset } = isChannelBatchDataUpdateOptions(update) ? update : { data: update };
|
|
309
303
|
return await this.client.updateChannelsBatch({
|
|
310
304
|
operation: "updateData",
|
|
311
305
|
filter,
|
|
312
|
-
data
|
|
306
|
+
...data && { data },
|
|
307
|
+
...custom_set && { custom_set },
|
|
308
|
+
...custom_unset && { custom_unset }
|
|
313
309
|
});
|
|
314
310
|
}
|
|
315
311
|
};
|
|
@@ -364,6 +360,22 @@ function logChatPromiseExecution(promise, name) {
|
|
|
364
360
|
console.warn(`failed to do ${name}, ran into error: `, error);
|
|
365
361
|
});
|
|
366
362
|
}
|
|
363
|
+
var noopLogger = () => null;
|
|
364
|
+
var logError = (logger, error, event) => {
|
|
365
|
+
const message = "Unhandled error in event listener";
|
|
366
|
+
logger("error", message, { error, event });
|
|
367
|
+
if (logger === noopLogger) console.error(message, error, event);
|
|
368
|
+
};
|
|
369
|
+
var invokeEventListener = (listener, event, logger) => {
|
|
370
|
+
try {
|
|
371
|
+
const result = listener(event);
|
|
372
|
+
if (result && typeof result.then === "function") {
|
|
373
|
+
Promise.resolve(result).catch((error) => logError(logger, error, event));
|
|
374
|
+
}
|
|
375
|
+
} catch (error) {
|
|
376
|
+
logError(logger, error, event);
|
|
377
|
+
}
|
|
378
|
+
};
|
|
367
379
|
var sleep = (m) => new Promise((r) => setTimeout(r, m));
|
|
368
380
|
function isFunction(value) {
|
|
369
381
|
return typeof value === "function" || value instanceof Function || Object.prototype.toString.call(value) === "[object Function]";
|
|
@@ -411,7 +423,6 @@ var channelHasReadEvents = (channel) => {
|
|
|
411
423
|
return !(Array.isArray(ownCapabilities) && !ownCapabilities.includes("read-events"));
|
|
412
424
|
};
|
|
413
425
|
var channelTracksReadLocally = (channel) => !channelHasReadEvents(channel) && !!channel?.getClient().options.isLocalUnreadCountEnabled;
|
|
414
|
-
var userHasReadReceipts = (client) => client.user?.privacy_settings?.read_receipts?.enabled ?? true;
|
|
415
426
|
function addFileToFormData(uri, name, contentType) {
|
|
416
427
|
const data = new FormData();
|
|
417
428
|
if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {
|
|
@@ -8964,7 +8975,6 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
|
|
|
8964
8975
|
* @param options
|
|
8965
8976
|
*/
|
|
8966
8977
|
this.markRead = async (collection, options) => {
|
|
8967
|
-
if (!userHasReadReceipts(this.client)) return null;
|
|
8968
8978
|
let result = null;
|
|
8969
8979
|
if (isChannel(collection)) {
|
|
8970
8980
|
result = await collection.markAsReadRequest(options);
|
|
@@ -8974,7 +8984,7 @@ var MessageDeliveryReporter = class _MessageDeliveryReporter {
|
|
|
8974
8984
|
thread_id: collection.id
|
|
8975
8985
|
});
|
|
8976
8986
|
}
|
|
8977
|
-
this.removeCandidateFor(collection);
|
|
8987
|
+
if (result) this.removeCandidateFor(collection);
|
|
8978
8988
|
return result;
|
|
8979
8989
|
};
|
|
8980
8990
|
/**
|
|
@@ -9359,18 +9369,14 @@ var Channel = class {
|
|
|
9359
9369
|
return await this.query(defaultOptions, "latest");
|
|
9360
9370
|
};
|
|
9361
9371
|
this._callChannelListeners = (event) => {
|
|
9362
|
-
const
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
}
|
|
9367
|
-
if (channel.listeners[event.type]) {
|
|
9368
|
-
listeners.push(...channel.listeners[event.type]);
|
|
9369
|
-
}
|
|
9372
|
+
const listeners = [
|
|
9373
|
+
...this.listeners.all ?? [],
|
|
9374
|
+
...this.listeners[event.type] ?? []
|
|
9375
|
+
];
|
|
9376
|
+
const { logger } = this._client;
|
|
9370
9377
|
for (const listener of listeners) {
|
|
9371
|
-
if (typeof listener
|
|
9372
|
-
|
|
9373
|
-
}
|
|
9378
|
+
if (typeof listener === "string") continue;
|
|
9379
|
+
invokeEventListener(listener, event, logger);
|
|
9374
9380
|
}
|
|
9375
9381
|
};
|
|
9376
9382
|
/**
|
|
@@ -10284,14 +10290,15 @@ var Channel = class {
|
|
|
10284
10290
|
return await this.getClient().messageDeliveryReporter.markRead(this, data);
|
|
10285
10291
|
}
|
|
10286
10292
|
/**
|
|
10287
|
-
* markReadRequest - Send the mark read event for this user, only works if the `read_events` setting is
|
|
10293
|
+
* markReadRequest - Send the mark read event for this user, only works if the `read_events` setting is
|
|
10294
|
+
* enabled and the user holds the `read-events` capability on this channel
|
|
10288
10295
|
*
|
|
10289
10296
|
* @param {MarkReadOptions} data
|
|
10290
10297
|
* @return {Promise<EventAPIResponse | null>} Description
|
|
10291
10298
|
*/
|
|
10292
10299
|
async markAsReadRequest(data = {}) {
|
|
10293
10300
|
this._checkInitialized();
|
|
10294
|
-
if (!this.
|
|
10301
|
+
if (!this.getClient()._isUsingServerAuth() && (!this.getConfig()?.read_events || !channelHasReadEvents(this))) {
|
|
10295
10302
|
return null;
|
|
10296
10303
|
}
|
|
10297
10304
|
return await this.getClient().post(this._channelURL() + "/read", {
|
|
@@ -10299,14 +10306,15 @@ var Channel = class {
|
|
|
10299
10306
|
});
|
|
10300
10307
|
}
|
|
10301
10308
|
/**
|
|
10302
|
-
* markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is
|
|
10309
|
+
* markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is
|
|
10310
|
+
* enabled and the user holds the `read-events` capability on this channel
|
|
10303
10311
|
*
|
|
10304
10312
|
* @param {MarkUnreadOptions} data
|
|
10305
10313
|
* @return {APIResponse} An API response
|
|
10306
10314
|
*/
|
|
10307
10315
|
async markUnread(data) {
|
|
10308
10316
|
this._checkInitialized();
|
|
10309
|
-
if (!this.
|
|
10317
|
+
if (!this.getClient()._isUsingServerAuth() && (!this.getConfig()?.read_events || !channelHasReadEvents(this))) {
|
|
10310
10318
|
return Promise.resolve(null);
|
|
10311
10319
|
}
|
|
10312
10320
|
return await this.getClient().post(this._channelURL() + "/unread", {
|
|
@@ -14352,6 +14360,8 @@ var StreamChat = class _StreamChat {
|
|
|
14352
14360
|
* The main use case for SDKs who do independent state recovery for channels.
|
|
14353
14361
|
*/
|
|
14354
14362
|
this.preventThreadCleanup = false;
|
|
14363
|
+
this._wsPromiseSettled = true;
|
|
14364
|
+
this._wsConnectId = 0;
|
|
14355
14365
|
this.nextRequestAbortController = null;
|
|
14356
14366
|
/**
|
|
14357
14367
|
* @private
|
|
@@ -14397,17 +14407,20 @@ var StreamChat = class _StreamChat {
|
|
|
14397
14407
|
const setTokenPromise = this._setToken(user, userTokenOrProvider);
|
|
14398
14408
|
this._setUser(user);
|
|
14399
14409
|
const wsPromise = this.openConnection();
|
|
14400
|
-
|
|
14410
|
+
const setUserPromise = Promise.all([setTokenPromise, wsPromise]).then(
|
|
14401
14411
|
(result) => result[1]
|
|
14402
14412
|
// We only return connection promise;
|
|
14403
14413
|
);
|
|
14414
|
+
this.setUserPromise = setUserPromise;
|
|
14404
14415
|
try {
|
|
14405
|
-
return await
|
|
14416
|
+
return await setUserPromise;
|
|
14406
14417
|
} catch (err) {
|
|
14407
|
-
if (this.
|
|
14408
|
-
this.
|
|
14409
|
-
|
|
14410
|
-
|
|
14418
|
+
if (this.setUserPromise === setUserPromise && this.userID === user.id) {
|
|
14419
|
+
if (this.persistUserOnConnectionFailure) {
|
|
14420
|
+
this.closeConnection();
|
|
14421
|
+
} else {
|
|
14422
|
+
this.disconnectUser();
|
|
14423
|
+
}
|
|
14411
14424
|
}
|
|
14412
14425
|
throw err;
|
|
14413
14426
|
}
|
|
@@ -14503,9 +14516,50 @@ var StreamChat = class _StreamChat {
|
|
|
14503
14516
|
return;
|
|
14504
14517
|
}
|
|
14505
14518
|
this.clientID = `${this.userID}--${randomId()}`;
|
|
14506
|
-
|
|
14519
|
+
const wsPromise = this._bindWsPromise(this.connect());
|
|
14507
14520
|
this._startCleaning();
|
|
14508
|
-
return
|
|
14521
|
+
return wsPromise;
|
|
14522
|
+
};
|
|
14523
|
+
/**
|
|
14524
|
+
* Rejects the shared `wsPromise`, invalidates any in-flight connect attempt
|
|
14525
|
+
*/
|
|
14526
|
+
this._rejectPendingWsPromise = (reason) => {
|
|
14527
|
+
if (!this._wsPromiseSettled) {
|
|
14528
|
+
this._wsConnectId += 1;
|
|
14529
|
+
this._wsPromiseSettled = true;
|
|
14530
|
+
this.wsPromise?.catch(() => {
|
|
14531
|
+
});
|
|
14532
|
+
this._rejectWsPromise?.(reason);
|
|
14533
|
+
}
|
|
14534
|
+
};
|
|
14535
|
+
/**
|
|
14536
|
+
* Keep a single pending `wsPromise` across close/reopen so callers that already
|
|
14537
|
+
* `await this.wsPromise` are not stranded when `openConnection` starts a new connect.
|
|
14538
|
+
*/
|
|
14539
|
+
this._bindWsPromise = (connectPromise) => {
|
|
14540
|
+
const connectId = ++this._wsConnectId;
|
|
14541
|
+
let pending = this.wsPromise;
|
|
14542
|
+
if (this._wsPromiseSettled || !pending) {
|
|
14543
|
+
this._wsPromiseSettled = false;
|
|
14544
|
+
pending = new Promise((resolve, reject) => {
|
|
14545
|
+
this._resolveWsPromise = resolve;
|
|
14546
|
+
this._rejectWsPromise = reject;
|
|
14547
|
+
});
|
|
14548
|
+
this.wsPromise = pending;
|
|
14549
|
+
}
|
|
14550
|
+
connectPromise.then(
|
|
14551
|
+
(value) => {
|
|
14552
|
+
if (connectId !== this._wsConnectId) return;
|
|
14553
|
+
this._wsPromiseSettled = true;
|
|
14554
|
+
this._resolveWsPromise?.(value);
|
|
14555
|
+
},
|
|
14556
|
+
(error) => {
|
|
14557
|
+
if (connectId !== this._wsConnectId) return;
|
|
14558
|
+
this._wsPromiseSettled = true;
|
|
14559
|
+
this._rejectWsPromise?.(error);
|
|
14560
|
+
}
|
|
14561
|
+
);
|
|
14562
|
+
return pending;
|
|
14509
14563
|
};
|
|
14510
14564
|
/**
|
|
14511
14565
|
* @deprecated Please use client.openConnction instead.
|
|
@@ -14539,6 +14593,10 @@ var StreamChat = class _StreamChat {
|
|
|
14539
14593
|
delete this._user;
|
|
14540
14594
|
delete this.userID;
|
|
14541
14595
|
this.anonymous = false;
|
|
14596
|
+
this._rejectPendingWsPromise(
|
|
14597
|
+
new Error("Connection was closed because disconnectUser() was called")
|
|
14598
|
+
);
|
|
14599
|
+
this.wsPromise = null;
|
|
14542
14600
|
const closePromise = this.closeConnection(timeout);
|
|
14543
14601
|
for (const channel of Object.values(this.activeChannels)) {
|
|
14544
14602
|
channel._disconnect();
|
|
@@ -14768,16 +14826,12 @@ var StreamChat = class _StreamChat {
|
|
|
14768
14826
|
}
|
|
14769
14827
|
};
|
|
14770
14828
|
this._callClientListeners = (event) => {
|
|
14771
|
-
const
|
|
14772
|
-
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
}
|
|
14776
|
-
if (client.listeners[event.type]) {
|
|
14777
|
-
listeners.push(...client.listeners[event.type]);
|
|
14778
|
-
}
|
|
14829
|
+
const listeners = [
|
|
14830
|
+
...this.listeners.all ?? [],
|
|
14831
|
+
...this.listeners[event.type] ?? []
|
|
14832
|
+
];
|
|
14779
14833
|
for (const listener of listeners) {
|
|
14780
|
-
listener
|
|
14834
|
+
invokeEventListener(listener, event, this.logger);
|
|
14781
14835
|
}
|
|
14782
14836
|
};
|
|
14783
14837
|
this.recoverState = async () => {
|
|
@@ -14813,7 +14867,9 @@ var StreamChat = class _StreamChat {
|
|
|
14813
14867
|
type: "connection.recovered"
|
|
14814
14868
|
});
|
|
14815
14869
|
}
|
|
14816
|
-
this.
|
|
14870
|
+
if (this._wsPromiseSettled) {
|
|
14871
|
+
this.wsPromise = Promise.resolve();
|
|
14872
|
+
}
|
|
14817
14873
|
this.setUserPromise = Promise.resolve();
|
|
14818
14874
|
};
|
|
14819
14875
|
/**
|
|
@@ -14931,7 +14987,7 @@ var StreamChat = class _StreamChat {
|
|
|
14931
14987
|
return this.userAgent;
|
|
14932
14988
|
}
|
|
14933
14989
|
if (!this.cachedUserAgent) {
|
|
14934
|
-
const version = "9.
|
|
14990
|
+
const version = "9.53.0";
|
|
14935
14991
|
const { name: sdkName, version: sdkVersion } = this.sdkIdentifier ?? {};
|
|
14936
14992
|
const { name: appName, version: appVersion } = this.appIdentifier ?? {};
|
|
14937
14993
|
const { os, model: deviceModel } = this.deviceIdentifier ?? {};
|
|
@@ -15020,7 +15076,7 @@ var StreamChat = class _StreamChat {
|
|
|
15020
15076
|
this.defaultWSTimeoutWithFallback = 6 * 1e3;
|
|
15021
15077
|
this.defaultWSTimeout = 15 * 1e3;
|
|
15022
15078
|
this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;
|
|
15023
|
-
this.logger = isFunction(inputOptions.logger) ? inputOptions.logger :
|
|
15079
|
+
this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : noopLogger;
|
|
15024
15080
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
15025
15081
|
this.threads = new ThreadManager({ client: this });
|
|
15026
15082
|
this.polls = new PollManager({ client: this });
|
|
@@ -18173,6 +18229,10 @@ var StreamChat = class _StreamChat {
|
|
|
18173
18229
|
/**
|
|
18174
18230
|
* Update Channels Batch
|
|
18175
18231
|
*
|
|
18232
|
+
* For the `updateData` operation, `data.custom` replaces the channel's whole
|
|
18233
|
+
* custom object, while the root-level `custom_set` / `custom_unset` patch
|
|
18234
|
+
* individual keys and leave the rest untouched.
|
|
18235
|
+
*
|
|
18176
18236
|
* @param {UpdateChannelsBatchOptions} payload for updating channels in batch
|
|
18177
18237
|
* @return {Promise<APIResponse & UpdateChannelsBatchResponse>} The server response
|
|
18178
18238
|
*/
|