@liveblocks/core 2.5.1 → 2.7.0-beta1
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/index.d.mts +269 -193
- package/dist/index.d.ts +269 -193
- package/dist/index.js +596 -443
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +582 -429
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "2.
|
|
9
|
+
var PKG_VERSION = "2.7.0-beta1";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -1859,8 +1859,7 @@ var Batch = class {
|
|
|
1859
1859
|
this.clearDelayTimeout();
|
|
1860
1860
|
}
|
|
1861
1861
|
};
|
|
1862
|
-
function createBatchStore(
|
|
1863
|
-
const batch = new Batch(callback, options);
|
|
1862
|
+
function createBatchStore(batch) {
|
|
1864
1863
|
const cache = /* @__PURE__ */ new Map();
|
|
1865
1864
|
const eventSource2 = makeEventSource();
|
|
1866
1865
|
function getCacheKey(args) {
|
|
@@ -4749,9 +4748,19 @@ function findNonSerializableValue(value, path = "") {
|
|
|
4749
4748
|
return false;
|
|
4750
4749
|
}
|
|
4751
4750
|
|
|
4751
|
+
// src/lib/chunk.ts
|
|
4752
|
+
function chunk(array, size) {
|
|
4753
|
+
const chunks = [];
|
|
4754
|
+
for (let i = 0, j = array.length; i < j; i += size) {
|
|
4755
|
+
chunks.push(array.slice(i, i + size));
|
|
4756
|
+
}
|
|
4757
|
+
return chunks;
|
|
4758
|
+
}
|
|
4759
|
+
|
|
4752
4760
|
// src/lib/createIds.ts
|
|
4753
4761
|
var THREAD_ID_PREFIX = "th";
|
|
4754
4762
|
var COMMENT_ID_PREFIX = "cm";
|
|
4763
|
+
var COMMENT_ATTACHMENT_ID_PREFIX = "at";
|
|
4755
4764
|
var INBOX_NOTIFICATION_ID_PREFIX = "in";
|
|
4756
4765
|
function createOptimisticId(prefix) {
|
|
4757
4766
|
return `${prefix}_${nanoid()}`;
|
|
@@ -4762,6 +4771,9 @@ function createThreadId() {
|
|
|
4762
4771
|
function createCommentId() {
|
|
4763
4772
|
return createOptimisticId(COMMENT_ID_PREFIX);
|
|
4764
4773
|
}
|
|
4774
|
+
function createCommentAttachmentId() {
|
|
4775
|
+
return createOptimisticId(COMMENT_ATTACHMENT_ID_PREFIX);
|
|
4776
|
+
}
|
|
4765
4777
|
function createInboxNotificationId() {
|
|
4766
4778
|
return createOptimisticId(INBOX_NOTIFICATION_ID_PREFIX);
|
|
4767
4779
|
}
|
|
@@ -5164,6 +5176,22 @@ function installBackgroundTabSpy() {
|
|
|
5164
5176
|
};
|
|
5165
5177
|
return [inBackgroundSince, unsub];
|
|
5166
5178
|
}
|
|
5179
|
+
var GET_ATTACHMENT_URLS_BATCH_DELAY = 50;
|
|
5180
|
+
var ATTACHMENT_PART_SIZE = 5 * 1024 * 1024;
|
|
5181
|
+
var ATTACHMENT_PART_BATCH_SIZE = 5;
|
|
5182
|
+
function splitFileIntoParts(file) {
|
|
5183
|
+
const parts = [];
|
|
5184
|
+
let start = 0;
|
|
5185
|
+
while (start < file.size) {
|
|
5186
|
+
const end = Math.min(start + ATTACHMENT_PART_SIZE, file.size);
|
|
5187
|
+
parts.push({
|
|
5188
|
+
partNumber: parts.length + 1,
|
|
5189
|
+
part: file.slice(start, end)
|
|
5190
|
+
});
|
|
5191
|
+
start = end;
|
|
5192
|
+
}
|
|
5193
|
+
return parts;
|
|
5194
|
+
}
|
|
5167
5195
|
var CommentsApiError = class extends Error {
|
|
5168
5196
|
constructor(message, status, details) {
|
|
5169
5197
|
super(message);
|
|
@@ -5172,429 +5200,138 @@ var CommentsApiError = class extends Error {
|
|
|
5172
5200
|
this.details = details;
|
|
5173
5201
|
}
|
|
5174
5202
|
};
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
if
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
} catch {
|
|
5193
|
-
error3 = new CommentsApiError(response.statusText, response.status);
|
|
5194
|
-
}
|
|
5195
|
-
throw error3;
|
|
5196
|
-
}
|
|
5197
|
-
}
|
|
5198
|
-
let body;
|
|
5199
|
-
try {
|
|
5200
|
-
body = await response.json();
|
|
5201
|
-
} catch {
|
|
5202
|
-
body = {};
|
|
5203
|
+
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 = 50;
|
|
5204
|
+
function createRoom(options, config) {
|
|
5205
|
+
const initialPresence = options.initialPresence;
|
|
5206
|
+
const initialStorage = options.initialStorage;
|
|
5207
|
+
const [inBackgroundSince, uninstallBgTabSpy] = installBackgroundTabSpy();
|
|
5208
|
+
const delegates = {
|
|
5209
|
+
...config.delegates,
|
|
5210
|
+
// A connection is allowed to go into "zombie state" only if all of the
|
|
5211
|
+
// following conditions apply:
|
|
5212
|
+
//
|
|
5213
|
+
// - The `backgroundKeepAliveTimeout` client option is configured
|
|
5214
|
+
// - The browser window has been in the background for at least
|
|
5215
|
+
// `backgroundKeepAliveTimeout` milliseconds
|
|
5216
|
+
// - There are no pending changes
|
|
5217
|
+
//
|
|
5218
|
+
canZombie() {
|
|
5219
|
+
return config.backgroundKeepAliveTimeout !== void 0 && inBackgroundSince.current !== null && Date.now() > inBackgroundSince.current + config.backgroundKeepAliveTimeout && getStorageStatus() !== "synchronizing";
|
|
5203
5220
|
}
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5221
|
+
};
|
|
5222
|
+
const managedSocket = new ManagedSocket(
|
|
5223
|
+
delegates,
|
|
5224
|
+
config.enableDebugLogging
|
|
5225
|
+
);
|
|
5226
|
+
const context = {
|
|
5227
|
+
buffer: {
|
|
5228
|
+
flushTimerID: void 0,
|
|
5229
|
+
lastFlushedAt: 0,
|
|
5230
|
+
presenceUpdates: (
|
|
5231
|
+
// Queue up the initial presence message as a Full Presence™ update
|
|
5232
|
+
{
|
|
5233
|
+
type: "full",
|
|
5234
|
+
data: initialPresence
|
|
5235
|
+
}
|
|
5236
|
+
),
|
|
5237
|
+
messages: [],
|
|
5238
|
+
storageOperations: []
|
|
5239
|
+
},
|
|
5240
|
+
staticSessionInfo: new ValueRef(null),
|
|
5241
|
+
dynamicSessionInfo: new ValueRef(null),
|
|
5242
|
+
myPresence: new PatchableRef(initialPresence),
|
|
5243
|
+
others: new OthersRef(),
|
|
5244
|
+
initialStorage,
|
|
5245
|
+
idFactory: null,
|
|
5246
|
+
// Y.js
|
|
5247
|
+
provider: void 0,
|
|
5248
|
+
onProviderUpdate: makeEventSource(),
|
|
5249
|
+
// Storage
|
|
5250
|
+
clock: 0,
|
|
5251
|
+
opClock: 0,
|
|
5252
|
+
nodes: /* @__PURE__ */ new Map(),
|
|
5253
|
+
root: void 0,
|
|
5254
|
+
undoStack: [],
|
|
5255
|
+
redoStack: [],
|
|
5256
|
+
pausedHistory: null,
|
|
5257
|
+
activeBatch: null,
|
|
5258
|
+
unacknowledgedOps: /* @__PURE__ */ new Map(),
|
|
5259
|
+
// Debug
|
|
5260
|
+
opStackTraces: process.env.NODE_ENV !== "production" ? /* @__PURE__ */ new Map() : void 0
|
|
5261
|
+
};
|
|
5262
|
+
const doNotBatchUpdates = (cb) => cb();
|
|
5263
|
+
const batchUpdates = config.unstable_batchedUpdates ?? doNotBatchUpdates;
|
|
5264
|
+
let lastTokenKey;
|
|
5265
|
+
function onStatusDidChange(newStatus) {
|
|
5266
|
+
const authValue = managedSocket.authValue;
|
|
5267
|
+
if (authValue !== null) {
|
|
5268
|
+
const tokenKey = getAuthBearerHeaderFromAuthValue(authValue);
|
|
5269
|
+
if (tokenKey !== lastTokenKey) {
|
|
5270
|
+
lastTokenKey = tokenKey;
|
|
5271
|
+
if (authValue.type === "secret") {
|
|
5272
|
+
const token = authValue.token.parsed;
|
|
5273
|
+
context.staticSessionInfo.set({
|
|
5274
|
+
userId: token.k === "sec-legacy" /* SECRET_LEGACY */ ? token.id : token.uid,
|
|
5275
|
+
userInfo: token.k === "sec-legacy" /* SECRET_LEGACY */ ? token.info : token.ui
|
|
5276
|
+
});
|
|
5277
|
+
} else {
|
|
5278
|
+
context.staticSessionInfo.set({
|
|
5279
|
+
userId: void 0,
|
|
5280
|
+
userInfo: void 0
|
|
5281
|
+
});
|
|
5215
5282
|
}
|
|
5216
5283
|
}
|
|
5217
|
-
);
|
|
5218
|
-
if (response.ok) {
|
|
5219
|
-
const json = await response.json();
|
|
5220
|
-
return {
|
|
5221
|
-
threads: {
|
|
5222
|
-
updated: json.data.map(convertToThreadData),
|
|
5223
|
-
deleted: json.deletedThreads.map(convertToThreadDeleteInfo)
|
|
5224
|
-
},
|
|
5225
|
-
inboxNotifications: {
|
|
5226
|
-
updated: json.inboxNotifications.map(convertToInboxNotificationData),
|
|
5227
|
-
deleted: json.deletedInboxNotifications.map(
|
|
5228
|
-
convertToInboxNotificationDeleteInfo
|
|
5229
|
-
)
|
|
5230
|
-
},
|
|
5231
|
-
requestedAt: new Date(json.meta.requestedAt)
|
|
5232
|
-
};
|
|
5233
|
-
} else if (response.status === 404) {
|
|
5234
|
-
return {
|
|
5235
|
-
threads: {
|
|
5236
|
-
updated: [],
|
|
5237
|
-
deleted: []
|
|
5238
|
-
},
|
|
5239
|
-
inboxNotifications: {
|
|
5240
|
-
updated: [],
|
|
5241
|
-
deleted: []
|
|
5242
|
-
},
|
|
5243
|
-
requestedAt: /* @__PURE__ */ new Date()
|
|
5244
|
-
};
|
|
5245
|
-
} else {
|
|
5246
|
-
throw new Error("There was an error while getting threads.");
|
|
5247
5284
|
}
|
|
5285
|
+
batchUpdates(() => {
|
|
5286
|
+
eventHub.status.notify(newStatus);
|
|
5287
|
+
notifySelfChanged(doNotBatchUpdates);
|
|
5288
|
+
});
|
|
5248
5289
|
}
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5290
|
+
let _connectionLossTimerId;
|
|
5291
|
+
let _hasLostConnection = false;
|
|
5292
|
+
function handleConnectionLossEvent(newStatus) {
|
|
5293
|
+
if (newStatus === "reconnecting") {
|
|
5294
|
+
_connectionLossTimerId = setTimeout(() => {
|
|
5295
|
+
batchUpdates(() => {
|
|
5296
|
+
eventHub.lostConnection.notify("lost");
|
|
5297
|
+
_hasLostConnection = true;
|
|
5298
|
+
context.others.clearOthers();
|
|
5299
|
+
notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
|
|
5300
|
+
});
|
|
5301
|
+
}, config.lostConnectionTimeout);
|
|
5302
|
+
} else {
|
|
5303
|
+
clearTimeout(_connectionLossTimerId);
|
|
5304
|
+
if (_hasLostConnection) {
|
|
5305
|
+
if (newStatus === "disconnected") {
|
|
5306
|
+
batchUpdates(() => {
|
|
5307
|
+
eventHub.lostConnection.notify("failed");
|
|
5308
|
+
});
|
|
5309
|
+
} else {
|
|
5310
|
+
batchUpdates(() => {
|
|
5311
|
+
eventHub.lostConnection.notify("restored");
|
|
5312
|
+
});
|
|
5262
5313
|
}
|
|
5314
|
+
_hasLostConnection = false;
|
|
5263
5315
|
}
|
|
5264
|
-
);
|
|
5265
|
-
if (response.ok) {
|
|
5266
|
-
const json = await response.json();
|
|
5267
|
-
return {
|
|
5268
|
-
threads: json.data.map(convertToThreadData),
|
|
5269
|
-
inboxNotifications: json.inboxNotifications.map(
|
|
5270
|
-
convertToInboxNotificationData
|
|
5271
|
-
),
|
|
5272
|
-
requestedAt: new Date(json.meta.requestedAt)
|
|
5273
|
-
};
|
|
5274
|
-
} else if (response.status === 404) {
|
|
5275
|
-
return {
|
|
5276
|
-
threads: [],
|
|
5277
|
-
inboxNotifications: [],
|
|
5278
|
-
deletedThreads: [],
|
|
5279
|
-
deletedInboxNotifications: [],
|
|
5280
|
-
requestedAt: /* @__PURE__ */ new Date()
|
|
5281
|
-
};
|
|
5282
|
-
} else {
|
|
5283
|
-
throw new Error("There was an error while getting threads.");
|
|
5284
5316
|
}
|
|
5285
5317
|
}
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
thread: void 0,
|
|
5299
|
-
inboxNotification: void 0
|
|
5300
|
-
};
|
|
5301
|
-
} else {
|
|
5302
|
-
throw new Error(`There was an error while getting thread ${threadId}.`);
|
|
5318
|
+
function onDidConnect() {
|
|
5319
|
+
context.buffer.presenceUpdates = {
|
|
5320
|
+
type: "full",
|
|
5321
|
+
data: (
|
|
5322
|
+
// Because context.me.current is a readonly object, we'll have to
|
|
5323
|
+
// make a copy here. Otherwise, type errors happen later when
|
|
5324
|
+
// "patching" my presence.
|
|
5325
|
+
{ ...context.myPresence.current }
|
|
5326
|
+
)
|
|
5327
|
+
};
|
|
5328
|
+
if (_getStorage$ !== null) {
|
|
5329
|
+
refreshStorage({ flush: false });
|
|
5303
5330
|
}
|
|
5331
|
+
flushNowOrSoon();
|
|
5304
5332
|
}
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
body,
|
|
5308
|
-
commentId = createCommentId(),
|
|
5309
|
-
threadId = createThreadId()
|
|
5310
|
-
}) {
|
|
5311
|
-
const thread = await fetchJson("/threads", {
|
|
5312
|
-
method: "POST",
|
|
5313
|
-
headers: {
|
|
5314
|
-
"Content-Type": "application/json"
|
|
5315
|
-
},
|
|
5316
|
-
body: JSON.stringify({
|
|
5317
|
-
id: threadId,
|
|
5318
|
-
comment: {
|
|
5319
|
-
id: commentId,
|
|
5320
|
-
body
|
|
5321
|
-
},
|
|
5322
|
-
metadata
|
|
5323
|
-
})
|
|
5324
|
-
});
|
|
5325
|
-
return convertToThreadData(thread);
|
|
5326
|
-
}
|
|
5327
|
-
async function deleteThread(threadId) {
|
|
5328
|
-
await fetchJson(`/threads/${encodeURIComponent(threadId)}`, {
|
|
5329
|
-
method: "DELETE"
|
|
5330
|
-
});
|
|
5331
|
-
}
|
|
5332
|
-
async function editThreadMetadata({
|
|
5333
|
-
metadata,
|
|
5334
|
-
threadId
|
|
5335
|
-
}) {
|
|
5336
|
-
return await fetchJson(
|
|
5337
|
-
`/threads/${encodeURIComponent(threadId)}/metadata`,
|
|
5338
|
-
{
|
|
5339
|
-
method: "POST",
|
|
5340
|
-
headers: {
|
|
5341
|
-
"Content-Type": "application/json"
|
|
5342
|
-
},
|
|
5343
|
-
body: JSON.stringify(metadata)
|
|
5344
|
-
}
|
|
5345
|
-
);
|
|
5346
|
-
}
|
|
5347
|
-
async function markThreadAsResolved(threadId) {
|
|
5348
|
-
await fetchJson(
|
|
5349
|
-
`/threads/${encodeURIComponent(threadId)}/mark-as-resolved`,
|
|
5350
|
-
{
|
|
5351
|
-
method: "POST"
|
|
5352
|
-
}
|
|
5353
|
-
);
|
|
5354
|
-
}
|
|
5355
|
-
async function markThreadAsUnresolved(threadId) {
|
|
5356
|
-
await fetchJson(
|
|
5357
|
-
`/threads/${encodeURIComponent(threadId)}/mark-as-unresolved`,
|
|
5358
|
-
{
|
|
5359
|
-
method: "POST"
|
|
5360
|
-
}
|
|
5361
|
-
);
|
|
5362
|
-
}
|
|
5363
|
-
async function createComment({
|
|
5364
|
-
threadId,
|
|
5365
|
-
commentId = createCommentId(),
|
|
5366
|
-
body
|
|
5367
|
-
}) {
|
|
5368
|
-
const comment = await fetchJson(
|
|
5369
|
-
`/threads/${encodeURIComponent(threadId)}/comments`,
|
|
5370
|
-
{
|
|
5371
|
-
method: "POST",
|
|
5372
|
-
headers: {
|
|
5373
|
-
"Content-Type": "application/json"
|
|
5374
|
-
},
|
|
5375
|
-
body: JSON.stringify({
|
|
5376
|
-
id: commentId,
|
|
5377
|
-
body
|
|
5378
|
-
})
|
|
5379
|
-
}
|
|
5380
|
-
);
|
|
5381
|
-
return convertToCommentData(comment);
|
|
5382
|
-
}
|
|
5383
|
-
async function editComment({
|
|
5384
|
-
threadId,
|
|
5385
|
-
commentId,
|
|
5386
|
-
body
|
|
5387
|
-
}) {
|
|
5388
|
-
const comment = await fetchJson(
|
|
5389
|
-
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
5390
|
-
commentId
|
|
5391
|
-
)}`,
|
|
5392
|
-
{
|
|
5393
|
-
method: "POST",
|
|
5394
|
-
headers: {
|
|
5395
|
-
"Content-Type": "application/json"
|
|
5396
|
-
},
|
|
5397
|
-
body: JSON.stringify({
|
|
5398
|
-
body
|
|
5399
|
-
})
|
|
5400
|
-
}
|
|
5401
|
-
);
|
|
5402
|
-
return convertToCommentData(comment);
|
|
5403
|
-
}
|
|
5404
|
-
async function deleteComment2({
|
|
5405
|
-
threadId,
|
|
5406
|
-
commentId
|
|
5407
|
-
}) {
|
|
5408
|
-
await fetchJson(
|
|
5409
|
-
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
5410
|
-
commentId
|
|
5411
|
-
)}`,
|
|
5412
|
-
{
|
|
5413
|
-
method: "DELETE"
|
|
5414
|
-
}
|
|
5415
|
-
);
|
|
5416
|
-
}
|
|
5417
|
-
async function addReaction2({
|
|
5418
|
-
threadId,
|
|
5419
|
-
commentId,
|
|
5420
|
-
emoji
|
|
5421
|
-
}) {
|
|
5422
|
-
const reaction = await fetchJson(
|
|
5423
|
-
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
5424
|
-
commentId
|
|
5425
|
-
)}/reactions`,
|
|
5426
|
-
{
|
|
5427
|
-
method: "POST",
|
|
5428
|
-
headers: {
|
|
5429
|
-
"Content-Type": "application/json"
|
|
5430
|
-
},
|
|
5431
|
-
body: JSON.stringify({ emoji })
|
|
5432
|
-
}
|
|
5433
|
-
);
|
|
5434
|
-
return convertToCommentUserReaction(reaction);
|
|
5435
|
-
}
|
|
5436
|
-
async function removeReaction2({
|
|
5437
|
-
threadId,
|
|
5438
|
-
commentId,
|
|
5439
|
-
emoji
|
|
5440
|
-
}) {
|
|
5441
|
-
await fetchJson(
|
|
5442
|
-
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
5443
|
-
commentId
|
|
5444
|
-
)}/reactions/${encodeURIComponent(emoji)}`,
|
|
5445
|
-
{
|
|
5446
|
-
method: "DELETE"
|
|
5447
|
-
}
|
|
5448
|
-
);
|
|
5449
|
-
}
|
|
5450
|
-
return {
|
|
5451
|
-
getThreads,
|
|
5452
|
-
getThreadsSince,
|
|
5453
|
-
getThread,
|
|
5454
|
-
createThread,
|
|
5455
|
-
deleteThread,
|
|
5456
|
-
editThreadMetadata,
|
|
5457
|
-
markThreadAsResolved,
|
|
5458
|
-
markThreadAsUnresolved,
|
|
5459
|
-
createComment,
|
|
5460
|
-
editComment,
|
|
5461
|
-
deleteComment: deleteComment2,
|
|
5462
|
-
addReaction: addReaction2,
|
|
5463
|
-
removeReaction: removeReaction2
|
|
5464
|
-
};
|
|
5465
|
-
}
|
|
5466
|
-
var MARK_INBOX_NOTIFICATIONS_AS_READ_BATCH_DELAY2 = 50;
|
|
5467
|
-
function createRoom(options, config) {
|
|
5468
|
-
const initialPresence = options.initialPresence;
|
|
5469
|
-
const initialStorage = options.initialStorage;
|
|
5470
|
-
const [inBackgroundSince, uninstallBgTabSpy] = installBackgroundTabSpy();
|
|
5471
|
-
const delegates = {
|
|
5472
|
-
...config.delegates,
|
|
5473
|
-
// A connection is allowed to go into "zombie state" only if all of the
|
|
5474
|
-
// following conditions apply:
|
|
5475
|
-
//
|
|
5476
|
-
// - The `backgroundKeepAliveTimeout` client option is configured
|
|
5477
|
-
// - The browser window has been in the background for at least
|
|
5478
|
-
// `backgroundKeepAliveTimeout` milliseconds
|
|
5479
|
-
// - There are no pending changes
|
|
5480
|
-
//
|
|
5481
|
-
canZombie() {
|
|
5482
|
-
return config.backgroundKeepAliveTimeout !== void 0 && inBackgroundSince.current !== null && Date.now() > inBackgroundSince.current + config.backgroundKeepAliveTimeout && getStorageStatus() !== "synchronizing";
|
|
5483
|
-
}
|
|
5484
|
-
};
|
|
5485
|
-
const managedSocket = new ManagedSocket(
|
|
5486
|
-
delegates,
|
|
5487
|
-
config.enableDebugLogging
|
|
5488
|
-
);
|
|
5489
|
-
const context = {
|
|
5490
|
-
buffer: {
|
|
5491
|
-
flushTimerID: void 0,
|
|
5492
|
-
lastFlushedAt: 0,
|
|
5493
|
-
presenceUpdates: (
|
|
5494
|
-
// Queue up the initial presence message as a Full Presence™ update
|
|
5495
|
-
{
|
|
5496
|
-
type: "full",
|
|
5497
|
-
data: initialPresence
|
|
5498
|
-
}
|
|
5499
|
-
),
|
|
5500
|
-
messages: [],
|
|
5501
|
-
storageOperations: []
|
|
5502
|
-
},
|
|
5503
|
-
staticSessionInfo: new ValueRef(null),
|
|
5504
|
-
dynamicSessionInfo: new ValueRef(null),
|
|
5505
|
-
myPresence: new PatchableRef(initialPresence),
|
|
5506
|
-
others: new OthersRef(),
|
|
5507
|
-
initialStorage,
|
|
5508
|
-
idFactory: null,
|
|
5509
|
-
// Y.js
|
|
5510
|
-
provider: void 0,
|
|
5511
|
-
onProviderUpdate: makeEventSource(),
|
|
5512
|
-
// Storage
|
|
5513
|
-
clock: 0,
|
|
5514
|
-
opClock: 0,
|
|
5515
|
-
nodes: /* @__PURE__ */ new Map(),
|
|
5516
|
-
root: void 0,
|
|
5517
|
-
undoStack: [],
|
|
5518
|
-
redoStack: [],
|
|
5519
|
-
pausedHistory: null,
|
|
5520
|
-
activeBatch: null,
|
|
5521
|
-
unacknowledgedOps: /* @__PURE__ */ new Map(),
|
|
5522
|
-
// Debug
|
|
5523
|
-
opStackTraces: process.env.NODE_ENV !== "production" ? /* @__PURE__ */ new Map() : void 0
|
|
5524
|
-
};
|
|
5525
|
-
const doNotBatchUpdates = (cb) => cb();
|
|
5526
|
-
const batchUpdates = config.unstable_batchedUpdates ?? doNotBatchUpdates;
|
|
5527
|
-
let lastTokenKey;
|
|
5528
|
-
function onStatusDidChange(newStatus) {
|
|
5529
|
-
const authValue = managedSocket.authValue;
|
|
5530
|
-
if (authValue !== null) {
|
|
5531
|
-
const tokenKey = getAuthBearerHeaderFromAuthValue(authValue);
|
|
5532
|
-
if (tokenKey !== lastTokenKey) {
|
|
5533
|
-
lastTokenKey = tokenKey;
|
|
5534
|
-
if (authValue.type === "secret") {
|
|
5535
|
-
const token = authValue.token.parsed;
|
|
5536
|
-
context.staticSessionInfo.set({
|
|
5537
|
-
userId: token.k === "sec-legacy" /* SECRET_LEGACY */ ? token.id : token.uid,
|
|
5538
|
-
userInfo: token.k === "sec-legacy" /* SECRET_LEGACY */ ? token.info : token.ui
|
|
5539
|
-
});
|
|
5540
|
-
} else {
|
|
5541
|
-
context.staticSessionInfo.set({
|
|
5542
|
-
userId: void 0,
|
|
5543
|
-
userInfo: void 0
|
|
5544
|
-
});
|
|
5545
|
-
}
|
|
5546
|
-
}
|
|
5547
|
-
}
|
|
5548
|
-
batchUpdates(() => {
|
|
5549
|
-
eventHub.status.notify(newStatus);
|
|
5550
|
-
notifySelfChanged(doNotBatchUpdates);
|
|
5551
|
-
});
|
|
5552
|
-
}
|
|
5553
|
-
let _connectionLossTimerId;
|
|
5554
|
-
let _hasLostConnection = false;
|
|
5555
|
-
function handleConnectionLossEvent(newStatus) {
|
|
5556
|
-
if (newStatus === "reconnecting") {
|
|
5557
|
-
_connectionLossTimerId = setTimeout(() => {
|
|
5558
|
-
batchUpdates(() => {
|
|
5559
|
-
eventHub.lostConnection.notify("lost");
|
|
5560
|
-
_hasLostConnection = true;
|
|
5561
|
-
context.others.clearOthers();
|
|
5562
|
-
notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
|
|
5563
|
-
});
|
|
5564
|
-
}, config.lostConnectionTimeout);
|
|
5565
|
-
} else {
|
|
5566
|
-
clearTimeout(_connectionLossTimerId);
|
|
5567
|
-
if (_hasLostConnection) {
|
|
5568
|
-
if (newStatus === "disconnected") {
|
|
5569
|
-
batchUpdates(() => {
|
|
5570
|
-
eventHub.lostConnection.notify("failed");
|
|
5571
|
-
});
|
|
5572
|
-
} else {
|
|
5573
|
-
batchUpdates(() => {
|
|
5574
|
-
eventHub.lostConnection.notify("restored");
|
|
5575
|
-
});
|
|
5576
|
-
}
|
|
5577
|
-
_hasLostConnection = false;
|
|
5578
|
-
}
|
|
5579
|
-
}
|
|
5580
|
-
}
|
|
5581
|
-
function onDidConnect() {
|
|
5582
|
-
context.buffer.presenceUpdates = {
|
|
5583
|
-
type: "full",
|
|
5584
|
-
data: (
|
|
5585
|
-
// Because context.me.current is a readonly object, we'll have to
|
|
5586
|
-
// make a copy here. Otherwise, type errors happen later when
|
|
5587
|
-
// "patching" my presence.
|
|
5588
|
-
{ ...context.myPresence.current }
|
|
5589
|
-
)
|
|
5590
|
-
};
|
|
5591
|
-
if (_getStorage$ !== null) {
|
|
5592
|
-
refreshStorage({ flush: false });
|
|
5593
|
-
}
|
|
5594
|
-
flushNowOrSoon();
|
|
5595
|
-
}
|
|
5596
|
-
function onDidDisconnect() {
|
|
5597
|
-
clearTimeout(context.buffer.flushTimerID);
|
|
5333
|
+
function onDidDisconnect() {
|
|
5334
|
+
clearTimeout(context.buffer.flushTimerID);
|
|
5598
5335
|
}
|
|
5599
5336
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
5600
5337
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -6592,16 +6329,411 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6592
6329
|
ydoc: eventHub.ydoc.observable,
|
|
6593
6330
|
comments: eventHub.comments.observable
|
|
6594
6331
|
};
|
|
6595
|
-
|
|
6596
|
-
config.roomId,
|
|
6597
|
-
delegates.authenticate,
|
|
6598
|
-
fetchClientApi
|
|
6599
|
-
);
|
|
6600
|
-
async function fetchNotificationsJson(endpoint, options2) {
|
|
6332
|
+
async function fetchCommentsApi(endpoint, params, options2) {
|
|
6601
6333
|
const authValue = await delegates.authenticate();
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6334
|
+
return fetchClientApi(config.roomId, endpoint, authValue, options2, params);
|
|
6335
|
+
}
|
|
6336
|
+
async function fetchCommentsJson(endpoint, options2, params) {
|
|
6337
|
+
const response = await fetchCommentsApi(endpoint, params, options2);
|
|
6338
|
+
if (!response.ok) {
|
|
6339
|
+
if (response.status >= 400 && response.status < 600) {
|
|
6340
|
+
let error3;
|
|
6341
|
+
try {
|
|
6342
|
+
const errorBody = await response.json();
|
|
6343
|
+
error3 = new CommentsApiError(
|
|
6344
|
+
errorBody.message,
|
|
6345
|
+
response.status,
|
|
6346
|
+
errorBody
|
|
6347
|
+
);
|
|
6348
|
+
} catch {
|
|
6349
|
+
error3 = new CommentsApiError(response.statusText, response.status);
|
|
6350
|
+
}
|
|
6351
|
+
throw error3;
|
|
6352
|
+
}
|
|
6353
|
+
}
|
|
6354
|
+
let body;
|
|
6355
|
+
try {
|
|
6356
|
+
body = await response.json();
|
|
6357
|
+
} catch {
|
|
6358
|
+
body = {};
|
|
6359
|
+
}
|
|
6360
|
+
return body;
|
|
6361
|
+
}
|
|
6362
|
+
async function getThreadsSince(options2) {
|
|
6363
|
+
const response = await fetchCommentsApi(
|
|
6364
|
+
"/threads",
|
|
6365
|
+
{
|
|
6366
|
+
since: options2?.since?.toISOString()
|
|
6367
|
+
},
|
|
6368
|
+
{
|
|
6369
|
+
headers: {
|
|
6370
|
+
"Content-Type": "application/json"
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
);
|
|
6374
|
+
if (response.ok) {
|
|
6375
|
+
const json = await response.json();
|
|
6376
|
+
return {
|
|
6377
|
+
threads: {
|
|
6378
|
+
updated: json.data.map(convertToThreadData),
|
|
6379
|
+
deleted: json.deletedThreads.map(convertToThreadDeleteInfo)
|
|
6380
|
+
},
|
|
6381
|
+
inboxNotifications: {
|
|
6382
|
+
updated: json.inboxNotifications.map(convertToInboxNotificationData),
|
|
6383
|
+
deleted: json.deletedInboxNotifications.map(
|
|
6384
|
+
convertToInboxNotificationDeleteInfo
|
|
6385
|
+
)
|
|
6386
|
+
},
|
|
6387
|
+
requestedAt: new Date(json.meta.requestedAt)
|
|
6388
|
+
};
|
|
6389
|
+
} else if (response.status === 404) {
|
|
6390
|
+
return {
|
|
6391
|
+
threads: {
|
|
6392
|
+
updated: [],
|
|
6393
|
+
deleted: []
|
|
6394
|
+
},
|
|
6395
|
+
inboxNotifications: {
|
|
6396
|
+
updated: [],
|
|
6397
|
+
deleted: []
|
|
6398
|
+
},
|
|
6399
|
+
requestedAt: /* @__PURE__ */ new Date()
|
|
6400
|
+
};
|
|
6401
|
+
} else {
|
|
6402
|
+
throw new Error("There was an error while getting threads.");
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
async function getThreads(options2) {
|
|
6406
|
+
let query;
|
|
6407
|
+
if (options2?.query) {
|
|
6408
|
+
query = objectToQuery(options2.query);
|
|
6409
|
+
}
|
|
6410
|
+
const response = await fetchCommentsApi(
|
|
6411
|
+
"/threads",
|
|
6412
|
+
{
|
|
6413
|
+
query
|
|
6414
|
+
},
|
|
6415
|
+
{
|
|
6416
|
+
headers: {
|
|
6417
|
+
"Content-Type": "application/json"
|
|
6418
|
+
}
|
|
6419
|
+
}
|
|
6420
|
+
);
|
|
6421
|
+
if (response.ok) {
|
|
6422
|
+
const json = await response.json();
|
|
6423
|
+
return {
|
|
6424
|
+
threads: json.data.map(convertToThreadData),
|
|
6425
|
+
inboxNotifications: json.inboxNotifications.map(
|
|
6426
|
+
convertToInboxNotificationData
|
|
6427
|
+
),
|
|
6428
|
+
requestedAt: new Date(json.meta.requestedAt)
|
|
6429
|
+
};
|
|
6430
|
+
} else if (response.status === 404) {
|
|
6431
|
+
return {
|
|
6432
|
+
threads: [],
|
|
6433
|
+
inboxNotifications: [],
|
|
6434
|
+
deletedThreads: [],
|
|
6435
|
+
deletedInboxNotifications: [],
|
|
6436
|
+
requestedAt: /* @__PURE__ */ new Date()
|
|
6437
|
+
};
|
|
6438
|
+
} else {
|
|
6439
|
+
throw new Error("There was an error while getting threads.");
|
|
6440
|
+
}
|
|
6441
|
+
}
|
|
6442
|
+
async function getThread(threadId) {
|
|
6443
|
+
const response = await fetchCommentsApi(
|
|
6444
|
+
`/thread-with-notification/${threadId}`
|
|
6445
|
+
);
|
|
6446
|
+
if (response.ok) {
|
|
6447
|
+
const json = await response.json();
|
|
6448
|
+
return {
|
|
6449
|
+
thread: convertToThreadData(json.thread),
|
|
6450
|
+
inboxNotification: json.inboxNotification ? convertToInboxNotificationData(json.inboxNotification) : void 0
|
|
6451
|
+
};
|
|
6452
|
+
} else if (response.status === 404) {
|
|
6453
|
+
return {
|
|
6454
|
+
thread: void 0,
|
|
6455
|
+
inboxNotification: void 0
|
|
6456
|
+
};
|
|
6457
|
+
} else {
|
|
6458
|
+
throw new Error(`There was an error while getting thread ${threadId}.`);
|
|
6459
|
+
}
|
|
6460
|
+
}
|
|
6461
|
+
async function createThread({
|
|
6462
|
+
metadata,
|
|
6463
|
+
body,
|
|
6464
|
+
commentId = createCommentId(),
|
|
6465
|
+
threadId = createThreadId(),
|
|
6466
|
+
attachmentIds
|
|
6467
|
+
}) {
|
|
6468
|
+
const thread = await fetchCommentsJson("/threads", {
|
|
6469
|
+
method: "POST",
|
|
6470
|
+
headers: {
|
|
6471
|
+
"Content-Type": "application/json"
|
|
6472
|
+
},
|
|
6473
|
+
body: JSON.stringify({
|
|
6474
|
+
id: threadId,
|
|
6475
|
+
comment: {
|
|
6476
|
+
id: commentId,
|
|
6477
|
+
body,
|
|
6478
|
+
attachmentIds
|
|
6479
|
+
},
|
|
6480
|
+
metadata
|
|
6481
|
+
})
|
|
6482
|
+
});
|
|
6483
|
+
return convertToThreadData(thread);
|
|
6484
|
+
}
|
|
6485
|
+
async function deleteThread(threadId) {
|
|
6486
|
+
await fetchCommentsJson(`/threads/${encodeURIComponent(threadId)}`, {
|
|
6487
|
+
method: "DELETE"
|
|
6488
|
+
});
|
|
6489
|
+
}
|
|
6490
|
+
async function editThreadMetadata({
|
|
6491
|
+
metadata,
|
|
6492
|
+
threadId
|
|
6493
|
+
}) {
|
|
6494
|
+
return await fetchCommentsJson(
|
|
6495
|
+
`/threads/${encodeURIComponent(threadId)}/metadata`,
|
|
6496
|
+
{
|
|
6497
|
+
method: "POST",
|
|
6498
|
+
headers: {
|
|
6499
|
+
"Content-Type": "application/json"
|
|
6500
|
+
},
|
|
6501
|
+
body: JSON.stringify(metadata)
|
|
6502
|
+
}
|
|
6503
|
+
);
|
|
6504
|
+
}
|
|
6505
|
+
async function markThreadAsResolved(threadId) {
|
|
6506
|
+
await fetchCommentsJson(
|
|
6507
|
+
`/threads/${encodeURIComponent(threadId)}/mark-as-resolved`,
|
|
6508
|
+
{
|
|
6509
|
+
method: "POST"
|
|
6510
|
+
}
|
|
6511
|
+
);
|
|
6512
|
+
}
|
|
6513
|
+
async function markThreadAsUnresolved(threadId) {
|
|
6514
|
+
await fetchCommentsJson(
|
|
6515
|
+
`/threads/${encodeURIComponent(threadId)}/mark-as-unresolved`,
|
|
6516
|
+
{
|
|
6517
|
+
method: "POST"
|
|
6518
|
+
}
|
|
6519
|
+
);
|
|
6520
|
+
}
|
|
6521
|
+
async function createComment({
|
|
6522
|
+
threadId,
|
|
6523
|
+
commentId = createCommentId(),
|
|
6524
|
+
body,
|
|
6525
|
+
attachmentIds
|
|
6526
|
+
}) {
|
|
6527
|
+
const comment = await fetchCommentsJson(
|
|
6528
|
+
`/threads/${encodeURIComponent(threadId)}/comments`,
|
|
6529
|
+
{
|
|
6530
|
+
method: "POST",
|
|
6531
|
+
headers: {
|
|
6532
|
+
"Content-Type": "application/json"
|
|
6533
|
+
},
|
|
6534
|
+
body: JSON.stringify({
|
|
6535
|
+
id: commentId,
|
|
6536
|
+
body,
|
|
6537
|
+
attachmentIds
|
|
6538
|
+
})
|
|
6539
|
+
}
|
|
6540
|
+
);
|
|
6541
|
+
return convertToCommentData(comment);
|
|
6542
|
+
}
|
|
6543
|
+
async function editComment({
|
|
6544
|
+
threadId,
|
|
6545
|
+
commentId,
|
|
6546
|
+
body,
|
|
6547
|
+
attachmentIds
|
|
6548
|
+
}) {
|
|
6549
|
+
const comment = await fetchCommentsJson(
|
|
6550
|
+
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
6551
|
+
commentId
|
|
6552
|
+
)}`,
|
|
6553
|
+
{
|
|
6554
|
+
method: "POST",
|
|
6555
|
+
headers: {
|
|
6556
|
+
"Content-Type": "application/json"
|
|
6557
|
+
},
|
|
6558
|
+
body: JSON.stringify({
|
|
6559
|
+
body,
|
|
6560
|
+
attachmentIds
|
|
6561
|
+
})
|
|
6562
|
+
}
|
|
6563
|
+
);
|
|
6564
|
+
return convertToCommentData(comment);
|
|
6565
|
+
}
|
|
6566
|
+
async function deleteComment2({
|
|
6567
|
+
threadId,
|
|
6568
|
+
commentId
|
|
6569
|
+
}) {
|
|
6570
|
+
await fetchCommentsJson(
|
|
6571
|
+
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
6572
|
+
commentId
|
|
6573
|
+
)}`,
|
|
6574
|
+
{
|
|
6575
|
+
method: "DELETE"
|
|
6576
|
+
}
|
|
6577
|
+
);
|
|
6578
|
+
}
|
|
6579
|
+
async function addReaction2({
|
|
6580
|
+
threadId,
|
|
6581
|
+
commentId,
|
|
6582
|
+
emoji
|
|
6583
|
+
}) {
|
|
6584
|
+
const reaction = await fetchCommentsJson(
|
|
6585
|
+
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
6586
|
+
commentId
|
|
6587
|
+
)}/reactions`,
|
|
6588
|
+
{
|
|
6589
|
+
method: "POST",
|
|
6590
|
+
headers: {
|
|
6591
|
+
"Content-Type": "application/json"
|
|
6592
|
+
},
|
|
6593
|
+
body: JSON.stringify({ emoji })
|
|
6594
|
+
}
|
|
6595
|
+
);
|
|
6596
|
+
return convertToCommentUserReaction(reaction);
|
|
6597
|
+
}
|
|
6598
|
+
async function removeReaction2({
|
|
6599
|
+
threadId,
|
|
6600
|
+
commentId,
|
|
6601
|
+
emoji
|
|
6602
|
+
}) {
|
|
6603
|
+
await fetchCommentsJson(
|
|
6604
|
+
`/threads/${encodeURIComponent(threadId)}/comments/${encodeURIComponent(
|
|
6605
|
+
commentId
|
|
6606
|
+
)}/reactions/${encodeURIComponent(emoji)}`,
|
|
6607
|
+
{
|
|
6608
|
+
method: "DELETE"
|
|
6609
|
+
}
|
|
6610
|
+
);
|
|
6611
|
+
}
|
|
6612
|
+
function prepareAttachment(file) {
|
|
6613
|
+
return {
|
|
6614
|
+
type: "localAttachment",
|
|
6615
|
+
status: "idle",
|
|
6616
|
+
id: createCommentAttachmentId(),
|
|
6617
|
+
name: file.name,
|
|
6618
|
+
size: file.size,
|
|
6619
|
+
mimeType: file.type,
|
|
6620
|
+
file
|
|
6621
|
+
};
|
|
6622
|
+
}
|
|
6623
|
+
async function uploadAttachment(attachment, options2 = {}) {
|
|
6624
|
+
const abortSignal = options2.signal;
|
|
6625
|
+
const abortError = abortSignal ? new DOMException(
|
|
6626
|
+
`Upload of attachment ${attachment.id} was aborted.`,
|
|
6627
|
+
"AbortError"
|
|
6628
|
+
) : void 0;
|
|
6629
|
+
if (abortSignal?.aborted) {
|
|
6630
|
+
throw abortError;
|
|
6631
|
+
}
|
|
6632
|
+
if (attachment.size <= ATTACHMENT_PART_SIZE) {
|
|
6633
|
+
return fetchCommentsJson(
|
|
6634
|
+
`/attachments/${encodeURIComponent(attachment.id)}/upload/${encodeURIComponent(attachment.name)}`,
|
|
6635
|
+
{
|
|
6636
|
+
method: "PUT",
|
|
6637
|
+
body: attachment.file,
|
|
6638
|
+
signal: abortSignal
|
|
6639
|
+
}
|
|
6640
|
+
);
|
|
6641
|
+
} else {
|
|
6642
|
+
let uploadId;
|
|
6643
|
+
const uploadedParts = [];
|
|
6644
|
+
try {
|
|
6645
|
+
const createMultiPartUpload = await fetchCommentsJson(
|
|
6646
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(attachment.name)}`,
|
|
6647
|
+
{
|
|
6648
|
+
method: "POST",
|
|
6649
|
+
signal: abortSignal
|
|
6650
|
+
}
|
|
6651
|
+
);
|
|
6652
|
+
uploadId = createMultiPartUpload.uploadId;
|
|
6653
|
+
const parts = splitFileIntoParts(attachment.file);
|
|
6654
|
+
if (abortSignal?.aborted) {
|
|
6655
|
+
throw abortError;
|
|
6656
|
+
}
|
|
6657
|
+
const batches = chunk(parts, ATTACHMENT_PART_BATCH_SIZE);
|
|
6658
|
+
for (const parts2 of batches) {
|
|
6659
|
+
const uploadedPartsPromises = [];
|
|
6660
|
+
for (const { part, partNumber } of parts2) {
|
|
6661
|
+
uploadedPartsPromises.push(
|
|
6662
|
+
fetchCommentsJson(
|
|
6663
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/${encodeURIComponent(partNumber)}`,
|
|
6664
|
+
{
|
|
6665
|
+
method: "PUT",
|
|
6666
|
+
body: part,
|
|
6667
|
+
signal: abortSignal
|
|
6668
|
+
}
|
|
6669
|
+
)
|
|
6670
|
+
);
|
|
6671
|
+
}
|
|
6672
|
+
uploadedParts.push(...await Promise.all(uploadedPartsPromises));
|
|
6673
|
+
}
|
|
6674
|
+
if (abortSignal?.aborted) {
|
|
6675
|
+
throw abortError;
|
|
6676
|
+
}
|
|
6677
|
+
const sortedUploadedParts = uploadedParts.sort(
|
|
6678
|
+
(a, b) => a.partNumber - b.partNumber
|
|
6679
|
+
);
|
|
6680
|
+
return fetchCommentsJson(
|
|
6681
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}/complete`,
|
|
6682
|
+
{
|
|
6683
|
+
method: "POST",
|
|
6684
|
+
headers: {
|
|
6685
|
+
"Content-Type": "application/json"
|
|
6686
|
+
},
|
|
6687
|
+
body: JSON.stringify({ parts: sortedUploadedParts }),
|
|
6688
|
+
signal: abortSignal
|
|
6689
|
+
}
|
|
6690
|
+
);
|
|
6691
|
+
} catch (error3) {
|
|
6692
|
+
if (uploadId && error3?.name && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
|
|
6693
|
+
await fetchCommentsApi(
|
|
6694
|
+
`/attachments/${encodeURIComponent(attachment.id)}/multipart/${encodeURIComponent(uploadId)}`,
|
|
6695
|
+
void 0,
|
|
6696
|
+
{
|
|
6697
|
+
method: "DELETE"
|
|
6698
|
+
}
|
|
6699
|
+
);
|
|
6700
|
+
}
|
|
6701
|
+
throw error3;
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
async function getAttachmentUrls(attachmentIds) {
|
|
6706
|
+
const { urls } = await fetchCommentsJson(
|
|
6707
|
+
"/attachments/presigned-urls",
|
|
6708
|
+
{
|
|
6709
|
+
method: "POST",
|
|
6710
|
+
headers: {
|
|
6711
|
+
"Content-Type": "application/json"
|
|
6712
|
+
},
|
|
6713
|
+
body: JSON.stringify({ attachmentIds })
|
|
6714
|
+
}
|
|
6715
|
+
);
|
|
6716
|
+
return urls;
|
|
6717
|
+
}
|
|
6718
|
+
const batchedGetAttachmentUrls = new Batch(
|
|
6719
|
+
async (batchedAttachmentIds) => {
|
|
6720
|
+
const attachmentIds = batchedAttachmentIds.flat();
|
|
6721
|
+
const attachmentUrls = await getAttachmentUrls(attachmentIds);
|
|
6722
|
+
return attachmentUrls.map(
|
|
6723
|
+
(url) => url ?? new Error("There was an error while getting this attachment's URL")
|
|
6724
|
+
);
|
|
6725
|
+
},
|
|
6726
|
+
{ delay: GET_ATTACHMENT_URLS_BATCH_DELAY }
|
|
6727
|
+
);
|
|
6728
|
+
const attachmentUrlsStore = createBatchStore(batchedGetAttachmentUrls);
|
|
6729
|
+
function getAttachmentUrl(attachmentId) {
|
|
6730
|
+
return batchedGetAttachmentUrls.get(attachmentId);
|
|
6731
|
+
}
|
|
6732
|
+
async function fetchNotificationsJson(endpoint, options2) {
|
|
6733
|
+
const authValue = await delegates.authenticate();
|
|
6734
|
+
const response = await fetchClientApi(
|
|
6735
|
+
config.roomId,
|
|
6736
|
+
endpoint,
|
|
6605
6737
|
authValue,
|
|
6606
6738
|
options2
|
|
6607
6739
|
);
|
|
@@ -6706,7 +6838,8 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6706
6838
|
// These exist only for our E2E testing app
|
|
6707
6839
|
explicitClose: (event) => managedSocket._privateSendMachineEvent({ type: "EXPLICIT_SOCKET_CLOSE", event }),
|
|
6708
6840
|
rawSend: (data) => managedSocket.send(data)
|
|
6709
|
-
}
|
|
6841
|
+
},
|
|
6842
|
+
attachmentUrlsStore
|
|
6710
6843
|
},
|
|
6711
6844
|
id: config.roomId,
|
|
6712
6845
|
subscribe: makeClassicSubscribeFn(events),
|
|
@@ -6747,10 +6880,27 @@ ${Array.from(traces).join("\n\n")}`
|
|
|
6747
6880
|
// Presence
|
|
6748
6881
|
getPresence: () => context.myPresence.current,
|
|
6749
6882
|
getOthers: () => context.others.current,
|
|
6883
|
+
// Comments
|
|
6884
|
+
getThreads,
|
|
6885
|
+
getThreadsSince,
|
|
6886
|
+
getThread,
|
|
6887
|
+
createThread,
|
|
6888
|
+
deleteThread,
|
|
6889
|
+
editThreadMetadata,
|
|
6890
|
+
markThreadAsResolved,
|
|
6891
|
+
markThreadAsUnresolved,
|
|
6892
|
+
createComment,
|
|
6893
|
+
editComment,
|
|
6894
|
+
deleteComment: deleteComment2,
|
|
6895
|
+
addReaction: addReaction2,
|
|
6896
|
+
removeReaction: removeReaction2,
|
|
6897
|
+
prepareAttachment,
|
|
6898
|
+
uploadAttachment,
|
|
6899
|
+
getAttachmentUrl,
|
|
6900
|
+
// Notifications
|
|
6750
6901
|
getNotificationSettings,
|
|
6751
6902
|
updateNotificationSettings,
|
|
6752
|
-
markInboxNotificationAsRead
|
|
6753
|
-
...commentsApi
|
|
6903
|
+
markInboxNotificationAsRead
|
|
6754
6904
|
},
|
|
6755
6905
|
// Explictly make the internal field non-enumerable, to avoid aggressive
|
|
6756
6906
|
// freezing when used with Immer
|
|
@@ -7541,7 +7691,7 @@ function createClient(options) {
|
|
|
7541
7691
|
() => !resolveUsers,
|
|
7542
7692
|
"Set the resolveUsers option in createClient to specify user info."
|
|
7543
7693
|
);
|
|
7544
|
-
const
|
|
7694
|
+
const batchedResolveUsers = new Batch(
|
|
7545
7695
|
async (batchedUserIds) => {
|
|
7546
7696
|
const userIds = batchedUserIds.flat();
|
|
7547
7697
|
const users = await resolveUsers?.({ userIds });
|
|
@@ -7550,12 +7700,13 @@ function createClient(options) {
|
|
|
7550
7700
|
},
|
|
7551
7701
|
{ delay: RESOLVE_USERS_BATCH_DELAY }
|
|
7552
7702
|
);
|
|
7703
|
+
const usersStore = createBatchStore(batchedResolveUsers);
|
|
7553
7704
|
const resolveRoomsInfo = clientOptions.resolveRoomsInfo;
|
|
7554
7705
|
const warnIfNoResolveRoomsInfo = createDevelopmentWarning(
|
|
7555
7706
|
() => !resolveRoomsInfo,
|
|
7556
7707
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
7557
7708
|
);
|
|
7558
|
-
const
|
|
7709
|
+
const batchedResolveRoomsInfo = new Batch(
|
|
7559
7710
|
async (batchedRoomIds) => {
|
|
7560
7711
|
const roomIds = batchedRoomIds.flat();
|
|
7561
7712
|
const roomsInfo = await resolveRoomsInfo?.({ roomIds });
|
|
@@ -7564,6 +7715,7 @@ function createClient(options) {
|
|
|
7564
7715
|
},
|
|
7565
7716
|
{ delay: RESOLVE_ROOMS_INFO_BATCH_DELAY }
|
|
7566
7717
|
);
|
|
7718
|
+
const roomsInfoStore = createBatchStore(batchedResolveRoomsInfo);
|
|
7567
7719
|
return Object.defineProperty(
|
|
7568
7720
|
{
|
|
7569
7721
|
enterRoom,
|
|
@@ -8469,6 +8621,7 @@ export {
|
|
|
8469
8621
|
assert,
|
|
8470
8622
|
assertNever,
|
|
8471
8623
|
b64decode,
|
|
8624
|
+
chunk,
|
|
8472
8625
|
cloneLson,
|
|
8473
8626
|
fancy_console_exports as console,
|
|
8474
8627
|
convertToCommentData,
|