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
|
@@ -138,6 +138,7 @@ __export(index_exports, {
|
|
|
138
138
|
ThreadManager: () => ThreadManager,
|
|
139
139
|
TokenManager: () => TokenManager,
|
|
140
140
|
UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT: () => UPDATE_LIVE_LOCATION_REQUEST_MIN_THROTTLE_TIMEOUT,
|
|
141
|
+
UploadManager: () => UploadManager,
|
|
141
142
|
UserFromToken: () => UserFromToken,
|
|
142
143
|
UserSearchSource: () => UserSearchSource,
|
|
143
144
|
VALID_MAX_VOTES_VALUE_REGEX: () => VALID_MAX_VOTES_VALUE_REGEX,
|
|
@@ -3299,11 +3300,11 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3299
3300
|
return attachments;
|
|
3300
3301
|
}
|
|
3301
3302
|
}
|
|
3302
|
-
return
|
|
3303
|
+
return stateAttachments;
|
|
3303
3304
|
};
|
|
3304
3305
|
this.updateAttachment = (attachmentToUpdate) => {
|
|
3305
3306
|
const updatedAttachments = this.prepareAttachmentUpdate(attachmentToUpdate);
|
|
3306
|
-
if (updatedAttachments) {
|
|
3307
|
+
if (updatedAttachments && updatedAttachments !== this.attachments) {
|
|
3307
3308
|
this.state.partialNext({ attachments: updatedAttachments });
|
|
3308
3309
|
}
|
|
3309
3310
|
};
|
|
@@ -3313,15 +3314,15 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3313
3314
|
let hasUpdates = false;
|
|
3314
3315
|
attachmentsToUpsert.forEach((attachment) => {
|
|
3315
3316
|
const updatedAttachments = this.prepareAttachmentUpdate(attachment);
|
|
3316
|
-
if (updatedAttachments) {
|
|
3317
|
-
attachments = updatedAttachments;
|
|
3318
|
-
hasUpdates = true;
|
|
3319
|
-
} else {
|
|
3317
|
+
if (updatedAttachments === null) {
|
|
3320
3318
|
const localAttachment = ensureIsLocalAttachment(attachment);
|
|
3321
3319
|
if (localAttachment) {
|
|
3322
3320
|
attachments.push(localAttachment);
|
|
3323
3321
|
hasUpdates = true;
|
|
3324
3322
|
}
|
|
3323
|
+
} else if (updatedAttachments !== this.attachments) {
|
|
3324
|
+
attachments = updatedAttachments;
|
|
3325
|
+
hasUpdates = true;
|
|
3325
3326
|
}
|
|
3326
3327
|
});
|
|
3327
3328
|
if (hasUpdates) {
|
|
@@ -3329,11 +3330,15 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3329
3330
|
}
|
|
3330
3331
|
};
|
|
3331
3332
|
this.removeAttachments = (localAttachmentIds) => {
|
|
3333
|
+
if (!localAttachmentIds.length) return;
|
|
3332
3334
|
this.state.partialNext({
|
|
3333
3335
|
attachments: this.attachments.filter(
|
|
3334
3336
|
(attachment) => !localAttachmentIds.includes(attachment.localMetadata?.id)
|
|
3335
3337
|
)
|
|
3336
3338
|
});
|
|
3339
|
+
for (const id of localAttachmentIds) {
|
|
3340
|
+
this.client.uploadManager.deleteUploadRecord(id);
|
|
3341
|
+
}
|
|
3337
3342
|
};
|
|
3338
3343
|
this.getUploadConfigCheck = async (fileLike) => {
|
|
3339
3344
|
const client = this.channel.getClient();
|
|
@@ -3422,13 +3427,17 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3422
3427
|
const percent = progressEvent.lengthComputable && progressEvent.total ? Math.round(progressEvent.loaded * 100 / progressEvent.total) : void 0;
|
|
3423
3428
|
options.onProgress?.(percent);
|
|
3424
3429
|
} : void 0;
|
|
3430
|
+
const axiosUploadConfig = progressHandler || options?.abortSignal ? {
|
|
3431
|
+
...progressHandler ? { onUploadProgress: progressHandler } : {},
|
|
3432
|
+
...options?.abortSignal ? { signal: options.abortSignal } : {}
|
|
3433
|
+
} : void 0;
|
|
3425
3434
|
if (isFileReference(fileLike)) {
|
|
3426
3435
|
return this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3427
3436
|
fileLike.uri,
|
|
3428
3437
|
fileLike.name,
|
|
3429
3438
|
fileLike.type,
|
|
3430
3439
|
void 0,
|
|
3431
|
-
|
|
3440
|
+
axiosUploadConfig
|
|
3432
3441
|
);
|
|
3433
3442
|
}
|
|
3434
3443
|
const file = isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -3436,13 +3445,7 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3436
3445
|
fileName: generateFileName(fileLike.type),
|
|
3437
3446
|
mimeType: fileLike.type
|
|
3438
3447
|
});
|
|
3439
|
-
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](
|
|
3440
|
-
file,
|
|
3441
|
-
void 0,
|
|
3442
|
-
void 0,
|
|
3443
|
-
void 0,
|
|
3444
|
-
progressHandler ? { onUploadProgress: progressHandler } : void 0
|
|
3445
|
-
);
|
|
3448
|
+
const { duration, ...result } = await this.channel[isImageFile(fileLike) ? "sendImage" : "sendFile"](file, void 0, void 0, void 0, axiosUploadConfig);
|
|
3446
3449
|
return result;
|
|
3447
3450
|
};
|
|
3448
3451
|
/**
|
|
@@ -3477,33 +3480,9 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3477
3480
|
});
|
|
3478
3481
|
return localAttachment;
|
|
3479
3482
|
}
|
|
3480
|
-
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3481
|
-
const uploadingAttachment = {
|
|
3482
|
-
...attachment,
|
|
3483
|
-
localMetadata: {
|
|
3484
|
-
...attachment.localMetadata,
|
|
3485
|
-
uploadState: "uploading",
|
|
3486
|
-
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3487
|
-
}
|
|
3488
|
-
};
|
|
3489
|
-
this.upsertAttachments([uploadingAttachment]);
|
|
3490
|
-
const uploadOptions = shouldTrackProgress ? {
|
|
3491
|
-
onProgress: (percent) => {
|
|
3492
|
-
this.updateAttachment({
|
|
3493
|
-
...uploadingAttachment,
|
|
3494
|
-
localMetadata: {
|
|
3495
|
-
...uploadingAttachment.localMetadata,
|
|
3496
|
-
uploadProgress: percent
|
|
3497
|
-
}
|
|
3498
|
-
});
|
|
3499
|
-
}
|
|
3500
|
-
} : void 0;
|
|
3501
3483
|
let response;
|
|
3502
3484
|
try {
|
|
3503
|
-
response = await this.
|
|
3504
|
-
localAttachment.localMetadata.file,
|
|
3505
|
-
uploadOptions
|
|
3506
|
-
);
|
|
3485
|
+
response = await this.upload(attachment);
|
|
3507
3486
|
} catch (error) {
|
|
3508
3487
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
3509
3488
|
const failedAttachment = {
|
|
@@ -3572,31 +3551,10 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3572
3551
|
this.upsertAttachments([attachment]);
|
|
3573
3552
|
return preUpload.state.attachment;
|
|
3574
3553
|
}
|
|
3575
|
-
const shouldTrackProgress = this.config.trackUploadProgress;
|
|
3576
|
-
attachment = {
|
|
3577
|
-
...attachment,
|
|
3578
|
-
localMetadata: {
|
|
3579
|
-
...attachment.localMetadata,
|
|
3580
|
-
uploadState: "uploading",
|
|
3581
|
-
...shouldTrackProgress && { uploadProgress: 0 }
|
|
3582
|
-
}
|
|
3583
|
-
};
|
|
3584
|
-
this.upsertAttachments([attachment]);
|
|
3585
|
-
const uploadOptions = shouldTrackProgress ? {
|
|
3586
|
-
onProgress: (percent) => {
|
|
3587
|
-
this.updateAttachment({
|
|
3588
|
-
...attachment,
|
|
3589
|
-
localMetadata: {
|
|
3590
|
-
...attachment.localMetadata,
|
|
3591
|
-
uploadProgress: percent
|
|
3592
|
-
}
|
|
3593
|
-
});
|
|
3594
|
-
}
|
|
3595
|
-
} : void 0;
|
|
3596
3554
|
let response;
|
|
3597
3555
|
let error;
|
|
3598
3556
|
try {
|
|
3599
|
-
response = await this.
|
|
3557
|
+
response = await this.upload(attachment);
|
|
3600
3558
|
} catch (err) {
|
|
3601
3559
|
error = err instanceof Error ? err : void 0;
|
|
3602
3560
|
}
|
|
@@ -3723,6 +3681,40 @@ var _AttachmentManager = class _AttachmentManager {
|
|
|
3723
3681
|
({ localMetadata }) => localMetadata.uploadState === state
|
|
3724
3682
|
);
|
|
3725
3683
|
}
|
|
3684
|
+
upload(attachment) {
|
|
3685
|
+
const localId = attachment.localMetadata.id;
|
|
3686
|
+
this.upsertAttachments([
|
|
3687
|
+
{
|
|
3688
|
+
...attachment,
|
|
3689
|
+
localMetadata: {
|
|
3690
|
+
...attachment.localMetadata,
|
|
3691
|
+
uploadState: "uploading",
|
|
3692
|
+
uploadProgress: this.config.trackUploadProgress ? 0 : void 0
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
]);
|
|
3696
|
+
const unsubscribe = this.client.uploadManager.state.subscribeWithSelector(
|
|
3697
|
+
(s) => ({ upload: s.uploads[localId] }),
|
|
3698
|
+
({ upload: nextUpload }) => {
|
|
3699
|
+
if (!nextUpload) return;
|
|
3700
|
+
this.updateAttachment({
|
|
3701
|
+
...attachment,
|
|
3702
|
+
localMetadata: {
|
|
3703
|
+
...attachment.localMetadata,
|
|
3704
|
+
uploadState: "uploading",
|
|
3705
|
+
uploadProgress: nextUpload.uploadProgress
|
|
3706
|
+
}
|
|
3707
|
+
});
|
|
3708
|
+
}
|
|
3709
|
+
);
|
|
3710
|
+
return this.client.uploadManager.upload({
|
|
3711
|
+
id: localId,
|
|
3712
|
+
channelCid: this.channel.cid,
|
|
3713
|
+
file: attachment.localMetadata.file
|
|
3714
|
+
}).finally(() => {
|
|
3715
|
+
unsubscribe();
|
|
3716
|
+
});
|
|
3717
|
+
}
|
|
3726
3718
|
};
|
|
3727
3719
|
_AttachmentManager.toLocalUploadAttachment = (fileLike) => {
|
|
3728
3720
|
const file = isFileReference(fileLike) || isFile(fileLike) ? fileLike : createFileFromBlobs({
|
|
@@ -7575,9 +7567,6 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7575
7567
|
return this.state.getLatestValue().showReplyInChannel;
|
|
7576
7568
|
}
|
|
7577
7569
|
get hasSendableData() {
|
|
7578
|
-
if (this.client.offlineDb) {
|
|
7579
|
-
return !this.textComposer.textIsEmpty || !!this.attachmentManager.attachments.length || !!this.pollId || !!this.locationComposer.validLocation;
|
|
7580
|
-
}
|
|
7581
7570
|
return !!(!this.attachmentManager.uploadsInProgressCount && (!this.textComposer.textIsEmpty || this.attachmentManager.successfulUploadsCount > 0) || this.pollId || !!this.locationComposer.validLocation);
|
|
7582
7571
|
}
|
|
7583
7572
|
get compositionIsEmpty() {
|
|
@@ -10599,6 +10588,131 @@ var StableWSConnection = class {
|
|
|
10599
10588
|
}
|
|
10600
10589
|
};
|
|
10601
10590
|
|
|
10591
|
+
// src/uploadManager.ts
|
|
10592
|
+
var initState7 = () => ({ uploads: {} });
|
|
10593
|
+
var upsertById = (uploads, record) => ({
|
|
10594
|
+
...uploads,
|
|
10595
|
+
[record.id]: { ...uploads[record.id], ...record }
|
|
10596
|
+
});
|
|
10597
|
+
var updateById = (uploads, record) => {
|
|
10598
|
+
if (!(record.id in uploads)) return null;
|
|
10599
|
+
const current = uploads[record.id];
|
|
10600
|
+
return { ...uploads, [record.id]: { ...current, ...record } };
|
|
10601
|
+
};
|
|
10602
|
+
var UploadManager = class {
|
|
10603
|
+
constructor(client) {
|
|
10604
|
+
this.client = client;
|
|
10605
|
+
this.inFlightUploads = /* @__PURE__ */ new Map();
|
|
10606
|
+
this.getUpload = (id) => this.uploads[id];
|
|
10607
|
+
/**
|
|
10608
|
+
* Clears all upload records.
|
|
10609
|
+
* Invoked when the user disconnects so a later session does not inherit stale upload state.
|
|
10610
|
+
* Aborts every in-flight upload request via its `UploadRequestOptions.abortSignal`.
|
|
10611
|
+
*/
|
|
10612
|
+
this.reset = () => {
|
|
10613
|
+
for (const { abortController } of this.inFlightUploads.values()) {
|
|
10614
|
+
abortController.abort();
|
|
10615
|
+
}
|
|
10616
|
+
this.inFlightUploads.clear();
|
|
10617
|
+
this.state.next(initState7());
|
|
10618
|
+
};
|
|
10619
|
+
/**
|
|
10620
|
+
* Removes the upload record for `id` if present.
|
|
10621
|
+
* If an upload is still in progress, aborts its `UploadRequestOptions.abortSignal`.
|
|
10622
|
+
*/
|
|
10623
|
+
this.deleteUploadRecord = (id) => {
|
|
10624
|
+
const flight = this.inFlightUploads.get(id);
|
|
10625
|
+
if (flight) {
|
|
10626
|
+
this.inFlightUploads.delete(id);
|
|
10627
|
+
flight.abortController.abort();
|
|
10628
|
+
}
|
|
10629
|
+
this.state.next((current) => {
|
|
10630
|
+
if (!(id in current.uploads)) return current;
|
|
10631
|
+
const uploads = { ...current.uploads };
|
|
10632
|
+
delete uploads[id];
|
|
10633
|
+
return { ...current, uploads };
|
|
10634
|
+
});
|
|
10635
|
+
};
|
|
10636
|
+
/**
|
|
10637
|
+
* Starts an upload for `id`, or returns the existing in-flight promise if one is already running.
|
|
10638
|
+
* Uses {@link StreamChat.channel}(`channelCid`) → `messageComposer.attachmentManager.doUploadRequest`.
|
|
10639
|
+
* Resolves with that result; rejects if the upload rejects (the record is removed from state either way).
|
|
10640
|
+
*/
|
|
10641
|
+
this.upload = ({
|
|
10642
|
+
id,
|
|
10643
|
+
channelCid,
|
|
10644
|
+
file
|
|
10645
|
+
}) => {
|
|
10646
|
+
const existing = this.inFlightUploads.get(id);
|
|
10647
|
+
if (existing) return existing.promise;
|
|
10648
|
+
let resolvePromise;
|
|
10649
|
+
let rejectPromise;
|
|
10650
|
+
const promise = new Promise((resolve, reject) => {
|
|
10651
|
+
resolvePromise = resolve;
|
|
10652
|
+
rejectPromise = reject;
|
|
10653
|
+
});
|
|
10654
|
+
const abortController = new AbortController();
|
|
10655
|
+
this.inFlightUploads.set(id, { promise, abortController });
|
|
10656
|
+
void (async () => {
|
|
10657
|
+
const attachmentManager = this.resolveAttachmentManager(channelCid);
|
|
10658
|
+
const trackProgress = attachmentManager.config.trackUploadProgress;
|
|
10659
|
+
try {
|
|
10660
|
+
this.upsertUpload({
|
|
10661
|
+
id,
|
|
10662
|
+
uploadProgress: trackProgress ? 0 : void 0
|
|
10663
|
+
});
|
|
10664
|
+
const onProgress = trackProgress ? (progress) => {
|
|
10665
|
+
this.updateUpload({
|
|
10666
|
+
id,
|
|
10667
|
+
uploadProgress: progress
|
|
10668
|
+
});
|
|
10669
|
+
} : void 0;
|
|
10670
|
+
const uploadRequestOptions = {
|
|
10671
|
+
abortSignal: abortController.signal,
|
|
10672
|
+
...onProgress ? { onProgress } : {}
|
|
10673
|
+
};
|
|
10674
|
+
const response = await attachmentManager.doUploadRequest(
|
|
10675
|
+
file,
|
|
10676
|
+
uploadRequestOptions
|
|
10677
|
+
);
|
|
10678
|
+
resolvePromise(response);
|
|
10679
|
+
} catch (error) {
|
|
10680
|
+
rejectPromise(error);
|
|
10681
|
+
} finally {
|
|
10682
|
+
this.inFlightUploads.delete(id);
|
|
10683
|
+
this.deleteUploadRecord(id);
|
|
10684
|
+
}
|
|
10685
|
+
})();
|
|
10686
|
+
return promise;
|
|
10687
|
+
};
|
|
10688
|
+
this.upsertUpload = (record) => {
|
|
10689
|
+
this.state.partialNext({
|
|
10690
|
+
uploads: upsertById(this.uploads, record)
|
|
10691
|
+
});
|
|
10692
|
+
};
|
|
10693
|
+
this.updateUpload = (record) => {
|
|
10694
|
+
this.state.next((current) => {
|
|
10695
|
+
const nextUploads = updateById(current.uploads, record);
|
|
10696
|
+
if (!nextUploads) return current;
|
|
10697
|
+
return { ...current, uploads: nextUploads };
|
|
10698
|
+
});
|
|
10699
|
+
};
|
|
10700
|
+
this.state = new StateStore(initState7());
|
|
10701
|
+
}
|
|
10702
|
+
resolveAttachmentManager(channelCid) {
|
|
10703
|
+
const colon = channelCid.indexOf(":");
|
|
10704
|
+
if (colon <= 0 || colon === channelCid.length - 1) {
|
|
10705
|
+
throw new Error(`Invalid channelCid: ${channelCid}`);
|
|
10706
|
+
}
|
|
10707
|
+
const channelType = channelCid.slice(0, colon);
|
|
10708
|
+
const channelId = channelCid.slice(colon + 1);
|
|
10709
|
+
return this.client.channel(channelType, channelId).messageComposer.attachmentManager;
|
|
10710
|
+
}
|
|
10711
|
+
get uploads() {
|
|
10712
|
+
return this.state.getLatestValue().uploads;
|
|
10713
|
+
}
|
|
10714
|
+
};
|
|
10715
|
+
|
|
10602
10716
|
// src/signing.ts
|
|
10603
10717
|
var import_jsonwebtoken = __toESM(require_jsonwebtoken());
|
|
10604
10718
|
var import_crypto = __toESM(require_crypto());
|
|
@@ -13071,6 +13185,7 @@ var StreamChat = class _StreamChat {
|
|
|
13071
13185
|
this.activeChannels = {};
|
|
13072
13186
|
this.state = new ClientState({ client: this });
|
|
13073
13187
|
this.threads.resetState();
|
|
13188
|
+
this.uploadManager.reset();
|
|
13074
13189
|
closePromise.finally(() => {
|
|
13075
13190
|
this.tokenManager.reset();
|
|
13076
13191
|
}).catch((err) => console.error(err));
|
|
@@ -13477,6 +13592,7 @@ var StreamChat = class _StreamChat {
|
|
|
13477
13592
|
this.blockedUsers = new StateStore({ userIds: [] });
|
|
13478
13593
|
this.moderation = new Moderation(this);
|
|
13479
13594
|
this.notifications = options?.notifications ?? new NotificationManager();
|
|
13595
|
+
this.uploadManager = new UploadManager(this);
|
|
13480
13596
|
if (secretOrOptions && isString2(secretOrOptions)) {
|
|
13481
13597
|
this.secret = secretOrOptions;
|
|
13482
13598
|
}
|
|
@@ -15266,7 +15382,7 @@ var StreamChat = class _StreamChat {
|
|
|
15266
15382
|
if (this.userAgent) {
|
|
15267
15383
|
return this.userAgent;
|
|
15268
15384
|
}
|
|
15269
|
-
const version = "9.
|
|
15385
|
+
const version = "9.42.1";
|
|
15270
15386
|
const clientBundle = "browser-cjs";
|
|
15271
15387
|
let userAgentString = "";
|
|
15272
15388
|
if (this.sdkIdentifier) {
|