stream-chat 9.13.0 → 9.15.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 +427 -189
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +1647 -232
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +427 -189
- 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 +4 -2
- package/dist/types/poll.d.ts +1 -1
- 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 +31 -10
- package/src/poll.ts +11 -14
- 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,300 @@ 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
|
+
remove(middlewareIds) {
|
|
4216
|
+
if (!middlewareIds && !middlewareIds.length) return;
|
|
4217
|
+
this.middleware = this.middleware.filter(
|
|
4218
|
+
(md) => typeof middlewareIds === "string" ? middlewareIds !== md.id : !middlewareIds.includes(md.id)
|
|
4219
|
+
);
|
|
4220
|
+
}
|
|
4221
|
+
async executeMiddlewareChain({
|
|
4222
|
+
eventName,
|
|
4223
|
+
initialValue,
|
|
4224
|
+
mode = "cancelable"
|
|
4225
|
+
}) {
|
|
4226
|
+
let index = -1;
|
|
4227
|
+
const execute = async (i, state, status) => {
|
|
4228
|
+
if (i <= index) {
|
|
4229
|
+
throw new Error("next() called multiple times");
|
|
4230
|
+
}
|
|
4231
|
+
index = i;
|
|
4232
|
+
const returnFromChain = i === this.middleware.length || status && ["complete", "discard"].includes(status);
|
|
4233
|
+
if (returnFromChain) return { state, status };
|
|
4234
|
+
const middleware = this.middleware[i];
|
|
4235
|
+
const handler = middleware.handlers[eventName];
|
|
4236
|
+
if (!handler) {
|
|
4237
|
+
return execute(i + 1, state, status);
|
|
4238
|
+
}
|
|
4239
|
+
const next = (adjustedState) => execute(i + 1, adjustedState);
|
|
4240
|
+
const complete = (adjustedState) => execute(i + 1, adjustedState, "complete");
|
|
4241
|
+
const discard = () => execute(i + 1, state, "discard");
|
|
4242
|
+
const forward = () => execute(i + 1, state);
|
|
4243
|
+
return await handler({
|
|
4244
|
+
state,
|
|
4245
|
+
next,
|
|
4246
|
+
complete,
|
|
4247
|
+
discard,
|
|
4248
|
+
forward
|
|
4249
|
+
});
|
|
4250
|
+
};
|
|
4251
|
+
const result = mode === "cancelable" ? await withCancellation(
|
|
4252
|
+
`middleware-execution-${this.id}-${eventName}`,
|
|
4253
|
+
async (abortSignal) => {
|
|
4254
|
+
const result2 = await execute(0, initialValue);
|
|
4255
|
+
if (abortSignal.aborted) {
|
|
4256
|
+
return "canceled";
|
|
4257
|
+
}
|
|
4258
|
+
return result2;
|
|
4259
|
+
}
|
|
4260
|
+
) : await execute(0, initialValue);
|
|
4261
|
+
return result === "canceled" ? { state: initialValue, status: "discard" } : result;
|
|
4262
|
+
}
|
|
4263
|
+
async execute({
|
|
4264
|
+
eventName,
|
|
4265
|
+
initialValue: initialState,
|
|
4266
|
+
mode
|
|
4267
|
+
}) {
|
|
4268
|
+
return await this.executeMiddlewareChain({
|
|
4269
|
+
eventName,
|
|
4270
|
+
initialValue: initialState,
|
|
4271
|
+
mode
|
|
4272
|
+
});
|
|
4273
|
+
}
|
|
4274
|
+
};
|
|
4275
|
+
|
|
4276
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/uploadErrorHandler.ts
|
|
4277
|
+
var createUploadErrorHandlerMiddleware = (composer) => ({
|
|
4278
|
+
id: "stream-io/attachment-manager-middleware/upload-error",
|
|
4279
|
+
handlers: {
|
|
4280
|
+
postProcess: ({
|
|
4281
|
+
state,
|
|
4282
|
+
discard,
|
|
4283
|
+
forward
|
|
4284
|
+
}) => {
|
|
4285
|
+
const { attachment, error } = state;
|
|
4286
|
+
if (!error) return forward();
|
|
4287
|
+
if (!attachment) return discard();
|
|
4288
|
+
const reason = error instanceof Error ? error.message : "unknown error";
|
|
4289
|
+
composer.client.notifications.addError({
|
|
4290
|
+
message: "Error uploading attachment",
|
|
4291
|
+
origin: {
|
|
4292
|
+
emitter: "AttachmentManager",
|
|
4293
|
+
context: { attachment }
|
|
4294
|
+
},
|
|
4295
|
+
options: {
|
|
4296
|
+
type: "api:attachment:upload:failed",
|
|
4297
|
+
metadata: { reason },
|
|
4298
|
+
originalError: error
|
|
4299
|
+
}
|
|
4300
|
+
});
|
|
4301
|
+
return forward();
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
});
|
|
4305
|
+
|
|
4306
|
+
// src/messageComposer/middleware/attachmentManager/postUpload/AttachmentPostUploadMiddlewareExecutor.ts
|
|
4307
|
+
var AttachmentPostUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
4308
|
+
constructor({ composer }) {
|
|
4309
|
+
super();
|
|
4310
|
+
this.use([
|
|
4311
|
+
createUploadErrorHandlerMiddleware(composer),
|
|
4312
|
+
createPostUploadAttachmentEnrichmentMiddleware()
|
|
4313
|
+
]);
|
|
4314
|
+
}
|
|
4315
|
+
};
|
|
4316
|
+
|
|
4317
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/serverUploadConfigCheck.ts
|
|
4318
|
+
var createUploadConfigCheckMiddleware = (composer) => ({
|
|
4319
|
+
id: "stream-io/attachment-manager-middleware/file-upload-config-check",
|
|
4320
|
+
handlers: {
|
|
4321
|
+
prepare: async ({
|
|
4322
|
+
state,
|
|
4323
|
+
next,
|
|
4324
|
+
discard
|
|
4325
|
+
}) => {
|
|
4326
|
+
const { attachmentManager } = composer;
|
|
4327
|
+
if (!attachmentManager || !state.attachment) return discard();
|
|
4328
|
+
const uploadPermissionCheck = await attachmentManager.getUploadConfigCheck(
|
|
4329
|
+
state.attachment.localMetadata.file
|
|
4330
|
+
);
|
|
4331
|
+
const attachment = {
|
|
4332
|
+
...state.attachment,
|
|
4333
|
+
localMetadata: {
|
|
4334
|
+
...state.attachment.localMetadata,
|
|
4335
|
+
uploadPermissionCheck,
|
|
4336
|
+
uploadState: uploadPermissionCheck.uploadBlocked ? "blocked" : "pending"
|
|
4337
|
+
}
|
|
4338
|
+
};
|
|
4339
|
+
return next({
|
|
4340
|
+
...state,
|
|
4341
|
+
attachment
|
|
4342
|
+
});
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
});
|
|
4346
|
+
|
|
4347
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/blockedUploadNotification.ts
|
|
4348
|
+
var createBlockedAttachmentUploadNotificationMiddleware = (composer) => ({
|
|
4349
|
+
id: "stream-io/attachment-manager-middleware/blocked-upload-notification",
|
|
4350
|
+
handlers: {
|
|
4351
|
+
prepare: ({
|
|
4352
|
+
state: { attachment },
|
|
4353
|
+
forward
|
|
4354
|
+
}) => {
|
|
4355
|
+
if (!attachment) return forward();
|
|
4356
|
+
if (attachment.localMetadata.uploadPermissionCheck?.uploadBlocked) {
|
|
4357
|
+
composer.client.notifications.addError({
|
|
4358
|
+
message: `The attachment upload was blocked`,
|
|
4359
|
+
origin: {
|
|
4360
|
+
emitter: "AttachmentManager",
|
|
4361
|
+
context: { blockedAttachment: attachment }
|
|
4362
|
+
},
|
|
4363
|
+
options: {
|
|
4364
|
+
type: "validation:attachment:upload:blocked",
|
|
4365
|
+
metadata: {
|
|
4366
|
+
reason: attachment.localMetadata.uploadPermissionCheck?.reason
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
});
|
|
4370
|
+
}
|
|
4371
|
+
return forward();
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
});
|
|
4375
|
+
|
|
4376
|
+
// src/messageComposer/middleware/attachmentManager/preUpload/AttachmentPreUploadMiddlewareExecutor.ts
|
|
4377
|
+
var AttachmentPreUploadMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
4378
|
+
constructor({ composer }) {
|
|
4379
|
+
super();
|
|
4380
|
+
this.use([
|
|
4381
|
+
createUploadConfigCheckMiddleware(composer),
|
|
4382
|
+
createBlockedAttachmentUploadNotificationMiddleware(composer)
|
|
4383
|
+
]);
|
|
4384
|
+
}
|
|
4385
|
+
};
|
|
4386
|
+
|
|
4091
4387
|
// src/store.ts
|
|
4092
4388
|
var isPatch = (value) => typeof value === "function";
|
|
4093
4389
|
var noop2 = () => {
|
|
@@ -4679,7 +4975,7 @@ var initState = ({
|
|
|
4679
4975
|
};
|
|
4680
4976
|
})
|
|
4681
4977
|
});
|
|
4682
|
-
var
|
|
4978
|
+
var _AttachmentManager = class _AttachmentManager {
|
|
4683
4979
|
constructor({ composer, message }) {
|
|
4684
4980
|
this.setCustomUploadFn = (doUploadRequest) => {
|
|
4685
4981
|
this.composer.updateConfig({ attachments: { doUploadRequest } });
|
|
@@ -4786,42 +5082,18 @@ var AttachmentManager = class {
|
|
|
4786
5082
|
}
|
|
4787
5083
|
return { uploadBlocked: false };
|
|
4788
5084
|
};
|
|
5085
|
+
// @deprecated use AttachmentManager.toLocalUploadAttachment(file)
|
|
4789
5086
|
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
|
-
}
|
|
5087
|
+
const localAttachment = _AttachmentManager.toLocalUploadAttachment(fileLike);
|
|
5088
|
+
const uploadPermissionCheck = await this.getUploadConfigCheck(
|
|
5089
|
+
localAttachment.localMetadata.file
|
|
5090
|
+
);
|
|
5091
|
+
localAttachment.localMetadata.uploadPermissionCheck = uploadPermissionCheck;
|
|
5092
|
+
localAttachment.localMetadata.uploadState = uploadPermissionCheck.uploadBlocked ? "blocked" : "pending";
|
|
4821
5093
|
return localAttachment;
|
|
4822
5094
|
};
|
|
4823
5095
|
this.ensureLocalUploadAttachment = async (attachment) => {
|
|
4824
|
-
if (!attachment.localMetadata?.file
|
|
5096
|
+
if (!attachment.localMetadata?.file) {
|
|
4825
5097
|
this.client.notifications.addError({
|
|
4826
5098
|
message: "File is required for upload attachment",
|
|
4827
5099
|
origin: { emitter: "AttachmentManager", context: { attachment } },
|
|
@@ -4829,6 +5101,14 @@ var AttachmentManager = class {
|
|
|
4829
5101
|
});
|
|
4830
5102
|
return;
|
|
4831
5103
|
}
|
|
5104
|
+
if (!attachment.localMetadata.id) {
|
|
5105
|
+
this.client.notifications.addError({
|
|
5106
|
+
message: "Local upload attachment missing local id",
|
|
5107
|
+
origin: { emitter: "AttachmentManager", context: { attachment } },
|
|
5108
|
+
options: { type: "validation:attachment:id:missing" }
|
|
5109
|
+
});
|
|
5110
|
+
return;
|
|
5111
|
+
}
|
|
4832
5112
|
if (!this.fileUploadFilter(attachment)) return;
|
|
4833
5113
|
const newAttachment = await this.fileToLocalUploadAttachment(
|
|
4834
5114
|
attachment.localMetadata.file
|
|
@@ -4868,6 +5148,7 @@ var AttachmentManager = class {
|
|
|
4868
5148
|
}
|
|
4869
5149
|
return this.doDefaultUploadRequest(fileLike);
|
|
4870
5150
|
};
|
|
5151
|
+
// @deprecated use attachmentManager.uploadFile(file)
|
|
4871
5152
|
this.uploadAttachment = async (attachment) => {
|
|
4872
5153
|
if (!this.isUploadEnabled) return;
|
|
4873
5154
|
const localAttachment = await this.ensureLocalUploadAttachment(attachment);
|
|
@@ -4951,19 +5232,75 @@ var AttachmentManager = class {
|
|
|
4951
5232
|
this.updateAttachment(uploadedAttachment);
|
|
4952
5233
|
return uploadedAttachment;
|
|
4953
5234
|
};
|
|
5235
|
+
this.uploadFile = async (file) => {
|
|
5236
|
+
const preUpload = await this.preUploadMiddlewareExecutor.execute({
|
|
5237
|
+
eventName: "prepare",
|
|
5238
|
+
initialValue: {
|
|
5239
|
+
attachment: _AttachmentManager.toLocalUploadAttachment(file)
|
|
5240
|
+
},
|
|
5241
|
+
mode: "concurrent"
|
|
5242
|
+
});
|
|
5243
|
+
let attachment = preUpload.state.attachment;
|
|
5244
|
+
if (preUpload.status === "discard") return attachment;
|
|
5245
|
+
if (!this.fileUploadFilter(attachment)) return attachment;
|
|
5246
|
+
if (attachment.localMetadata.uploadState === "blocked") {
|
|
5247
|
+
this.upsertAttachments([attachment]);
|
|
5248
|
+
return preUpload.state.attachment;
|
|
5249
|
+
}
|
|
5250
|
+
attachment = {
|
|
5251
|
+
...attachment,
|
|
5252
|
+
localMetadata: {
|
|
5253
|
+
...attachment.localMetadata,
|
|
5254
|
+
uploadState: "uploading"
|
|
5255
|
+
}
|
|
5256
|
+
};
|
|
5257
|
+
this.upsertAttachments([attachment]);
|
|
5258
|
+
let response;
|
|
5259
|
+
let error;
|
|
5260
|
+
try {
|
|
5261
|
+
response = await this.doUploadRequest(file);
|
|
5262
|
+
} catch (err) {
|
|
5263
|
+
error = err instanceof Error ? err : void 0;
|
|
5264
|
+
}
|
|
5265
|
+
const postUpload = await this.postUploadMiddlewareExecutor.execute({
|
|
5266
|
+
eventName: "postProcess",
|
|
5267
|
+
initialValue: {
|
|
5268
|
+
attachment: {
|
|
5269
|
+
...attachment,
|
|
5270
|
+
localMetadata: {
|
|
5271
|
+
...attachment.localMetadata,
|
|
5272
|
+
uploadState: error ? "failed" : "finished"
|
|
5273
|
+
}
|
|
5274
|
+
},
|
|
5275
|
+
error,
|
|
5276
|
+
response
|
|
5277
|
+
},
|
|
5278
|
+
mode: "concurrent"
|
|
5279
|
+
});
|
|
5280
|
+
attachment = postUpload.state.attachment;
|
|
5281
|
+
if (postUpload.status === "discard") {
|
|
5282
|
+
this.removeAttachments([attachment.localMetadata.id]);
|
|
5283
|
+
return attachment;
|
|
5284
|
+
}
|
|
5285
|
+
this.updateAttachment(attachment);
|
|
5286
|
+
return attachment;
|
|
5287
|
+
};
|
|
4954
5288
|
this.uploadFiles = async (files) => {
|
|
4955
5289
|
if (!this.isUploadEnabled) return;
|
|
4956
5290
|
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)
|
|
5291
|
+
return await Promise.all(
|
|
5292
|
+
iterableFiles.slice(0, this.availableUploadSlots).map(this.uploadFile)
|
|
4962
5293
|
);
|
|
4963
5294
|
};
|
|
4964
5295
|
this.composer = composer;
|
|
4965
5296
|
this.state = new StateStore(initState({ message }));
|
|
4966
5297
|
this.attachmentsByIdGetterCache = { attachmentsById: {}, attachments: [] };
|
|
5298
|
+
this.preUploadMiddlewareExecutor = new AttachmentPreUploadMiddlewareExecutor({
|
|
5299
|
+
composer
|
|
5300
|
+
});
|
|
5301
|
+
this.postUploadMiddlewareExecutor = new AttachmentPostUploadMiddlewareExecutor({
|
|
5302
|
+
composer
|
|
5303
|
+
});
|
|
4967
5304
|
}
|
|
4968
5305
|
get attachmentsById() {
|
|
4969
5306
|
const { attachments } = this.state.getLatestValue();
|
|
@@ -4993,9 +5330,15 @@ var AttachmentManager = class {
|
|
|
4993
5330
|
set acceptedFiles(acceptedFiles) {
|
|
4994
5331
|
this.composer.updateConfig({ attachments: { acceptedFiles } });
|
|
4995
5332
|
}
|
|
5333
|
+
/*
|
|
5334
|
+
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
5335
|
+
*/
|
|
4996
5336
|
get fileUploadFilter() {
|
|
4997
5337
|
return this.config.fileUploadFilter;
|
|
4998
5338
|
}
|
|
5339
|
+
/*
|
|
5340
|
+
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
5341
|
+
*/
|
|
4999
5342
|
set fileUploadFilter(fileUploadFilter) {
|
|
5000
5343
|
this.composer.updateConfig({ attachments: { fileUploadFilter } });
|
|
5001
5344
|
}
|
|
@@ -5042,6 +5385,39 @@ var AttachmentManager = class {
|
|
|
5042
5385
|
);
|
|
5043
5386
|
}
|
|
5044
5387
|
};
|
|
5388
|
+
_AttachmentManager.toLocalUploadAttachment = (fileLike) => {
|
|
5389
|
+
const file = isFileReference(fileLike) || isFile2(fileLike) ? fileLike : createFileFromBlobs({
|
|
5390
|
+
blobsArray: [fileLike],
|
|
5391
|
+
fileName: generateFileName(fileLike.type),
|
|
5392
|
+
mimeType: fileLike.type
|
|
5393
|
+
});
|
|
5394
|
+
const localAttachment = {
|
|
5395
|
+
file_size: file.size,
|
|
5396
|
+
mime_type: file.type,
|
|
5397
|
+
localMetadata: {
|
|
5398
|
+
file,
|
|
5399
|
+
id: generateUUIDv4(),
|
|
5400
|
+
uploadState: "pending"
|
|
5401
|
+
},
|
|
5402
|
+
type: getAttachmentTypeFromMimeType(file.type)
|
|
5403
|
+
};
|
|
5404
|
+
localAttachment[isImageFile(file) ? "fallback" : "title"] = file.name;
|
|
5405
|
+
if (isImageFile(file)) {
|
|
5406
|
+
localAttachment.localMetadata.previewUri = isFileReference(fileLike) ? fileLike.uri : URL.createObjectURL?.(fileLike);
|
|
5407
|
+
if (isFileReference(fileLike) && fileLike.height && fileLike.width) {
|
|
5408
|
+
localAttachment.original_height = fileLike.height;
|
|
5409
|
+
localAttachment.original_width = fileLike.width;
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
if (isFileReference(fileLike) && fileLike.thumb_url) {
|
|
5413
|
+
localAttachment.thumb_url = fileLike.thumb_url;
|
|
5414
|
+
}
|
|
5415
|
+
if (isFileReference(fileLike) && fileLike.duration) {
|
|
5416
|
+
localAttachment.duration = fileLike.duration;
|
|
5417
|
+
}
|
|
5418
|
+
return localAttachment;
|
|
5419
|
+
};
|
|
5420
|
+
var AttachmentManager = _AttachmentManager;
|
|
5045
5421
|
|
|
5046
5422
|
// src/messageComposer/configuration/configuration.ts
|
|
5047
5423
|
var import_linkifyjs = require("linkifyjs");
|
|
@@ -5381,146 +5757,6 @@ var LocationComposer = class {
|
|
|
5381
5757
|
}
|
|
5382
5758
|
};
|
|
5383
5759
|
|
|
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
5760
|
// src/messageComposer/middleware/pollComposer/state.ts
|
|
5525
5761
|
var VALID_MAX_VOTES_VALUE_REGEX = /^([2-9]|10)$/;
|
|
5526
5762
|
var MAX_POLL_OPTIONS = 100;
|
|
@@ -8455,7 +8691,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8455
8691
|
id: this.id,
|
|
8456
8692
|
mentioned_users: [],
|
|
8457
8693
|
parent_id: this.threadId ?? void 0,
|
|
8458
|
-
pinned_at: null,
|
|
8694
|
+
pinned_at: this.editedMessage?.pinned_at || null,
|
|
8459
8695
|
reaction_groups: null,
|
|
8460
8696
|
status: this.editedMessage ? this.editedMessage.status : "sending",
|
|
8461
8697
|
text,
|
|
@@ -12283,15 +12519,17 @@ var Poll = class {
|
|
|
12283
12519
|
const { max_votes_allowed, ownVotesByOptionId } = this.data;
|
|
12284
12520
|
const reachedVoteLimit = max_votes_allowed && max_votes_allowed === Object.keys(ownVotesByOptionId).length;
|
|
12285
12521
|
if (reachedVoteLimit) {
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12522
|
+
this.client.notifications.addInfo({
|
|
12523
|
+
message: "Reached the vote limit. Remove an existing vote first.",
|
|
12524
|
+
origin: {
|
|
12525
|
+
emitter: "Poll",
|
|
12526
|
+
context: { messageId, optionId }
|
|
12527
|
+
},
|
|
12528
|
+
options: {
|
|
12529
|
+
type: "validation:poll:castVote:limit"
|
|
12290
12530
|
}
|
|
12291
12531
|
});
|
|
12292
|
-
|
|
12293
|
-
await this.removeVote(oldestVote.id, messageId);
|
|
12294
|
-
}
|
|
12532
|
+
return;
|
|
12295
12533
|
}
|
|
12296
12534
|
return await this.client.castPollVote(messageId, this.id, {
|
|
12297
12535
|
option_id: optionId
|
|
@@ -15774,7 +16012,7 @@ var StreamChat = class _StreamChat {
|
|
|
15774
16012
|
if (this.userAgent) {
|
|
15775
16013
|
return this.userAgent;
|
|
15776
16014
|
}
|
|
15777
|
-
const version = "9.
|
|
16015
|
+
const version = "9.15.0";
|
|
15778
16016
|
const clientBundle = "browser-cjs";
|
|
15779
16017
|
let userAgentString = "";
|
|
15780
16018
|
if (this.sdkIdentifier) {
|