stream-chat 9.41.1 → 9.42.1
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 +181 -65
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +182 -65
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +181 -65
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/client.d.ts +5 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +1 -1
- package/dist/types/messageComposer/attachmentManager.d.ts +1 -0
- package/dist/types/messageComposer/configuration/types.d.ts +6 -1
- package/dist/types/messageComposer/fileUtils.d.ts +1 -1
- package/dist/types/messageComposer/messageComposer.d.ts +4 -4
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +2 -2
- package/dist/types/messageComposer/pollComposer.d.ts +2 -2
- package/dist/types/messageComposer/textComposer.d.ts +2 -2
- package/dist/types/uploadManager.d.ts +45 -0
- package/dist/types/utils.d.ts +3 -3
- package/package.json +2 -2
- package/src/client.ts +7 -0
- package/src/index.ts +1 -0
- package/src/messageComposer/attachmentManager.ts +65 -69
- package/src/messageComposer/configuration/types.ts +6 -1
- package/src/messageComposer/messageComposer.ts +0 -9
- package/src/uploadManager.ts +176 -0
package/dist/cjs/index.node.js
CHANGED
|
@@ -117,6 +117,7 @@ __export(index_exports, {
|
|
|
117
117
|
ThreadManager: () => ThreadManager,
|
|
118
118
|
TokenManager: () => TokenManager,
|
|
119
119
|
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT: () => UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
120
|
+
UploadManager: () => UploadManager,
|
|
120
121
|
UserFromToken: () => UserFromToken,
|
|
121
122
|
UserSearchSource: () => UserSearchSource,
|
|
122
123
|
VALID_MAX_VOTES_VALUE_REGEX: () => VALID_MAX_VOTES_VALUE_REGEX,
|
|
@@ -3278,11 +3279,11 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3278
3279
|
return attachments;
|
|
3279
3280
|
}
|
|
3280
3281
|
}
|
|
3281
|
-
return
|
|
3282
|
+
return stateAttachments;
|
|
3282
3283
|
};
|
|
3283
3284
|
this.updateAttachment = (attachmentToUpdate) => {
|
|
3284
3285
|
const updatedAttachments = this.prepareAttachmentUpdate(attachmentToUpdate);
|
|
3285
|
-
if (updatedAttachments) {
|
|
3286
|
+
if (updatedAttachments && updatedAttachments !== this.attachments) {
|
|
3286
3287
|
this.state.partialNext({ attachments: updatedAttachments });
|
|
3287
3288
|
}
|
|
3288
3289
|
};
|
|
@@ -3292,15 +3293,15 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3292
3293
|
let hasUpdates = false;
|
|
3293
3294
|
attachmentsToUpsert.forEach((attachment) => {
|
|
3294
3295
|
const updatedAttachments = this.prepareAttachmentUpdate(attachment);
|
|
3295
|
-
if (updatedAttachments) {
|
|
3296
|
-
attachments = updatedAttachments;
|
|
3297
|
-
hasUpdates = true;
|
|
3298
|
-
} else {
|
|
3296
|
+
if (updatedAttachments === null) {
|
|
3299
3297
|
const localAttachment = ensureIsLocalAttachment(attachment);
|
|
3300
3298
|
if (localAttachment) {
|
|
3301
3299
|
attachments.push(localAttachment);
|
|
3302
3300
|
hasUpdates = true;
|
|
3303
3301
|
}
|
|
3302
|
+
} else if (updatedAttachments !== this.attachments) {
|
|
3303
|
+
attachments = updatedAttachments;
|
|
3304
|
+
hasUpdates = true;
|
|
3304
3305
|
}
|
|
3305
3306
|
});
|
|
3306
3307
|
if (hasUpdates) {
|
|
@@ -3308,11 +3309,15 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3308
3309
|
}
|
|
3309
3310
|
};
|
|
3310
3311
|
this.removeAttachments = (localAttachmentIds) => {
|
|
3312
|
+
if (!localAttachmentIds.length) return;
|
|
3311
3313
|
this.state.partialNext({
|
|
3312
3314
|
attachments: this.attachments.filter(
|
|
3313
3315
|
(attachment) => !localAttachmentIds.includes(attachment.localMetadata?.id)
|
|
3314
3316
|
)
|
|
3315
3317
|
});
|
|
3318
|
+
for (const id of localAttachmentIds) {
|
|
3319
|
+
this.client.uploadManager.deleteUploadRecord(id);
|
|
3320
|
+
}
|
|
3316
3321
|
};
|
|
3317
3322
|
this.getUploadConfigCheck = async (fileLike) => {
|
|
3318
3323
|
const client = this.channel.getClient();
|
|
@@ -3401,13 +3406,17 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3401
3406
|
const percent = progressEvent.lengthComputable && progressEvent.total ? Math.round(progressEvent.loaded * 100 / progressEvent.total) : void 0;
|
|
3402
3407
|
options.onProgress?.(percent);
|
|
3403
3408
|
} : void 0;
|
|
3409
|
+
const axiosUploadConfig = progressHandler || options?.abortSignal ? {
|
|
3410
|
+
...progressHandler ? { onUploadProgress: progressHandler } : {},
|
|
3411
|
+
...options?.abortSignal ? { signal: options.abortSignal } : {}
|
|
3412
|
+
} : void 0;
|
|
3404
3413
|
if (isFileReference(fileLike)) {
|
|
3405
3414
|
return this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3406
3415
|
fileLike.uri,
|
|
3407
3416
|
fileLike.name,
|
|
3408
3417
|
fileLike.type,
|
|
3409
3418
|
void 0,
|
|
3410
|
-
|
|
3419
|
+
axiosUploadConfig
|
|
3411
3420
|
);
|
|
3412
3421
|
}
|
|
3413
3422
|
const file = isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -3415,13 +3424,7 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3415
3424
|
fileName: generateFileName(fileLike.type),
|
|
3416
3425
|
mimeType: fileLike.type
|
|
3417
3426
|
});
|
|
3418
|
-
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3419
|
-
file,
|
|
3420
|
-
void 0,
|
|
3421
|
-
void 0,
|
|
3422
|
-
void 0,
|
|
3423
|
-
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3424
|
-
);
|
|
3427
|
+
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](file, void 0, void 0, void 0, axiosUploadConfig);
|
|
3425
3428
|
return result;
|
|
3426
3429
|
};
|
|
3427
3430
|
/**
|
|
@@ -3456,33 +3459,9 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3456
3459
|
});
|
|
3457
3460
|
return localAttachment;
|
|
3458
3461
|
}
|
|
3459
|
-
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3460
|
-
const uploadingAttachment = {
|
|
3461
|
-
...attachment,
|
|
3462
|
-
localMetadata: {
|
|
3463
|
-
...attachment.localMetadata,
|
|
3464
|
-
uploadState: "uploading",
|
|
3465
|
-
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3466
|
-
}
|
|
3467
|
-
};
|
|
3468
|
-
this.upsertAttachments([uploadingAttachment]);
|
|
3469
|
-
const uploadOptions = shouldTrackProgress ? {
|
|
3470
|
-
onProgress: (percent) => {
|
|
3471
|
-
this.updateAttachment({
|
|
3472
|
-
...uploadingAttachment,
|
|
3473
|
-
localMetadata: {
|
|
3474
|
-
...uploadingAttachment.localMetadata,
|
|
3475
|
-
uploadProgress: percent
|
|
3476
|
-
}
|
|
3477
|
-
});
|
|
3478
|
-
}
|
|
3479
|
-
} : void 0;
|
|
3480
3462
|
let response;
|
|
3481
3463
|
try {
|
|
3482
|
-
response = await this.
|
|
3483
|
-
localAttachment.localMetadata.file,
|
|
3484
|
-
uploadOptions
|
|
3485
|
-
);
|
|
3464
|
+
response = await this.upload(attachment);
|
|
3486
3465
|
} catch (error) {
|
|
3487
3466
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
3488
3467
|
const failedAttachment = {
|
|
@@ -3551,31 +3530,10 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3551
3530
|
this.upsertAttachments([attachment]);
|
|
3552
3531
|
return preUpload.state.attachment;
|
|
3553
3532
|
}
|
|
3554
|
-
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3555
|
-
attachment = {
|
|
3556
|
-
...attachment,
|
|
3557
|
-
localMetadata: {
|
|
3558
|
-
...attachment.localMetadata,
|
|
3559
|
-
uploadState: "uploading",
|
|
3560
|
-
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3561
|
-
}
|
|
3562
|
-
};
|
|
3563
|
-
this.upsertAttachments([attachment]);
|
|
3564
|
-
const uploadOptions = shouldTrackProgress ? {
|
|
3565
|
-
onProgress: (percent) => {
|
|
3566
|
-
this.updateAttachment({
|
|
3567
|
-
...attachment,
|
|
3568
|
-
localMetadata: {
|
|
3569
|
-
...attachment.localMetadata,
|
|
3570
|
-
uploadProgress: percent
|
|
3571
|
-
}
|
|
3572
|
-
});
|
|
3573
|
-
}
|
|
3574
|
-
} : void 0;
|
|
3575
3533
|
let response;
|
|
3576
3534
|
let error;
|
|
3577
3535
|
try {
|
|
3578
|
-
response = await this.
|
|
3536
|
+
response = await this.upload(attachment);
|
|
3579
3537
|
} catch (err) {
|
|
3580
3538
|
error = err instanceof Error ? err : void 0;
|
|
3581
3539
|
}
|
|
@@ -3702,6 +3660,40 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3702
3660
|
({ localMetadata }) => localMetadata.uploadState === state
|
|
3703
3661
|
);
|
|
3704
3662
|
}
|
|
3663
|
+
upload(attachment) {
|
|
3664
|
+
const localId = attachment.localMetadata.id;
|
|
3665
|
+
this.upsertAttachments([
|
|
3666
|
+
{
|
|
3667
|
+
...attachment,
|
|
3668
|
+
localMetadata: {
|
|
3669
|
+
...attachment.localMetadata,
|
|
3670
|
+
uploadState: "uploading",
|
|
3671
|
+
uploadProgress: this.config.trackUploadProgress ? 0 : void 0
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
]);
|
|
3675
|
+
const unsubscribe = this.client.uploadManager.state.subscribeWithSelector(
|
|
3676
|
+
(s) => ({ upload: s.uploads[localId] }),
|
|
3677
|
+
({ upload: nextUpload }) => {
|
|
3678
|
+
if (!nextUpload) return;
|
|
3679
|
+
this.updateAttachment({
|
|
3680
|
+
...attachment,
|
|
3681
|
+
localMetadata: {
|
|
3682
|
+
...attachment.localMetadata,
|
|
3683
|
+
uploadState: "uploading",
|
|
3684
|
+
uploadProgress: nextUpload.uploadProgress
|
|
3685
|
+
}
|
|
3686
|
+
});
|
|
3687
|
+
}
|
|
3688
|
+
);
|
|
3689
|
+
return this.client.uploadManager.upload({
|
|
3690
|
+
id: localId,
|
|
3691
|
+
channelCid: this.channel.cid,
|
|
3692
|
+
file: attachment.localMetadata.file
|
|
3693
|
+
}).finally(() => {
|
|
3694
|
+
unsubscribe();
|
|
3695
|
+
});
|
|
3696
|
+
}
|
|
3705
3697
|
};
|
|
3706
3698
|
_AttachmentManager.toLocalUploadAttachment = (fileLike) => {
|
|
3707
3699
|
const file = isFileReference(fileLike) || isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -7554,9 +7546,6 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7554
7546
|
return this.state.getLatestValue().showReplyInChannel;
|
|
7555
7547
|
}
|
|
7556
7548
|
get hasSendableData() {
|
|
7557
|
-
if (this.client.offlineDb) {
|
|
7558
|
-
return !this.textComposer.textIsEmpty || !!this.attachmentManager.attachments.length || !!this.pollId || !!this.locationComposer.validLocation;
|
|
7559
|
-
}
|
|
7560
7549
|
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId || !!this.locationComposer.validLocation);
|
|
7561
7550
|
}
|
|
7562
7551
|
get compositionIsEmpty() {
|
|
@@ -10578,6 +10567,131 @@ var StableWSConnection = class {
|
|
|
10578
10567
|
}
|
|
10579
10568
|
};
|
|
10580
10569
|
|
|
10570
|
+
// src/uploadManager.ts
|
|
10571
|
+
var initState7 = () => ({ uploads: {} });
|
|
10572
|
+
var upsertById = (uploads, record) => ({
|
|
10573
|
+
...uploads,
|
|
10574
|
+
[record.id]: { ...uploads[record.id], ...record }
|
|
10575
|
+
});
|
|
10576
|
+
var updateById = (uploads, record) => {
|
|
10577
|
+
if (!(record.id in uploads)) return null;
|
|
10578
|
+
const current = uploads[record.id];
|
|
10579
|
+
return { ...uploads, [record.id]: { ...current, ...record } };
|
|
10580
|
+
};
|
|
10581
|
+
var UploadManager = class {
|
|
10582
|
+
constructor(client) {
|
|
10583
|
+
this.client = client;
|
|
10584
|
+
this.inFlightUploads = /* @__PURE__ */ new Map();
|
|
10585
|
+
this.getUpload = (id) => this.uploads[id];
|
|
10586
|
+
/**
|
|
10587
|
+
* Clears all upload records.
|
|
10588
|
+
* Invoked when the user disconnects so a later session does not inherit stale upload state.
|
|
10589
|
+
* Aborts every in-flight upload request via its `UploadRequestOptions.abortSignal`.
|
|
10590
|
+
*/
|
|
10591
|
+
this.reset = () => {
|
|
10592
|
+
for (const { abortController } of this.inFlightUploads.values()) {
|
|
10593
|
+
abortController.abort();
|
|
10594
|
+
}
|
|
10595
|
+
this.inFlightUploads.clear();
|
|
10596
|
+
this.state.next(initState7());
|
|
10597
|
+
};
|
|
10598
|
+
/**
|
|
10599
|
+
* Removes the upload record for `id` if present.
|
|
10600
|
+
* If an upload is still in progress, aborts its `UploadRequestOptions.abortSignal`.
|
|
10601
|
+
*/
|
|
10602
|
+
this.deleteUploadRecord = (id) => {
|
|
10603
|
+
const flight = this.inFlightUploads.get(id);
|
|
10604
|
+
if (flight) {
|
|
10605
|
+
this.inFlightUploads.delete(id);
|
|
10606
|
+
flight.abortController.abort();
|
|
10607
|
+
}
|
|
10608
|
+
this.state.next((current) => {
|
|
10609
|
+
if (!(id in current.uploads)) return current;
|
|
10610
|
+
const uploads = { ...current.uploads };
|
|
10611
|
+
delete uploads[id];
|
|
10612
|
+
return { ...current, uploads };
|
|
10613
|
+
});
|
|
10614
|
+
};
|
|
10615
|
+
/**
|
|
10616
|
+
* Starts an upload for `id`, or returns the existing in-flight promise if one is already running.
|
|
10617
|
+
* Uses {@link StreamChat.channel}(`channelCid`) → `messageComposer.attachmentManager.doUploadRequest`.
|
|
10618
|
+
* Resolves with that result; rejects if the upload rejects (the record is removed from state either way).
|
|
10619
|
+
*/
|
|
10620
|
+
this.upload = ({
|
|
10621
|
+
id,
|
|
10622
|
+
channelCid,
|
|
10623
|
+
file
|
|
10624
|
+
}) => {
|
|
10625
|
+
const existing = this.inFlightUploads.get(id);
|
|
10626
|
+
if (existing) return existing.promise;
|
|
10627
|
+
let resolvePromise;
|
|
10628
|
+
let rejectPromise;
|
|
10629
|
+
const promise = new Promise((resolve, reject) => {
|
|
10630
|
+
resolvePromise = resolve;
|
|
10631
|
+
rejectPromise = reject;
|
|
10632
|
+
});
|
|
10633
|
+
const abortController = new AbortController();
|
|
10634
|
+
this.inFlightUploads.set(id, { promise, abortController });
|
|
10635
|
+
void (async () => {
|
|
10636
|
+
const attachmentManager = this.resolveAttachmentManager(channelCid);
|
|
10637
|
+
const trackProgress = attachmentManager.config.trackUploadProgress;
|
|
10638
|
+
try {
|
|
10639
|
+
this.upsertUpload({
|
|
10640
|
+
id,
|
|
10641
|
+
uploadProgress: trackProgress ? 0 : void 0
|
|
10642
|
+
});
|
|
10643
|
+
const onProgress = trackProgress ? (progress) => {
|
|
10644
|
+
this.updateUpload({
|
|
10645
|
+
id,
|
|
10646
|
+
uploadProgress: progress
|
|
10647
|
+
});
|
|
10648
|
+
} : void 0;
|
|
10649
|
+
const uploadRequestOptions = {
|
|
10650
|
+
abortSignal: abortController.signal,
|
|
10651
|
+
...onProgress ? { onProgress } : {}
|
|
10652
|
+
};
|
|
10653
|
+
const response = await attachmentManager.doUploadRequest(
|
|
10654
|
+
file,
|
|
10655
|
+
uploadRequestOptions
|
|
10656
|
+
);
|
|
10657
|
+
resolvePromise(response);
|
|
10658
|
+
} catch (error) {
|
|
10659
|
+
rejectPromise(error);
|
|
10660
|
+
} finally {
|
|
10661
|
+
this.inFlightUploads.delete(id);
|
|
10662
|
+
this.deleteUploadRecord(id);
|
|
10663
|
+
}
|
|
10664
|
+
})();
|
|
10665
|
+
return promise;
|
|
10666
|
+
};
|
|
10667
|
+
this.upsertUpload = (record) => {
|
|
10668
|
+
this.state.partialNext({
|
|
10669
|
+
uploads: upsertById(this.uploads, record)
|
|
10670
|
+
});
|
|
10671
|
+
};
|
|
10672
|
+
this.updateUpload = (record) => {
|
|
10673
|
+
this.state.next((current) => {
|
|
10674
|
+
const nextUploads = updateById(current.uploads, record);
|
|
10675
|
+
if (!nextUploads) return current;
|
|
10676
|
+
return { ...current, uploads: nextUploads };
|
|
10677
|
+
});
|
|
10678
|
+
};
|
|
10679
|
+
this.state = new StateStore(initState7());
|
|
10680
|
+
}
|
|
10681
|
+
resolveAttachmentManager(channelCid) {
|
|
10682
|
+
const colon = channelCid.indexOf(":");
|
|
10683
|
+
if (colon <= 0 || colon === channelCid.length - 1) {
|
|
10684
|
+
throw new Error(`Invalid channelCid: ${channelCid}`);
|
|
10685
|
+
}
|
|
10686
|
+
const channelType = channelCid.slice(0, colon);
|
|
10687
|
+
const channelId = channelCid.slice(colon + 1);
|
|
10688
|
+
return this.client.channel(channelType, channelId).messageComposer.attachmentManager;
|
|
10689
|
+
}
|
|
10690
|
+
get uploads() {
|
|
10691
|
+
return this.state.getLatestValue().uploads;
|
|
10692
|
+
}
|
|
10693
|
+
};
|
|
10694
|
+
|
|
10581
10695
|
// src/signing.ts
|
|
10582
10696
|
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
10583
10697
|
var import_crypto = __toESM(require("crypto"));
|
|
@@ -13050,6 +13164,7 @@ var StreamChat = class _StreamChat {
|
|
|
13050
13164
|
this.activeChannels = {};
|
|
13051
13165
|
this.state = new ClientState({ client: this });
|
|
13052
13166
|
this.threads.resetState();
|
|
13167
|
+
this.uploadManager.reset();
|
|
13053
13168
|
closePromise.finally(() => {
|
|
13054
13169
|
this.tokenManager.reset();
|
|
13055
13170
|
}).catch((err) => console.error(err));
|
|
@@ -13456,6 +13571,7 @@ var StreamChat = class _StreamChat {
|
|
|
13456
13571
|
this.blockedUsers = new StateStore({ userIds: [] });
|
|
13457
13572
|
this.moderation = new Moderation(this);
|
|
13458
13573
|
this.notifications = options?.notifications ?? new NotificationManager();
|
|
13574
|
+
this.uploadManager = new UploadManager(this);
|
|
13459
13575
|
if (secretOrOptions && isString2(secretOrOptions)) {
|
|
13460
13576
|
this.secret = secretOrOptions;
|
|
13461
13577
|
}
|
|
@@ -15245,7 +15361,7 @@ var StreamChat = class _StreamChat {
|
|
|
15245
15361
|
if (this.userAgent) {
|
|
15246
15362
|
return this.userAgent;
|
|
15247
15363
|
}
|
|
15248
|
-
const version = "9.
|
|
15364
|
+
const version = "9.42.1";
|
|
15249
15365
|
const clientBundle = "node-cjs";
|
|
15250
15366
|
let userAgentString = "";
|
|
15251
15367
|
if (this.sdkIdentifier) {
|
|
@@ -17935,6 +18051,7 @@ var FixedSizeQueueCache = class {
|
|
|
17935
18051
|
ThreadManager,
|
|
17936
18052
|
TokenManager,
|
|
17937
18053
|
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
18054
|
+
UploadManager,
|
|
17938
18055
|
UserFromToken,
|
|
17939
18056
|
UserSearchSource,
|
|
17940
18057
|
VALID_MAX_VOTES_VALUE_REGEX,
|