stream-chat 9.13.0 → 9.14.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.cjs +412 -182
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +1846 -439
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +412 -182
- package/dist/esm/index.js.map +4 -4
- package/dist/types/messageComposer/attachmentManager.d.ts +11 -3
- package/dist/types/messageComposer/configuration/types.d.ts +1 -1
- package/dist/types/messageComposer/middleware/attachmentManager/index.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.d.ts +5 -0
- package/dist/types/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.d.ts +2 -0
- package/dist/types/messageComposer/middleware/attachmentManager/postUpload/index.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.d.ts +5 -0
- package/dist/types/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/preUpload/index.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.d.ts +3 -0
- package/dist/types/messageComposer/middleware/attachmentManager/types.d.ts +20 -0
- package/dist/types/messageComposer/types.d.ts +1 -0
- package/dist/types/middleware.d.ts +3 -2
- package/package.json +2 -2
- package/src/messageComposer/attachmentManager.ts +116 -25
- package/src/messageComposer/configuration/types.ts +3 -2
- package/src/messageComposer/messageComposer.ts +1 -1
- package/src/messageComposer/middleware/attachmentManager/index.ts +3 -0
- package/src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts +20 -0
- package/src/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.ts +43 -0
- package/src/messageComposer/middleware/attachmentManager/postUpload/index.ts +3 -0
- package/src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts +39 -0
- package/src/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.ts +20 -0
- package/src/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.ts +38 -0
- package/src/messageComposer/middleware/attachmentManager/preUpload/index.ts +3 -0
- package/src/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.ts +40 -0
- package/src/messageComposer/middleware/attachmentManager/types.ts +32 -0
- package/src/messageComposer/types.ts +6 -0
- package/src/middleware.ts +22 -10
- package/src/utils.ts +5 -1
|
@@ -140,7 +140,8 @@ var require_https = __commonJS({
|
|
|
140
140
|
// node_modules/form-data/lib/browser.js
|
|
141
141
|
var require_browser = __commonJS({
|
|
142
142
|
"node_modules/form-data/lib/browser.js"(exports, module2) {
|
|
143
|
-
|
|
143
|
+
"use strict";
|
|
144
|
+
module2.exports = typeof self === "object" ? self.FormData : window.FormData;
|
|
144
145
|
}
|
|
145
146
|
});
|
|
146
147
|
|
|
@@ -3151,7 +3152,8 @@ var messagePaginationLinear = ({
|
|
|
3151
3152
|
return newPagination;
|
|
3152
3153
|
};
|
|
3153
3154
|
var messageSetPagination = (params) => {
|
|
3154
|
-
|
|
3155
|
+
const messagesFilteredLocally = params.returnedPage.filter(({ shadowed }) => shadowed);
|
|
3156
|
+
if (params.parentSet.messages.length + messagesFilteredLocally.length < params.returnedPage.length) {
|
|
3155
3157
|
params.logger?.(
|
|
3156
3158
|
"error",
|
|
3157
3159
|
"Corrupted message set state: parent set size < returned page size"
|
|
@@ -4088,6 +4090,294 @@ var ensureIsLocalAttachment = (attachment) => {
|
|
|
4088
4090
|
};
|
|
4089
4091
|
};
|
|
4090
4092
|
|
|
4093
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/attachmentEnrichment.ts
|
|
4094
|
+
var createPostUploadAttachmentEnrichmentMiddleware = () => ({
|
|
4095
|
+
id: "stream-io/attachment-manager-middleware/post-upload-enrichment",
|
|
4096
|
+
handlers: {
|
|
4097
|
+
postProcess: ({
|
|
4098
|
+
state,
|
|
4099
|
+
discard,
|
|
4100
|
+
forward,
|
|
4101
|
+
next
|
|
4102
|
+
}) => {
|
|
4103
|
+
const { attachment, error, response } = state;
|
|
4104
|
+
if (error) return forward();
|
|
4105
|
+
if (!attachment || !response) return discard();
|
|
4106
|
+
const enrichedAttachment = { ...attachment };
|
|
4107
|
+
if (isLocalImageAttachment(attachment)) {
|
|
4108
|
+
if (attachment.localMetadata.previewUri) {
|
|
4109
|
+
URL.revokeObjectURL(attachment.localMetadata.previewUri);
|
|
4110
|
+
delete enrichedAttachment.localMetadata.previewUri;
|
|
4111
|
+
}
|
|
4112
|
+
enrichedAttachment.image_url = response.file;
|
|
4113
|
+
} else {
|
|
4114
|
+
enrichedAttachment.asset_url = response.file;
|
|
4115
|
+
}
|
|
4116
|
+
if (response.thumb_url) {
|
|
4117
|
+
enrichedAttachment.thumb_url = response.thumb_url;
|
|
4118
|
+
}
|
|
4119
|
+
return next({
|
|
4120
|
+
...state,
|
|
4121
|
+
attachment: enrichedAttachment
|
|
4122
|
+
});
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
});
|
|
4126
|
+
|
|
4127
|
+
// src/utils/concurrency.ts
|
|
4128
|
+
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
4129
|
+
var withCancellation = createRunner(wrapWithCancellation);
|
|
4130
|
+
var pendingPromises = /* @__PURE__ */ new Map();
|
|
4131
|
+
function createRunner(wrapper) {
|
|
4132
|
+
return function run(tag, cb) {
|
|
4133
|
+
const { cb: wrapped, onContinued } = wrapper(tag, cb);
|
|
4134
|
+
const pending = pendingPromises.get(tag);
|
|
4135
|
+
pending?.onContinued();
|
|
4136
|
+
const promise = pending ? pending.promise.then(wrapped, wrapped) : wrapped();
|
|
4137
|
+
pendingPromises.set(tag, { promise, onContinued });
|
|
4138
|
+
return promise;
|
|
4139
|
+
};
|
|
4140
|
+
}
|
|
4141
|
+
function wrapWithContinuationTracking(tag, cb) {
|
|
4142
|
+
let hasContinuation = false;
|
|
4143
|
+
const wrapped = () => cb().finally(() => {
|
|
4144
|
+
if (!hasContinuation) {
|
|
4145
|
+
pendingPromises.delete(tag);
|
|
4146
|
+
}
|
|
4147
|
+
});
|
|
4148
|
+
const onContinued = () => hasContinuation = true;
|
|
4149
|
+
return { cb: wrapped, onContinued };
|
|
4150
|
+
}
|
|
4151
|
+
function wrapWithCancellation(tag, cb) {
|
|
4152
|
+
const ac = new AbortController();
|
|
4153
|
+
const wrapped = () => {
|
|
4154
|
+
if (ac.signal.aborted) {
|
|
4155
|
+
return Promise.resolve("canceled");
|
|
4156
|
+
}
|
|
4157
|
+
return cb(ac.signal).finally(() => {
|
|
4158
|
+
if (!ac.signal.aborted) {
|
|
4159
|
+
pendingPromises.delete(tag);
|
|
4160
|
+
}
|
|
4161
|
+
});
|
|
4162
|
+
};
|
|
4163
|
+
const onContinued = () => ac.abort();
|
|
4164
|
+
return { cb: wrapped, onContinued };
|
|
4165
|
+
}
|
|
4166
|
+
|
|
4167
|
+
// src/middleware.ts
|
|
4168
|
+
var MiddlewareExecutor = class {
|
|
4169
|
+
constructor() {
|
|
4170
|
+
this.middleware = [];
|
|
4171
|
+
this.id = generateUUIDv4();
|
|
4172
|
+
}
|
|
4173
|
+
use(middleware) {
|
|
4174
|
+
this.middleware = this.middleware.concat(middleware);
|
|
4175
|
+
return this;
|
|
4176
|
+
}
|
|
4177
|
+
// todo: document how to re-arrange the order of middleware using replace
|
|
4178
|
+
replace(middleware) {
|
|
4179
|
+
const newMiddleware = [...this.middleware];
|
|
4180
|
+
middleware.forEach((upserted) => {
|
|
4181
|
+
const existingIndex = this.middleware.findIndex(
|
|
4182
|
+
(existing) => existing.id === upserted.id
|
|
4183
|
+
);
|
|
4184
|
+
if (existingIndex >= 0) {
|
|
4185
|
+
newMiddleware.splice(existingIndex, 1, upserted);
|
|
4186
|
+
} else {
|
|
4187
|
+
newMiddleware.push(upserted);
|
|
4188
|
+
}
|
|
4189
|
+
});
|
|
4190
|
+
this.middleware = newMiddleware;
|
|
4191
|
+
return this;
|
|
4192
|
+
}
|
|
4193
|
+
insert({
|
|
4194
|
+
middleware,
|
|
4195
|
+
position,
|
|
4196
|
+
unique
|
|
4197
|
+
}) {
|
|
4198
|
+
if (unique) {
|
|
4199
|
+
middleware.forEach((md) => {
|
|
4200
|
+
const existingMiddlewareIndex = this.middleware.findIndex((m) => m.id === md.id);
|
|
4201
|
+
if (existingMiddlewareIndex >= 0) {
|
|
4202
|
+
this.middleware.splice(existingMiddlewareIndex, 1);
|
|
4203
|
+
}
|
|
4204
|
+
});
|
|
4205
|
+
}
|
|
4206
|
+
const targetId = position.after || position.before;
|
|
4207
|
+
const targetIndex = this.middleware.findIndex((m) => m.id === targetId);
|
|
4208
|
+
const insertionIndex = position.after ? targetIndex + 1 : targetIndex;
|
|
4209
|
+
this.middleware.splice(insertionIndex, 0, ...middleware);
|
|
4210
|
+
return this;
|
|
4211
|
+
}
|
|
4212
|
+
setOrder(order) {
|
|
4213
|
+
this.middleware = order.map((id) => this.middleware.find((middleware) => middleware.id === id)).filter(Boolean);
|
|
4214
|
+
}
|
|
4215
|
+
async executeMiddlewareChain({
|
|
4216
|
+
eventName,
|
|
4217
|
+
initialValue,
|
|
4218
|
+
mode = "cancelable"
|
|
4219
|
+
}) {
|
|
4220
|
+
let index = -1;
|
|
4221
|
+
const execute = async (i, state, status) => {
|
|
4222
|
+
if (i <= index) {
|
|
4223
|
+
throw new Error("next() called multiple times");
|
|
4224
|
+
}
|
|
4225
|
+
index = i;
|
|
4226
|
+
const returnFromChain = i === this.middleware.length || status && ["complete", "discard"].includes(status);
|
|
4227
|
+
if (returnFromChain) return { state, status };
|
|
4228
|
+
const middleware = this.middleware[i];
|
|
4229
|
+
const handler = middleware.handlers[eventName];
|
|
4230
|
+
if (!handler) {
|
|
4231
|
+
return execute(i + 1, state, status);
|
|
4232
|
+
}
|
|
4233
|
+
const next = (adjustedState) => execute(i + 1, adjustedState);
|
|
4234
|
+
const complete = (adjustedState) => execute(i + 1, adjustedState, "complete");
|
|
4235
|
+
const discard = () => execute(i + 1, state, "discard");
|
|
4236
|
+
const forward = () => execute(i + 1, state);
|
|
4237
|
+
return await handler({
|
|
4238
|
+
state,
|
|
4239
|
+
next,
|
|
4240
|
+
complete,
|
|
4241
|
+
discard,
|
|
4242
|
+
forward
|
|
4243
|
+
});
|
|
4244
|
+
};
|
|
4245
|
+
const result = mode === "cancelable" ? await withCancellation(
|
|
4246
|
+
`middleware-execution-${this.id}-${eventName}`,
|
|
4247
|
+
async (abortSignal) => {
|
|
4248
|
+
const result2 = await execute(0, initialValue);
|
|
4249
|
+
if (abortSignal.aborted) {
|
|
4250
|
+
return "canceled";
|
|
4251
|
+
}
|
|
4252
|
+
return result2;
|
|
4253
|
+
}
|
|
4254
|
+
) : await execute(0, initialValue);
|
|
4255
|
+
return result === "canceled" ? { state: initialValue, status: "discard" } : result;
|
|
4256
|
+
}
|
|
4257
|
+
async execute({
|
|
4258
|
+
eventName,
|
|
4259
|
+
initialValue: initialState,
|
|
4260
|
+
mode
|
|
4261
|
+
}) {
|
|
4262
|
+
return await this.executeMiddlewareChain({
|
|
4263
|
+
eventName,
|
|
4264
|
+
initialValue: initialState,
|
|
4265
|
+
mode
|
|
4266
|
+
});
|
|
4267
|
+
}
|
|
4268
|
+
};
|
|
4269
|
+
|
|
4270
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts
|
|
4271
|
+
var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
4272
|
+
id: "stream-io/attachment-manager-middleware/upload-error",
|
|
4273
|
+
handlers: {
|
|
4274
|
+
postProcess: ({
|
|
4275
|
+
state,
|
|
4276
|
+
discard,
|
|
4277
|
+
forward
|
|
4278
|
+
}) => {
|
|
4279
|
+
const { attachment, error } = state;
|
|
4280
|
+
if (!error) return forward();
|
|
4281
|
+
if (!attachment) return discard();
|
|
4282
|
+
const reason = error instanceof Error ? error.message : "unknown error";
|
|
4283
|
+
composer.client.notifications.addError({
|
|
4284
|
+
message: "Error uploading attachment",
|
|
4285
|
+
origin: {
|
|
4286
|
+
emitter: "AttachmentManager",
|
|
4287
|
+
context: { attachment }
|
|
4288
|
+
},
|
|
4289
|
+
options: {
|
|
4290
|
+
type: "api:attachment:upload:failed",
|
|
4291
|
+
metadata: { reason },
|
|
4292
|
+
originalError: error
|
|
4293
|
+
}
|
|
4294
|
+
});
|
|
4295
|
+
return forward();
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4298
|
+
});
|
|
4299
|
+
|
|
4300
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts
|
|
4301
|
+
var AttachmentPostUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
4302
|
+
constructor({ composer }) {
|
|
4303
|
+
super();
|
|
4304
|
+
this.use([
|
|
4305
|
+
createUploadErrorHandlerMiddleware(composer),
|
|
4306
|
+
createPostUploadAttachmentEnrichmentMiddleware()
|
|
4307
|
+
]);
|
|
4308
|
+
}
|
|
4309
|
+
};
|
|
4310
|
+
|
|
4311
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.ts
|
|
4312
|
+
var createUploadConfigCheckMiddleware = (composer) => ({
|
|
4313
|
+
id: "stream-io/attachment-manager-middleware/file-upload-config-check",
|
|
4314
|
+
handlers: {
|
|
4315
|
+
prepare: async ({
|
|
4316
|
+
state,
|
|
4317
|
+
next,
|
|
4318
|
+
discard
|
|
4319
|
+
}) => {
|
|
4320
|
+
const { attachmentManager } = composer;
|
|
4321
|
+
if (!attachmentManager || !state.attachment) return discard();
|
|
4322
|
+
const uploadPermissionCheck = await attachmentManager.getUploadConfigCheck(
|
|
4323
|
+
state.attachment.localMetadata.file
|
|
4324
|
+
);
|
|
4325
|
+
const attachment = {
|
|
4326
|
+
...state.attachment,
|
|
4327
|
+
localMetadata: {
|
|
4328
|
+
...state.attachment.localMetadata,
|
|
4329
|
+
uploadPermissionCheck,
|
|
4330
|
+
uploadState: uploadPermissionCheck.uploadBlocked ? "blocked" : "pending"
|
|
4331
|
+
}
|
|
4332
|
+
};
|
|
4333
|
+
return next({
|
|
4334
|
+
...state,
|
|
4335
|
+
attachment
|
|
4336
|
+
});
|
|
4337
|
+
}
|
|
4338
|
+
}
|
|
4339
|
+
});
|
|
4340
|
+
|
|
4341
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.ts
|
|
4342
|
+
var createBlockedAttachmentUploadNotificationMiddleware = (composer) => ({
|
|
4343
|
+
id: "stream-io/attachment-manager-middleware/blocked-upload-notification",
|
|
4344
|
+
handlers: {
|
|
4345
|
+
prepare: ({
|
|
4346
|
+
state: { attachment },
|
|
4347
|
+
forward
|
|
4348
|
+
}) => {
|
|
4349
|
+
if (!attachment) return forward();
|
|
4350
|
+
if (attachment.localMetadata.uploadPermissionCheck?.uploadBlocked) {
|
|
4351
|
+
composer.client.notifications.addError({
|
|
4352
|
+
message: `The attachment upload was blocked`,
|
|
4353
|
+
origin: {
|
|
4354
|
+
emitter: "AttachmentManager",
|
|
4355
|
+
context: { blockedAttachment: attachment }
|
|
4356
|
+
},
|
|
4357
|
+
options: {
|
|
4358
|
+
type: "validation:attachment:upload:blocked",
|
|
4359
|
+
metadata: {
|
|
4360
|
+
reason: attachment.localMetadata.uploadPermissionCheck?.reason
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
});
|
|
4364
|
+
}
|
|
4365
|
+
return forward();
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
});
|
|
4369
|
+
|
|
4370
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.ts
|
|
4371
|
+
var AttachmentPreUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
4372
|
+
constructor({ composer }) {
|
|
4373
|
+
super();
|
|
4374
|
+
this.use([
|
|
4375
|
+
createUploadConfigCheckMiddleware(composer),
|
|
4376
|
+
createBlockedAttachmentUploadNotificationMiddleware(composer)
|
|
4377
|
+
]);
|
|
4378
|
+
}
|
|
4379
|
+
};
|
|
4380
|
+
|
|
4091
4381
|
// src/store.ts
|
|
4092
4382
|
var isPatch = (value) => typeof value === "function";
|
|
4093
4383
|
var noop2 = () => {
|
|
@@ -4679,7 +4969,7 @@ var initState = ({
|
|
|
4679
4969
|
};
|
|
4680
4970
|
})
|
|
4681
4971
|
});
|
|
4682
|
-
var
|
|
4972
|
+
var _AttachmentManager = class _AttachmentManager {
|
|
4683
4973
|
constructor({ composer, message }) {
|
|
4684
4974
|
this.setCustomUploadFn = (doUploadRequest) => {
|
|
4685
4975
|
this.composer.updateConfig({ attachments: { doUploadRequest } });
|
|
@@ -4786,42 +5076,18 @@ var AttachmentManager = class {
|
|
|
4786
5076
|
}
|
|
4787
5077
|
return { uploadBlocked: false };
|
|
4788
5078
|
};
|
|
5079
|
+
// @deprecated use AttachmentManager.toLocalUploadAttachment(file)
|
|
4789
5080
|
this.fileToLocalUploadAttachment = async (fileLike) => {
|
|
4790
|
-
const
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
const localAttachment = {
|
|
4797
|
-
file_size: file.size,
|
|
4798
|
-
mime_type: file.type,
|
|
4799
|
-
localMetadata: {
|
|
4800
|
-
file,
|
|
4801
|
-
id: generateUUIDv4(),
|
|
4802
|
-
uploadPermissionCheck,
|
|
4803
|
-
uploadState: uploadPermissionCheck.uploadBlocked ? "blocked" : "pending"
|
|
4804
|
-
},
|
|
4805
|
-
type: getAttachmentTypeFromMimeType(file.type)
|
|
4806
|
-
};
|
|
4807
|
-
localAttachment[isImageFile(file) ? "fallback" : "title"] = file.name;
|
|
4808
|
-
if (isImageFile(file)) {
|
|
4809
|
-
localAttachment.localMetadata.previewUri = isFileReference(fileLike) ? fileLike.uri : URL.createObjectURL?.(fileLike);
|
|
4810
|
-
if (isFileReference(fileLike) && fileLike.height && fileLike.width) {
|
|
4811
|
-
localAttachment.original_height = fileLike.height;
|
|
4812
|
-
localAttachment.original_width = fileLike.width;
|
|
4813
|
-
}
|
|
4814
|
-
}
|
|
4815
|
-
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
4816
|
-
localAttachment.thumb_url = fileLike.thumb_url;
|
|
4817
|
-
}
|
|
4818
|
-
if (isFileReference(fileLike) && fileLike.duration) {
|
|
4819
|
-
localAttachment.duration = fileLike.duration;
|
|
4820
|
-
}
|
|
5081
|
+
const localAttachment = _AttachmentManager.toLocalUploadAttachment(fileLike);
|
|
5082
|
+
const uploadPermissionCheck = await this.getUploadConfigCheck(
|
|
5083
|
+
localAttachment.localMetadata.file
|
|
5084
|
+
);
|
|
5085
|
+
localAttachment.localMetadata.uploadPermissionCheck = uploadPermissionCheck;
|
|
5086
|
+
localAttachment.localMetadata.uploadState = uploadPermissionCheck.uploadBlocked ? "blocked" : "pending";
|
|
4821
5087
|
return localAttachment;
|
|
4822
5088
|
};
|
|
4823
5089
|
this.ensureLocalUploadAttachment = async (attachment) => {
|
|
4824
|
-
if (!attachment.localMetadata?.file
|
|
5090
|
+
if (!attachment.localMetadata?.file) {
|
|
4825
5091
|
this.client.notifications.addError({
|
|
4826
5092
|
message: "File is required for upload attachment",
|
|
4827
5093
|
origin: { emitter: "AttachmentManager", context: { attachment } },
|
|
@@ -4829,6 +5095,14 @@ var AttachmentManager = class {
|
|
|
4829
5095
|
});
|
|
4830
5096
|
return;
|
|
4831
5097
|
}
|
|
5098
|
+
if (!attachment.localMetadata.id) {
|
|
5099
|
+
this.client.notifications.addError({
|
|
5100
|
+
message: "Local upload attachment missing local id",
|
|
5101
|
+
origin: { emitter: "AttachmentManager", context: { attachment } },
|
|
5102
|
+
options: { type: "validation:attachment:id:missing" }
|
|
5103
|
+
});
|
|
5104
|
+
return;
|
|
5105
|
+
}
|
|
4832
5106
|
if (!this.fileUploadFilter(attachment)) return;
|
|
4833
5107
|
const newAttachment = await this.fileToLocalUploadAttachment(
|
|
4834
5108
|
attachment.localMetadata.file
|
|
@@ -4868,6 +5142,7 @@ var AttachmentManager = class {
|
|
|
4868
5142
|
}
|
|
4869
5143
|
return this.doDefaultUploadRequest(fileLike);
|
|
4870
5144
|
};
|
|
5145
|
+
// @deprecated use attachmentManager.uploadFile(file)
|
|
4871
5146
|
this.uploadAttachment = async (attachment) => {
|
|
4872
5147
|
if (!this.isUploadEnabled) return;
|
|
4873
5148
|
const localAttachment = await this.ensureLocalUploadAttachment(attachment);
|
|
@@ -4951,19 +5226,75 @@ var AttachmentManager = class {
|
|
|
4951
5226
|
this.updateAttachment(uploadedAttachment);
|
|
4952
5227
|
return uploadedAttachment;
|
|
4953
5228
|
};
|
|
5229
|
+
this.uploadFile = async (file) => {
|
|
5230
|
+
const preUpload = await this.preUploadMiddlewareExecutor.execute({
|
|
5231
|
+
eventName: "prepare",
|
|
5232
|
+
initialValue: {
|
|
5233
|
+
attachment: _AttachmentManager.toLocalUploadAttachment(file)
|
|
5234
|
+
},
|
|
5235
|
+
mode: "concurrent"
|
|
5236
|
+
});
|
|
5237
|
+
let attachment = preUpload.state.attachment;
|
|
5238
|
+
if (preUpload.status === "discard") return attachment;
|
|
5239
|
+
if (!this.fileUploadFilter(attachment)) return attachment;
|
|
5240
|
+
if (attachment.localMetadata.uploadState === "blocked") {
|
|
5241
|
+
this.upsertAttachments([attachment]);
|
|
5242
|
+
return preUpload.state.attachment;
|
|
5243
|
+
}
|
|
5244
|
+
attachment = {
|
|
5245
|
+
...attachment,
|
|
5246
|
+
localMetadata: {
|
|
5247
|
+
...attachment.localMetadata,
|
|
5248
|
+
uploadState: "uploading"
|
|
5249
|
+
}
|
|
5250
|
+
};
|
|
5251
|
+
this.upsertAttachments([attachment]);
|
|
5252
|
+
let response;
|
|
5253
|
+
let error;
|
|
5254
|
+
try {
|
|
5255
|
+
response = await this.doUploadRequest(file);
|
|
5256
|
+
} catch (err) {
|
|
5257
|
+
error = err instanceof Error ? err : void 0;
|
|
5258
|
+
}
|
|
5259
|
+
const postUpload = await this.postUploadMiddlewareExecutor.execute({
|
|
5260
|
+
eventName: "postProcess",
|
|
5261
|
+
initialValue: {
|
|
5262
|
+
attachment: {
|
|
5263
|
+
...attachment,
|
|
5264
|
+
localMetadata: {
|
|
5265
|
+
...attachment.localMetadata,
|
|
5266
|
+
uploadState: error ? "failed" : "finished"
|
|
5267
|
+
}
|
|
5268
|
+
},
|
|
5269
|
+
error,
|
|
5270
|
+
response
|
|
5271
|
+
},
|
|
5272
|
+
mode: "concurrent"
|
|
5273
|
+
});
|
|
5274
|
+
attachment = postUpload.state.attachment;
|
|
5275
|
+
if (postUpload.status === "discard") {
|
|
5276
|
+
this.removeAttachments([attachment.localMetadata.id]);
|
|
5277
|
+
return attachment;
|
|
5278
|
+
}
|
|
5279
|
+
this.updateAttachment(attachment);
|
|
5280
|
+
return attachment;
|
|
5281
|
+
};
|
|
4954
5282
|
this.uploadFiles = async (files) => {
|
|
4955
5283
|
if (!this.isUploadEnabled) return;
|
|
4956
5284
|
const iterableFiles = isFileList2(files) ? Array.from(files) : files;
|
|
4957
|
-
|
|
4958
|
-
iterableFiles.map(this.
|
|
4959
|
-
);
|
|
4960
|
-
return Promise.all(
|
|
4961
|
-
attachments.filter(this.fileUploadFilter).slice(0, this.availableUploadSlots).map(this.uploadAttachment)
|
|
5285
|
+
return await Promise.all(
|
|
5286
|
+
iterableFiles.slice(0, this.availableUploadSlots).map(this.uploadFile)
|
|
4962
5287
|
);
|
|
4963
5288
|
};
|
|
4964
5289
|
this.composer = composer;
|
|
4965
5290
|
this.state = new StateStore(initState({ message }));
|
|
4966
5291
|
this.attachmentsByIdGetterCache = { attachmentsById: {}, attachments: [] };
|
|
5292
|
+
this.preUploadMiddlewareExecutor = new AttachmentPreUploadMiddlewareExecutor({
|
|
5293
|
+
composer
|
|
5294
|
+
});
|
|
5295
|
+
this.postUploadMiddlewareExecutor = new AttachmentPostUploadMiddlewareExecutor({
|
|
5296
|
+
composer
|
|
5297
|
+
});
|
|
4967
5298
|
}
|
|
4968
5299
|
get attachmentsById() {
|
|
4969
5300
|
const { attachments } = this.state.getLatestValue();
|
|
@@ -4993,9 +5324,15 @@ var AttachmentManager = class {
|
|
|
4993
5324
|
set acceptedFiles(acceptedFiles) {
|
|
4994
5325
|
this.composer.updateConfig({ attachments: { acceptedFiles } });
|
|
4995
5326
|
}
|
|
5327
|
+
/*
|
|
5328
|
+
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
5329
|
+
*/
|
|
4996
5330
|
get fileUploadFilter() {
|
|
4997
5331
|
return this.config.fileUploadFilter;
|
|
4998
5332
|
}
|
|
5333
|
+
/*
|
|
5334
|
+
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
5335
|
+
*/
|
|
4999
5336
|
set fileUploadFilter(fileUploadFilter) {
|
|
5000
5337
|
this.composer.updateConfig({ attachments: { fileUploadFilter } });
|
|
5001
5338
|
}
|
|
@@ -5042,6 +5379,39 @@ var AttachmentManager = class {
|
|
|
5042
5379
|
);
|
|
5043
5380
|
}
|
|
5044
5381
|
};
|
|
5382
|
+
_AttachmentManager.toLocalUploadAttachment = (fileLike) => {
|
|
5383
|
+
const file = isFileReference(fileLike) || isFile2(fileLike) ? fileLike : createFileFromBlobs({
|
|
5384
|
+
blobsArray: [fileLike],
|
|
5385
|
+
fileName: generateFileName(fileLike.type),
|
|
5386
|
+
mimeType: fileLike.type
|
|
5387
|
+
});
|
|
5388
|
+
const localAttachment = {
|
|
5389
|
+
file_size: file.size,
|
|
5390
|
+
mime_type: file.type,
|
|
5391
|
+
localMetadata: {
|
|
5392
|
+
file,
|
|
5393
|
+
id: generateUUIDv4(),
|
|
5394
|
+
uploadState: "pending"
|
|
5395
|
+
},
|
|
5396
|
+
type: getAttachmentTypeFromMimeType(file.type)
|
|
5397
|
+
};
|
|
5398
|
+
localAttachment[isImageFile(file) ? "fallback" : "title"] = file.name;
|
|
5399
|
+
if (isImageFile(file)) {
|
|
5400
|
+
localAttachment.localMetadata.previewUri = isFileReference(fileLike) ? fileLike.uri : URL.createObjectURL?.(fileLike);
|
|
5401
|
+
if (isFileReference(fileLike) && fileLike.height && fileLike.width) {
|
|
5402
|
+
localAttachment.original_height = fileLike.height;
|
|
5403
|
+
localAttachment.original_width = fileLike.width;
|
|
5404
|
+
}
|
|
5405
|
+
}
|
|
5406
|
+
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
5407
|
+
localAttachment.thumb_url = fileLike.thumb_url;
|
|
5408
|
+
}
|
|
5409
|
+
if (isFileReference(fileLike) && fileLike.duration) {
|
|
5410
|
+
localAttachment.duration = fileLike.duration;
|
|
5411
|
+
}
|
|
5412
|
+
return localAttachment;
|
|
5413
|
+
};
|
|
5414
|
+
var AttachmentManager = _AttachmentManager;
|
|
5045
5415
|
|
|
5046
5416
|
// src/messageComposer/configuration/configuration.ts
|
|
5047
5417
|
var import_linkifyjs = require("linkifyjs");
|
|
@@ -5381,146 +5751,6 @@ var LocationComposer = class {
|
|
|
5381
5751
|
}
|
|
5382
5752
|
};
|
|
5383
5753
|
|
|
5384
|
-
// src/utils/concurrency.ts
|
|
5385
|
-
var withoutConcurrency = createRunner(wrapWithContinuationTracking);
|
|
5386
|
-
var withCancellation = createRunner(wrapWithCancellation);
|
|
5387
|
-
var pendingPromises = /* @__PURE__ */ new Map();
|
|
5388
|
-
function createRunner(wrapper) {
|
|
5389
|
-
return function run(tag, cb) {
|
|
5390
|
-
const { cb: wrapped, onContinued } = wrapper(tag, cb);
|
|
5391
|
-
const pending = pendingPromises.get(tag);
|
|
5392
|
-
pending?.onContinued();
|
|
5393
|
-
const promise = pending ? pending.promise.then(wrapped, wrapped) : wrapped();
|
|
5394
|
-
pendingPromises.set(tag, { promise, onContinued });
|
|
5395
|
-
return promise;
|
|
5396
|
-
};
|
|
5397
|
-
}
|
|
5398
|
-
function wrapWithContinuationTracking(tag, cb) {
|
|
5399
|
-
let hasContinuation = false;
|
|
5400
|
-
const wrapped = () => cb().finally(() => {
|
|
5401
|
-
if (!hasContinuation) {
|
|
5402
|
-
pendingPromises.delete(tag);
|
|
5403
|
-
}
|
|
5404
|
-
});
|
|
5405
|
-
const onContinued = () => hasContinuation = true;
|
|
5406
|
-
return { cb: wrapped, onContinued };
|
|
5407
|
-
}
|
|
5408
|
-
function wrapWithCancellation(tag, cb) {
|
|
5409
|
-
const ac = new AbortController();
|
|
5410
|
-
const wrapped = () => {
|
|
5411
|
-
if (ac.signal.aborted) {
|
|
5412
|
-
return Promise.resolve("canceled");
|
|
5413
|
-
}
|
|
5414
|
-
return cb(ac.signal).finally(() => {
|
|
5415
|
-
if (!ac.signal.aborted) {
|
|
5416
|
-
pendingPromises.delete(tag);
|
|
5417
|
-
}
|
|
5418
|
-
});
|
|
5419
|
-
};
|
|
5420
|
-
const onContinued = () => ac.abort();
|
|
5421
|
-
return { cb: wrapped, onContinued };
|
|
5422
|
-
}
|
|
5423
|
-
|
|
5424
|
-
// src/middleware.ts
|
|
5425
|
-
var MiddlewareExecutor = class {
|
|
5426
|
-
constructor() {
|
|
5427
|
-
this.middleware = [];
|
|
5428
|
-
this.id = generateUUIDv4();
|
|
5429
|
-
}
|
|
5430
|
-
use(middleware) {
|
|
5431
|
-
this.middleware = this.middleware.concat(middleware);
|
|
5432
|
-
return this;
|
|
5433
|
-
}
|
|
5434
|
-
// todo: document how to re-arrange the order of middleware using replace
|
|
5435
|
-
replace(middleware) {
|
|
5436
|
-
const newMiddleware = [...this.middleware];
|
|
5437
|
-
middleware.forEach((upserted) => {
|
|
5438
|
-
const existingIndex = this.middleware.findIndex(
|
|
5439
|
-
(existing) => existing.id === upserted.id
|
|
5440
|
-
);
|
|
5441
|
-
if (existingIndex >= 0) {
|
|
5442
|
-
newMiddleware.splice(existingIndex, 1, upserted);
|
|
5443
|
-
} else {
|
|
5444
|
-
newMiddleware.push(upserted);
|
|
5445
|
-
}
|
|
5446
|
-
});
|
|
5447
|
-
this.middleware = newMiddleware;
|
|
5448
|
-
return this;
|
|
5449
|
-
}
|
|
5450
|
-
insert({
|
|
5451
|
-
middleware,
|
|
5452
|
-
position,
|
|
5453
|
-
unique
|
|
5454
|
-
}) {
|
|
5455
|
-
if (unique) {
|
|
5456
|
-
middleware.forEach((md) => {
|
|
5457
|
-
const existingMiddlewareIndex = this.middleware.findIndex((m) => m.id === md.id);
|
|
5458
|
-
if (existingMiddlewareIndex >= 0) {
|
|
5459
|
-
this.middleware.splice(existingMiddlewareIndex, 1);
|
|
5460
|
-
}
|
|
5461
|
-
});
|
|
5462
|
-
}
|
|
5463
|
-
const targetId = position.after || position.before;
|
|
5464
|
-
const targetIndex = this.middleware.findIndex((m) => m.id === targetId);
|
|
5465
|
-
const insertionIndex = position.after ? targetIndex + 1 : targetIndex;
|
|
5466
|
-
this.middleware.splice(insertionIndex, 0, ...middleware);
|
|
5467
|
-
return this;
|
|
5468
|
-
}
|
|
5469
|
-
setOrder(order) {
|
|
5470
|
-
this.middleware = order.map((id) => this.middleware.find((middleware) => middleware.id === id)).filter(Boolean);
|
|
5471
|
-
}
|
|
5472
|
-
async executeMiddlewareChain({
|
|
5473
|
-
eventName,
|
|
5474
|
-
initialValue
|
|
5475
|
-
}) {
|
|
5476
|
-
let index = -1;
|
|
5477
|
-
const execute = async (i, state, status) => {
|
|
5478
|
-
if (i <= index) {
|
|
5479
|
-
throw new Error("next() called multiple times");
|
|
5480
|
-
}
|
|
5481
|
-
index = i;
|
|
5482
|
-
const returnFromChain = i === this.middleware.length || status && ["complete", "discard"].includes(status);
|
|
5483
|
-
if (returnFromChain) return { state, status };
|
|
5484
|
-
const middleware = this.middleware[i];
|
|
5485
|
-
const handler = middleware.handlers[eventName];
|
|
5486
|
-
if (!handler) {
|
|
5487
|
-
return execute(i + 1, state, status);
|
|
5488
|
-
}
|
|
5489
|
-
const next = (adjustedState) => execute(i + 1, adjustedState);
|
|
5490
|
-
const complete = (adjustedState) => execute(i + 1, adjustedState, "complete");
|
|
5491
|
-
const discard = () => execute(i + 1, state, "discard");
|
|
5492
|
-
const forward = () => execute(i + 1, state);
|
|
5493
|
-
return await handler({
|
|
5494
|
-
state,
|
|
5495
|
-
next,
|
|
5496
|
-
complete,
|
|
5497
|
-
discard,
|
|
5498
|
-
forward
|
|
5499
|
-
});
|
|
5500
|
-
};
|
|
5501
|
-
const result = await withCancellation(
|
|
5502
|
-
`middleware-execution-${this.id}-${eventName}`,
|
|
5503
|
-
async (abortSignal) => {
|
|
5504
|
-
const result2 = await execute(0, initialValue);
|
|
5505
|
-
if (abortSignal.aborted) {
|
|
5506
|
-
return "canceled";
|
|
5507
|
-
}
|
|
5508
|
-
return result2;
|
|
5509
|
-
}
|
|
5510
|
-
);
|
|
5511
|
-
return result === "canceled" ? { state: initialValue, status: "discard" } : result;
|
|
5512
|
-
}
|
|
5513
|
-
async execute({
|
|
5514
|
-
eventName,
|
|
5515
|
-
initialValue: initialState
|
|
5516
|
-
}) {
|
|
5517
|
-
return await this.executeMiddlewareChain({
|
|
5518
|
-
eventName,
|
|
5519
|
-
initialValue: initialState
|
|
5520
|
-
});
|
|
5521
|
-
}
|
|
5522
|
-
};
|
|
5523
|
-
|
|
5524
5754
|
// src/messageComposer/middleware/pollComposer/state.ts
|
|
5525
5755
|
var VALID_MAX_VOTES_VALUE_REGEX = /^([2-9]|10)$/;
|
|
5526
5756
|
var MAX_POLL_OPTIONS = 100;
|
|
@@ -8455,7 +8685,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8455
8685
|
id: this.id,
|
|
8456
8686
|
mentioned_users: [],
|
|
8457
8687
|
parent_id: this.threadId ?? void 0,
|
|
8458
|
-
pinned_at: null,
|
|
8688
|
+
pinned_at: this.editedMessage?.pinned_at || null,
|
|
8459
8689
|
reaction_groups: null,
|
|
8460
8690
|
status: this.editedMessage ? this.editedMessage.status : "sending",
|
|
8461
8691
|
text,
|
|
@@ -15774,7 +16004,7 @@ var StreamChat = class _StreamChat {
|
|
|
15774
16004
|
if (this.userAgent) {
|
|
15775
16005
|
return this.userAgent;
|
|
15776
16006
|
}
|
|
15777
|
-
const version = "9.
|
|
16007
|
+
const version = "9.14.0";
|
|
15778
16008
|
const clientBundle = "browser-cjs";
|
|
15779
16009
|
let userAgentString = "";
|
|
15780
16010
|
if (this.sdkIdentifier) {
|