@liveblocks/react 2.13.3-emails1 → 2.14.0-lexical1
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/_private.d.mts +6 -3
- package/dist/_private.d.ts +6 -3
- package/dist/_private.js +18 -7
- package/dist/_private.js.map +1 -1
- package/dist/_private.mjs +21 -10
- package/dist/_private.mjs.map +1 -1
- package/dist/{chunk-BRCWZCNY.mjs → chunk-A4RI4GZW.mjs} +502 -351
- package/dist/chunk-A4RI4GZW.mjs.map +1 -0
- package/dist/{chunk-ZJOZQBXZ.mjs → chunk-CI2PWFZS.mjs} +2 -2
- package/dist/{chunk-X4DDEZYL.js → chunk-N33NEN5R.js} +496 -345
- package/dist/chunk-N33NEN5R.js.map +1 -0
- package/dist/{chunk-ZZZADXFA.js → chunk-QJWT5TQ2.js} +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/index.mjs +2 -2
- package/dist/{room-Rl_QnQMY.d.mts → room-FAbgoSMw.d.mts} +60 -67
- package/dist/{room-Rl_QnQMY.d.ts → room-FAbgoSMw.d.ts} +60 -67
- package/dist/suspense.d.mts +1 -1
- package/dist/suspense.d.ts +1 -1
- package/dist/suspense.js +4 -4
- package/dist/suspense.mjs +2 -2
- package/package.json +3 -3
- package/dist/chunk-BRCWZCNY.mjs.map +0 -1
- package/dist/chunk-X4DDEZYL.js.map +0 -1
- /package/dist/{chunk-ZJOZQBXZ.mjs.map → chunk-CI2PWFZS.mjs.map} +0 -0
- /package/dist/{chunk-ZZZADXFA.js.map → chunk-QJWT5TQ2.js.map} +0 -0
|
@@ -132,6 +132,8 @@ var use = (
|
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
|
|
135
|
+
|
|
136
|
+
|
|
135
137
|
// src/lib/autobind.ts
|
|
136
138
|
function autobind(self) {
|
|
137
139
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -202,36 +204,35 @@ function sanitizeThread(thread) {
|
|
|
202
204
|
return thread;
|
|
203
205
|
}
|
|
204
206
|
var ThreadDB = class _ThreadDB {
|
|
205
|
-
|
|
207
|
+
#byId;
|
|
208
|
+
#asc;
|
|
209
|
+
#desc;
|
|
210
|
+
// This signal will be notified on every mutation
|
|
211
|
+
|
|
206
212
|
constructor() {
|
|
207
|
-
this
|
|
213
|
+
this.#asc = _core.SortedList.from([], (t1, t2) => {
|
|
208
214
|
const d1 = t1.createdAt;
|
|
209
215
|
const d2 = t2.createdAt;
|
|
210
216
|
return d1 < d2 ? true : d1 === d2 ? t1.id < t2.id : false;
|
|
211
217
|
});
|
|
212
|
-
this
|
|
218
|
+
this.#desc = _core.SortedList.from([], (t1, t2) => {
|
|
213
219
|
const d2 = t2.updatedAt;
|
|
214
220
|
const d1 = t1.updatedAt;
|
|
215
221
|
return d2 < d1 ? true : d2 === d1 ? t2.id < t1.id : false;
|
|
216
222
|
});
|
|
217
|
-
this
|
|
218
|
-
this.
|
|
223
|
+
this.#byId = /* @__PURE__ */ new Map();
|
|
224
|
+
this.signal = new (0, _core.MutableSignal)(this);
|
|
219
225
|
}
|
|
220
226
|
//
|
|
221
227
|
// Public APIs
|
|
222
228
|
//
|
|
223
229
|
clone() {
|
|
224
230
|
const newPool = new _ThreadDB();
|
|
225
|
-
newPool
|
|
226
|
-
newPool
|
|
227
|
-
newPool
|
|
228
|
-
newPool._version = this._version;
|
|
231
|
+
newPool.#byId = new Map(this.#byId);
|
|
232
|
+
newPool.#asc = this.#asc.clone();
|
|
233
|
+
newPool.#desc = this.#desc.clone();
|
|
229
234
|
return newPool;
|
|
230
235
|
}
|
|
231
|
-
/** Gets the transaction count for this DB. Increments any time the DB is modified. */
|
|
232
|
-
get version() {
|
|
233
|
-
return this._version;
|
|
234
|
-
}
|
|
235
236
|
/** Returns an existing thread by ID. Will never return a deleted thread. */
|
|
236
237
|
get(threadId) {
|
|
237
238
|
const thread = this.getEvenIfDeleted(threadId);
|
|
@@ -239,24 +240,26 @@ var ThreadDB = class _ThreadDB {
|
|
|
239
240
|
}
|
|
240
241
|
/** Returns the (possibly deleted) thread by ID. */
|
|
241
242
|
getEvenIfDeleted(threadId) {
|
|
242
|
-
return this.
|
|
243
|
+
return this.#byId.get(threadId);
|
|
243
244
|
}
|
|
244
245
|
/** Adds or updates a thread in the DB. If the newly given thread is a deleted one, it will get deleted. */
|
|
245
246
|
upsert(thread) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (toRemove
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
247
|
+
this.signal.mutate(() => {
|
|
248
|
+
thread = sanitizeThread(thread);
|
|
249
|
+
const id = thread.id;
|
|
250
|
+
const toRemove = this.#byId.get(id);
|
|
251
|
+
if (toRemove) {
|
|
252
|
+
if (toRemove.deletedAt) return false;
|
|
253
|
+
this.#asc.remove(toRemove);
|
|
254
|
+
this.#desc.remove(toRemove);
|
|
255
|
+
}
|
|
256
|
+
if (!thread.deletedAt) {
|
|
257
|
+
this.#asc.add(thread);
|
|
258
|
+
this.#desc.add(thread);
|
|
259
|
+
}
|
|
260
|
+
this.#byId.set(id, thread);
|
|
261
|
+
return true;
|
|
262
|
+
});
|
|
260
263
|
}
|
|
261
264
|
/** Like .upsert(), except it won't update if a thread by this ID already exists. */
|
|
262
265
|
// TODO Consider renaming this to just .upsert(). I'm not sure if we really
|
|
@@ -272,7 +275,7 @@ var ThreadDB = class _ThreadDB {
|
|
|
272
275
|
* queries, but it can still be accessed via `.getEvenIfDeleted()`.
|
|
273
276
|
*/
|
|
274
277
|
delete(threadId, deletedAt) {
|
|
275
|
-
const existing = this.
|
|
278
|
+
const existing = this.#byId.get(threadId);
|
|
276
279
|
if (existing && !existing.deletedAt) {
|
|
277
280
|
this.upsert({ ...existing, deletedAt, updatedAt: deletedAt });
|
|
278
281
|
}
|
|
@@ -289,7 +292,7 @@ var ThreadDB = class _ThreadDB {
|
|
|
289
292
|
* Will never return deleted threads in the result.
|
|
290
293
|
*/
|
|
291
294
|
findMany(roomId, query, direction) {
|
|
292
|
-
const index = direction === "desc" ? this
|
|
295
|
+
const index = direction === "desc" ? this.#desc : this.#asc;
|
|
293
296
|
const crit = [];
|
|
294
297
|
if (roomId !== void 0) {
|
|
295
298
|
crit.push((t) => t.roomId === roomId);
|
|
@@ -297,12 +300,6 @@ var ThreadDB = class _ThreadDB {
|
|
|
297
300
|
crit.push(makeThreadsFilter(query));
|
|
298
301
|
return Array.from(index.filter((t) => crit.every((pred) => pred(t))));
|
|
299
302
|
}
|
|
300
|
-
//
|
|
301
|
-
// Private APIs
|
|
302
|
-
//
|
|
303
|
-
touch() {
|
|
304
|
-
++this._version;
|
|
305
|
-
}
|
|
306
303
|
};
|
|
307
304
|
|
|
308
305
|
// src/umbrella-store.ts
|
|
@@ -339,62 +336,67 @@ function usify(promise) {
|
|
|
339
336
|
var noop2 = Promise.resolve();
|
|
340
337
|
var ASYNC_LOADING = Object.freeze({ isLoading: true });
|
|
341
338
|
var PaginatedResource = class {
|
|
339
|
+
|
|
340
|
+
#eventSource;
|
|
341
|
+
#fetchPage;
|
|
342
|
+
#paginationState;
|
|
343
|
+
// Should be null while in loading or error state!
|
|
344
|
+
#pendingFetchMore;
|
|
342
345
|
constructor(fetchPage) {
|
|
343
|
-
this
|
|
344
|
-
this
|
|
345
|
-
this
|
|
346
|
-
this
|
|
347
|
-
this.
|
|
348
|
-
this.observable = this._eventSource.observable;
|
|
346
|
+
this.#paginationState = null;
|
|
347
|
+
this.#fetchPage = fetchPage;
|
|
348
|
+
this.#eventSource = _core.makeEventSource.call(void 0, );
|
|
349
|
+
this.#pendingFetchMore = null;
|
|
350
|
+
this.observable = this.#eventSource.observable;
|
|
349
351
|
autobind(this);
|
|
350
352
|
}
|
|
351
|
-
patchPaginationState(patch) {
|
|
352
|
-
const state = this
|
|
353
|
+
#patchPaginationState(patch) {
|
|
354
|
+
const state = this.#paginationState;
|
|
353
355
|
if (state === null) return;
|
|
354
|
-
this
|
|
355
|
-
this.
|
|
356
|
+
this.#paginationState = { ...state, ...patch };
|
|
357
|
+
this.#eventSource.notify();
|
|
356
358
|
}
|
|
357
|
-
async
|
|
358
|
-
const state = this
|
|
359
|
+
async #fetchMore() {
|
|
360
|
+
const state = this.#paginationState;
|
|
359
361
|
if (!_optionalChain([state, 'optionalAccess', _3 => _3.cursor])) {
|
|
360
362
|
return;
|
|
361
363
|
}
|
|
362
|
-
this
|
|
364
|
+
this.#patchPaginationState({ isFetchingMore: true });
|
|
363
365
|
try {
|
|
364
|
-
const nextCursor = await this
|
|
365
|
-
this
|
|
366
|
+
const nextCursor = await this.#fetchPage(state.cursor);
|
|
367
|
+
this.#patchPaginationState({
|
|
366
368
|
cursor: nextCursor,
|
|
367
369
|
fetchMoreError: void 0,
|
|
368
370
|
isFetchingMore: false
|
|
369
371
|
});
|
|
370
372
|
} catch (err) {
|
|
371
|
-
this
|
|
373
|
+
this.#patchPaginationState({
|
|
372
374
|
isFetchingMore: false,
|
|
373
375
|
fetchMoreError: err
|
|
374
376
|
});
|
|
375
377
|
}
|
|
376
378
|
}
|
|
377
379
|
fetchMore() {
|
|
378
|
-
const state = this
|
|
380
|
+
const state = this.#paginationState;
|
|
379
381
|
if (_optionalChain([state, 'optionalAccess', _4 => _4.cursor]) === null) {
|
|
380
382
|
return noop2;
|
|
381
383
|
}
|
|
382
|
-
if (!this
|
|
383
|
-
this
|
|
384
|
-
this
|
|
384
|
+
if (!this.#pendingFetchMore) {
|
|
385
|
+
this.#pendingFetchMore = this.#fetchMore().finally(() => {
|
|
386
|
+
this.#pendingFetchMore = null;
|
|
385
387
|
});
|
|
386
388
|
}
|
|
387
|
-
return this
|
|
389
|
+
return this.#pendingFetchMore;
|
|
388
390
|
}
|
|
389
391
|
get() {
|
|
390
|
-
const usable = this
|
|
392
|
+
const usable = this.#cachedPromise;
|
|
391
393
|
if (usable === null || usable.status === "pending") {
|
|
392
394
|
return ASYNC_LOADING;
|
|
393
395
|
}
|
|
394
396
|
if (usable.status === "rejected") {
|
|
395
397
|
return { isLoading: false, error: usable.reason };
|
|
396
398
|
}
|
|
397
|
-
const state = this
|
|
399
|
+
const state = this.#paginationState;
|
|
398
400
|
return {
|
|
399
401
|
isLoading: false,
|
|
400
402
|
data: {
|
|
@@ -405,12 +407,13 @@ var PaginatedResource = class {
|
|
|
405
407
|
}
|
|
406
408
|
};
|
|
407
409
|
}
|
|
410
|
+
#cachedPromise = null;
|
|
408
411
|
waitUntilLoaded() {
|
|
409
|
-
if (this
|
|
410
|
-
return this
|
|
412
|
+
if (this.#cachedPromise) {
|
|
413
|
+
return this.#cachedPromise;
|
|
411
414
|
}
|
|
412
415
|
const initialFetcher = _core.autoRetry.call(void 0,
|
|
413
|
-
() => this
|
|
416
|
+
() => this.#fetchPage(
|
|
414
417
|
/* cursor */
|
|
415
418
|
void 0
|
|
416
419
|
),
|
|
@@ -419,7 +422,7 @@ var PaginatedResource = class {
|
|
|
419
422
|
);
|
|
420
423
|
const promise = usify(
|
|
421
424
|
initialFetcher.then((cursor) => {
|
|
422
|
-
this
|
|
425
|
+
this.#paginationState = {
|
|
423
426
|
cursor,
|
|
424
427
|
isFetchingMore: false,
|
|
425
428
|
fetchMoreError: void 0
|
|
@@ -427,29 +430,31 @@ var PaginatedResource = class {
|
|
|
427
430
|
})
|
|
428
431
|
);
|
|
429
432
|
promise.then(
|
|
430
|
-
() => this.
|
|
433
|
+
() => this.#eventSource.notify(),
|
|
431
434
|
() => {
|
|
432
|
-
this.
|
|
435
|
+
this.#eventSource.notify();
|
|
433
436
|
setTimeout(() => {
|
|
434
|
-
this
|
|
435
|
-
this.
|
|
437
|
+
this.#cachedPromise = null;
|
|
438
|
+
this.#eventSource.notify();
|
|
436
439
|
}, 5e3);
|
|
437
440
|
}
|
|
438
441
|
);
|
|
439
|
-
this
|
|
442
|
+
this.#cachedPromise = promise;
|
|
440
443
|
return promise;
|
|
441
444
|
}
|
|
442
445
|
};
|
|
443
446
|
var SinglePageResource = class {
|
|
447
|
+
|
|
448
|
+
#eventSource;
|
|
449
|
+
#fetchPage;
|
|
444
450
|
constructor(fetchPage) {
|
|
445
|
-
this
|
|
446
|
-
this
|
|
447
|
-
this.
|
|
448
|
-
this.observable = this._eventSource.observable;
|
|
451
|
+
this.#fetchPage = fetchPage;
|
|
452
|
+
this.#eventSource = _core.makeEventSource.call(void 0, );
|
|
453
|
+
this.observable = this.#eventSource.observable;
|
|
449
454
|
autobind(this);
|
|
450
455
|
}
|
|
451
456
|
get() {
|
|
452
|
-
const usable = this
|
|
457
|
+
const usable = this.#cachedPromise;
|
|
453
458
|
if (usable === null || usable.status === "pending") {
|
|
454
459
|
return ASYNC_LOADING;
|
|
455
460
|
}
|
|
@@ -461,95 +466,187 @@ var SinglePageResource = class {
|
|
|
461
466
|
data: void 0
|
|
462
467
|
};
|
|
463
468
|
}
|
|
469
|
+
#cachedPromise = null;
|
|
464
470
|
waitUntilLoaded() {
|
|
465
|
-
if (this
|
|
466
|
-
return this
|
|
471
|
+
if (this.#cachedPromise) {
|
|
472
|
+
return this.#cachedPromise;
|
|
467
473
|
}
|
|
468
474
|
const initialFetcher = _core.autoRetry.call(void 0,
|
|
469
|
-
() => this
|
|
475
|
+
() => this.#fetchPage(),
|
|
470
476
|
5,
|
|
471
477
|
[5e3, 5e3, 1e4, 15e3]
|
|
472
478
|
);
|
|
473
479
|
const promise = usify(initialFetcher);
|
|
474
480
|
promise.then(
|
|
475
|
-
() => this.
|
|
481
|
+
() => this.#eventSource.notify(),
|
|
476
482
|
() => {
|
|
477
|
-
this.
|
|
483
|
+
this.#eventSource.notify();
|
|
478
484
|
setTimeout(() => {
|
|
479
|
-
this
|
|
480
|
-
this.
|
|
485
|
+
this.#cachedPromise = null;
|
|
486
|
+
this.#eventSource.notify();
|
|
481
487
|
}, 5e3);
|
|
482
488
|
}
|
|
483
489
|
);
|
|
484
|
-
this
|
|
490
|
+
this.#cachedPromise = promise;
|
|
485
491
|
return promise;
|
|
486
492
|
}
|
|
487
493
|
};
|
|
488
494
|
var UmbrellaStore = class {
|
|
495
|
+
#client;
|
|
496
|
+
#syncSource;
|
|
497
|
+
//
|
|
498
|
+
// Internally, the UmbrellaStore keeps track of a few source signals that can
|
|
499
|
+
// be set and mutated individually. When any of those are mutated then the
|
|
500
|
+
// clean "external state" is recomputed.
|
|
501
|
+
//
|
|
502
|
+
// Mutate inputs... ...observe clean/consistent output!
|
|
503
|
+
//
|
|
504
|
+
// .-> Base ThreadDB ---------+ +----> Clean threads by ID (Part 1)
|
|
505
|
+
// / | |
|
|
506
|
+
// mutate ----> Base Notifications --+ | | +--> Clean notifications (Part 1)
|
|
507
|
+
// \ | | | | & notifications by ID
|
|
508
|
+
// | \ | | Apply | |
|
|
509
|
+
// | `-> OptimisticUpdates --+--+--> Optimistic --+-+--> Notification Settings (Part 2)
|
|
510
|
+
// \ | Updates |
|
|
511
|
+
// `------- etc etc ---------+ +--> History Versions (Part 3)
|
|
512
|
+
// ^
|
|
513
|
+
// |
|
|
514
|
+
// | ^ ^
|
|
515
|
+
// Signal | |
|
|
516
|
+
// or DerivedSignal DerivedSignals
|
|
517
|
+
// MutableSignal
|
|
518
|
+
//
|
|
519
|
+
//
|
|
520
|
+
// Input signals.
|
|
521
|
+
// (Can be mutated directly.)
|
|
522
|
+
//
|
|
523
|
+
|
|
524
|
+
// Exposes its signal under `.signal` prop
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
//
|
|
531
|
+
// Output signals.
|
|
532
|
+
// (Readonly, clean, consistent. With optimistic updates applied.)
|
|
533
|
+
//
|
|
534
|
+
// Note that the output of threadifications signal is the same as the ones for
|
|
535
|
+
// threads and notifications separately, but the threadifications signal will
|
|
536
|
+
// be updated whenever either of them change.
|
|
537
|
+
//
|
|
538
|
+
// TODO(vincent+nimesh) APIs like getRoomThreadsLoadingState should really also be modeled as output signals.
|
|
539
|
+
//
|
|
540
|
+
|
|
541
|
+
// Notifications
|
|
542
|
+
#notificationsLastRequestedAt = null;
|
|
543
|
+
// Keeps track of when we successfully requested an inbox notifications update for the last time. Will be `null` as long as the first successful fetch hasn't happened yet.
|
|
544
|
+
#notifications;
|
|
545
|
+
// Room Threads
|
|
546
|
+
#roomThreadsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
547
|
+
#roomThreads = /* @__PURE__ */ new Map();
|
|
548
|
+
// User Threads
|
|
549
|
+
#userThreadsLastRequestedAt = null;
|
|
550
|
+
#userThreads = /* @__PURE__ */ new Map();
|
|
551
|
+
// Room versions
|
|
552
|
+
#roomVersions = /* @__PURE__ */ new Map();
|
|
553
|
+
#roomVersionsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
554
|
+
// Room notification settings
|
|
555
|
+
#roomNotificationSettings = /* @__PURE__ */ new Map();
|
|
489
556
|
constructor(client) {
|
|
490
|
-
this
|
|
491
|
-
this
|
|
492
|
-
this._stateCached = null;
|
|
493
|
-
// Notifications
|
|
494
|
-
this._notificationsLastRequestedAt = null;
|
|
495
|
-
// Room Threads
|
|
496
|
-
this._roomThreadsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
497
|
-
this._roomThreads = /* @__PURE__ */ new Map();
|
|
498
|
-
// User Threads
|
|
499
|
-
this._userThreadsLastRequestedAt = null;
|
|
500
|
-
this._userThreads = /* @__PURE__ */ new Map();
|
|
501
|
-
// Room versions
|
|
502
|
-
this._roomVersions = /* @__PURE__ */ new Map();
|
|
503
|
-
this._roomVersionsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
504
|
-
// Room notification settings
|
|
505
|
-
this._roomNotificationSettings = /* @__PURE__ */ new Map();
|
|
506
|
-
this._client = client[_core.kInternal].as();
|
|
507
|
-
this._syncSource = this._client[_core.kInternal].createSyncSource();
|
|
557
|
+
this.#client = client[_core.kInternal].as();
|
|
558
|
+
this.#syncSource = this.#client[_core.kInternal].createSyncSource();
|
|
508
559
|
const inboxFetcher = async (cursor) => {
|
|
509
|
-
const result = await this.
|
|
560
|
+
const result = await this.#client.getInboxNotifications({ cursor });
|
|
510
561
|
this.updateThreadsAndNotifications(
|
|
511
562
|
result.threads,
|
|
512
563
|
result.inboxNotifications
|
|
513
564
|
);
|
|
514
|
-
if (this
|
|
515
|
-
this
|
|
565
|
+
if (this.#notificationsLastRequestedAt === null) {
|
|
566
|
+
this.#notificationsLastRequestedAt = result.requestedAt;
|
|
516
567
|
}
|
|
517
568
|
const nextCursor = result.nextCursor;
|
|
518
569
|
return nextCursor;
|
|
519
570
|
};
|
|
520
|
-
this
|
|
521
|
-
this.
|
|
571
|
+
this.#notifications = new PaginatedResource(inboxFetcher);
|
|
572
|
+
this.#notifications.observable.subscribe(
|
|
522
573
|
() => (
|
|
523
574
|
// Note that the store itself does not change, but it's only vehicle at
|
|
524
575
|
// the moment to trigger a re-render, so we'll do a no-op update here.
|
|
525
|
-
this.
|
|
576
|
+
this.invalidateEntireStore()
|
|
577
|
+
)
|
|
578
|
+
);
|
|
579
|
+
this.baseThreadsDB = new ThreadDB();
|
|
580
|
+
this.optimisticUpdates = new (0, _core.Signal)([]);
|
|
581
|
+
this.baseVersionsByRoomId = new (0, _core.Signal)({});
|
|
582
|
+
this.baseNotificationsById = new (0, _core.Signal)({});
|
|
583
|
+
this.baseSettingsByRoomId = new (0, _core.Signal)({});
|
|
584
|
+
this.permissionHintsByRoomId = new (0, _core.Signal)({});
|
|
585
|
+
const threadifications = _core.DerivedSignal.from(
|
|
586
|
+
this.baseThreadsDB.signal,
|
|
587
|
+
this.baseNotificationsById,
|
|
588
|
+
this.optimisticUpdates,
|
|
589
|
+
(ts, ns, updates) => applyOptimisticUpdates_forThreadifications(ts, ns, updates)
|
|
590
|
+
);
|
|
591
|
+
const threads = _core.DerivedSignal.from(threadifications, (s) => ({
|
|
592
|
+
threadsDB: s.threadsDB
|
|
593
|
+
}));
|
|
594
|
+
const notifications = _core.DerivedSignal.from(threadifications, (s) => ({
|
|
595
|
+
sortedNotifications: s.sortedNotifications,
|
|
596
|
+
notificationsById: s.notificationsById
|
|
597
|
+
}));
|
|
598
|
+
const settingsByRoomId = _core.DerivedSignal.from(
|
|
599
|
+
this.baseSettingsByRoomId,
|
|
600
|
+
this.optimisticUpdates,
|
|
601
|
+
(settings, updates) => applyOptimisticUpdates_forSettings(settings, updates)
|
|
602
|
+
);
|
|
603
|
+
const versionsByRoomId = _core.DerivedSignal.from(
|
|
604
|
+
this.baseVersionsByRoomId,
|
|
605
|
+
(hv) => hv
|
|
606
|
+
);
|
|
607
|
+
this.outputs = {
|
|
608
|
+
threadifications,
|
|
609
|
+
threads,
|
|
610
|
+
notifications,
|
|
611
|
+
settingsByRoomId,
|
|
612
|
+
versionsByRoomId
|
|
613
|
+
};
|
|
614
|
+
this.optimisticUpdates.subscribe(
|
|
615
|
+
() => this.#syncSource.setSyncStatus(
|
|
616
|
+
this.optimisticUpdates.get().length > 0 ? "synchronizing" : "synchronized"
|
|
526
617
|
)
|
|
527
618
|
);
|
|
528
|
-
this._rawThreadsDB = new ThreadDB();
|
|
529
|
-
this._store = _core.createStore.call(void 0, {
|
|
530
|
-
optimisticUpdates: [],
|
|
531
|
-
permissionsByRoom: {},
|
|
532
|
-
notificationsById: {},
|
|
533
|
-
settingsByRoomId: {},
|
|
534
|
-
versionsByRoomId: {}
|
|
535
|
-
});
|
|
536
619
|
autobind(this);
|
|
537
620
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
this._prevState = rawState;
|
|
544
|
-
this._prevVersion = this._rawThreadsDB.version;
|
|
545
|
-
}
|
|
546
|
-
return this._stateCached;
|
|
621
|
+
get1_both() {
|
|
622
|
+
return this.outputs.threadifications.get();
|
|
623
|
+
}
|
|
624
|
+
subscribe1_both(callback) {
|
|
625
|
+
return this.outputs.threadifications.subscribe(callback);
|
|
547
626
|
}
|
|
548
|
-
|
|
549
|
-
return this.
|
|
627
|
+
get1_threads() {
|
|
628
|
+
return this.outputs.threads.get();
|
|
550
629
|
}
|
|
551
|
-
|
|
552
|
-
return this.
|
|
630
|
+
subscribe1_threads(callback) {
|
|
631
|
+
return this.outputs.threads.subscribe(callback);
|
|
632
|
+
}
|
|
633
|
+
get1_notifications() {
|
|
634
|
+
return this.outputs.notifications.get();
|
|
635
|
+
}
|
|
636
|
+
subscribe1_notifications(callback) {
|
|
637
|
+
return this.outputs.notifications.subscribe(callback);
|
|
638
|
+
}
|
|
639
|
+
get2() {
|
|
640
|
+
return this.outputs.settingsByRoomId.get();
|
|
641
|
+
}
|
|
642
|
+
subscribe2(callback) {
|
|
643
|
+
return this.outputs.settingsByRoomId.subscribe(callback);
|
|
644
|
+
}
|
|
645
|
+
get3() {
|
|
646
|
+
return this.outputs.versionsByRoomId.get();
|
|
647
|
+
}
|
|
648
|
+
subscribe3(callback) {
|
|
649
|
+
return this.outputs.versionsByRoomId.subscribe(callback);
|
|
553
650
|
}
|
|
554
651
|
/**
|
|
555
652
|
* Returns the async result of the given query and room id. If the query is success,
|
|
@@ -558,7 +655,7 @@ var UmbrellaStore = class {
|
|
|
558
655
|
*/
|
|
559
656
|
getRoomThreadsLoadingState(roomId, query) {
|
|
560
657
|
const queryKey = makeRoomThreadsQueryKey(roomId, query);
|
|
561
|
-
const paginatedResource = this.
|
|
658
|
+
const paginatedResource = this.#roomThreads.get(queryKey);
|
|
562
659
|
if (paginatedResource === void 0) {
|
|
563
660
|
return ASYNC_LOADING;
|
|
564
661
|
}
|
|
@@ -566,7 +663,7 @@ var UmbrellaStore = class {
|
|
|
566
663
|
if (asyncResult.isLoading || asyncResult.error) {
|
|
567
664
|
return asyncResult;
|
|
568
665
|
}
|
|
569
|
-
const threads = this.
|
|
666
|
+
const threads = this.get1_threads().threadsDB.findMany(
|
|
570
667
|
roomId,
|
|
571
668
|
_nullishCoalesce(query, () => ( {})),
|
|
572
669
|
"asc"
|
|
@@ -583,7 +680,7 @@ var UmbrellaStore = class {
|
|
|
583
680
|
}
|
|
584
681
|
getUserThreadsLoadingState(query) {
|
|
585
682
|
const queryKey = makeUserThreadsQueryKey(query);
|
|
586
|
-
const paginatedResource = this.
|
|
683
|
+
const paginatedResource = this.#userThreads.get(queryKey);
|
|
587
684
|
if (paginatedResource === void 0) {
|
|
588
685
|
return ASYNC_LOADING;
|
|
589
686
|
}
|
|
@@ -591,7 +688,7 @@ var UmbrellaStore = class {
|
|
|
591
688
|
if (asyncResult.isLoading || asyncResult.error) {
|
|
592
689
|
return asyncResult;
|
|
593
690
|
}
|
|
594
|
-
const threads = this.
|
|
691
|
+
const threads = this.get1_threads().threadsDB.findMany(
|
|
595
692
|
void 0,
|
|
596
693
|
// Do _not_ filter by roomId
|
|
597
694
|
_nullishCoalesce(query, () => ( {})),
|
|
@@ -609,14 +706,14 @@ var UmbrellaStore = class {
|
|
|
609
706
|
}
|
|
610
707
|
// NOTE: This will read the async result, but WILL NOT start loading at the moment!
|
|
611
708
|
getInboxNotificationsLoadingState() {
|
|
612
|
-
const asyncResult = this.
|
|
709
|
+
const asyncResult = this.#notifications.get();
|
|
613
710
|
if (asyncResult.isLoading || asyncResult.error) {
|
|
614
711
|
return asyncResult;
|
|
615
712
|
}
|
|
616
713
|
const page = asyncResult.data;
|
|
617
714
|
return {
|
|
618
715
|
isLoading: false,
|
|
619
|
-
inboxNotifications: this.
|
|
716
|
+
inboxNotifications: this.get1_notifications().sortedNotifications,
|
|
620
717
|
hasFetchedAll: page.hasFetchedAll,
|
|
621
718
|
isFetchingMore: page.isFetchingMore,
|
|
622
719
|
fetchMoreError: page.fetchMoreError,
|
|
@@ -624,9 +721,10 @@ var UmbrellaStore = class {
|
|
|
624
721
|
};
|
|
625
722
|
}
|
|
626
723
|
// NOTE: This will read the async result, but WILL NOT start loading at the moment!
|
|
724
|
+
// TODO(vincent+nimesh) This should really be a derived Signal!
|
|
627
725
|
getNotificationSettingsLoadingState(roomId) {
|
|
628
726
|
const queryKey = makeNotificationSettingsQueryKey(roomId);
|
|
629
|
-
const resource = this.
|
|
727
|
+
const resource = this.#roomNotificationSettings.get(queryKey);
|
|
630
728
|
if (resource === void 0) {
|
|
631
729
|
return ASYNC_LOADING;
|
|
632
730
|
}
|
|
@@ -636,12 +734,12 @@ var UmbrellaStore = class {
|
|
|
636
734
|
}
|
|
637
735
|
return {
|
|
638
736
|
isLoading: false,
|
|
639
|
-
settings: _core.nn.call(void 0, this.
|
|
737
|
+
settings: _core.nn.call(void 0, this.get2()[roomId])
|
|
640
738
|
};
|
|
641
739
|
}
|
|
642
740
|
getRoomVersionsLoadingState(roomId) {
|
|
643
741
|
const queryKey = makeVersionsQueryKey(roomId);
|
|
644
|
-
const resource = this.
|
|
742
|
+
const resource = this.#roomVersions.get(queryKey);
|
|
645
743
|
if (resource === void 0) {
|
|
646
744
|
return ASYNC_LOADING;
|
|
647
745
|
}
|
|
@@ -651,70 +749,53 @@ var UmbrellaStore = class {
|
|
|
651
749
|
}
|
|
652
750
|
return {
|
|
653
751
|
isLoading: false,
|
|
654
|
-
versions: Object.values(_nullishCoalesce(this.
|
|
752
|
+
versions: Object.values(_nullishCoalesce(this.get3()[roomId], () => ( {})))
|
|
655
753
|
};
|
|
656
754
|
}
|
|
657
|
-
subscribe(callback) {
|
|
658
|
-
return this._store.subscribe(callback);
|
|
659
|
-
}
|
|
660
|
-
_getPermissions(roomId) {
|
|
661
|
-
return this._store.get().permissionsByRoom[roomId];
|
|
662
|
-
}
|
|
663
755
|
// Direct low-level cache mutations ------------------------------------------------- {{{
|
|
664
|
-
mutateThreadsDB(mutate) {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
mutate(db);
|
|
668
|
-
if (old !== db.version) {
|
|
669
|
-
this._store.set((state) => ({ ...state }));
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
updateInboxNotificationsCache(mapFn) {
|
|
673
|
-
this._store.set((state) => {
|
|
674
|
-
const inboxNotifications = mapFn(state.notificationsById);
|
|
675
|
-
return inboxNotifications !== state.notificationsById ? { ...state, notificationsById: inboxNotifications } : state;
|
|
756
|
+
#mutateThreadsDB(mutate) {
|
|
757
|
+
_core.batch.call(void 0, () => {
|
|
758
|
+
mutate(this.baseThreadsDB);
|
|
676
759
|
});
|
|
677
760
|
}
|
|
678
|
-
|
|
679
|
-
this.
|
|
761
|
+
#updateInboxNotificationsCache(mapFn) {
|
|
762
|
+
this.baseNotificationsById.set((prev) => mapFn(prev));
|
|
763
|
+
}
|
|
764
|
+
#setNotificationSettings(roomId, settings) {
|
|
765
|
+
this.baseSettingsByRoomId.set((state) => ({
|
|
680
766
|
...state,
|
|
681
|
-
|
|
682
|
-
...state.settingsByRoomId,
|
|
683
|
-
[roomId]: settings
|
|
684
|
-
}
|
|
767
|
+
[roomId]: settings
|
|
685
768
|
}));
|
|
686
769
|
}
|
|
687
|
-
updateRoomVersions(roomId, versions) {
|
|
688
|
-
this.
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
770
|
+
#updateRoomVersions(roomId, versions) {
|
|
771
|
+
this.baseVersionsByRoomId.set((prev) => {
|
|
772
|
+
const newVersions = { ...prev[roomId] };
|
|
773
|
+
for (const version2 of versions) {
|
|
774
|
+
newVersions[version2.id] = version2;
|
|
775
|
+
}
|
|
692
776
|
return {
|
|
693
|
-
...
|
|
694
|
-
|
|
695
|
-
...state.versionsByRoomId,
|
|
696
|
-
[roomId]: {
|
|
697
|
-
// Merge with existing versions for the room, or start with an empty object
|
|
698
|
-
..._nullishCoalesce(state.versionsByRoomId[roomId], () => ( {})),
|
|
699
|
-
...versionsById
|
|
700
|
-
}
|
|
701
|
-
}
|
|
777
|
+
...prev,
|
|
778
|
+
[roomId]: newVersions
|
|
702
779
|
};
|
|
703
780
|
});
|
|
704
781
|
}
|
|
705
|
-
updateOptimisticUpdatesCache(mapFn) {
|
|
706
|
-
this.
|
|
707
|
-
const optimisticUpdates = mapFn(state.optimisticUpdates);
|
|
708
|
-
this._syncSource.setSyncStatus(
|
|
709
|
-
optimisticUpdates.length > 0 ? "synchronizing" : "synchronized"
|
|
710
|
-
);
|
|
711
|
-
return { ...state, optimisticUpdates };
|
|
712
|
-
});
|
|
782
|
+
#updateOptimisticUpdatesCache(mapFn) {
|
|
783
|
+
this.optimisticUpdates.set(mapFn);
|
|
713
784
|
}
|
|
714
785
|
// ---------------------------------------------------------------------------------- }}}
|
|
715
786
|
/** @internal - Only call this method from unit tests. */
|
|
716
|
-
|
|
717
|
-
|
|
787
|
+
force_set_versions(callback) {
|
|
788
|
+
_core.batch.call(void 0, () => {
|
|
789
|
+
this.baseVersionsByRoomId.set(callback);
|
|
790
|
+
this.invalidateEntireStore();
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
/** @internal - Only call this method from unit tests. */
|
|
794
|
+
force_set_notifications(callback) {
|
|
795
|
+
_core.batch.call(void 0, () => {
|
|
796
|
+
this.baseNotificationsById.set(callback);
|
|
797
|
+
this.invalidateEntireStore();
|
|
798
|
+
});
|
|
718
799
|
}
|
|
719
800
|
/**
|
|
720
801
|
* Updates an existing inbox notification with a new value, replacing the
|
|
@@ -724,18 +805,17 @@ var UmbrellaStore = class {
|
|
|
724
805
|
* the cache.
|
|
725
806
|
*/
|
|
726
807
|
updateInboxNotification(inboxNotificationId, optimisticUpdateId, callback) {
|
|
727
|
-
|
|
808
|
+
_core.batch.call(void 0, () => {
|
|
728
809
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
729
|
-
this
|
|
810
|
+
this.#updateInboxNotificationsCache((cache) => {
|
|
730
811
|
const existing = cache[inboxNotificationId];
|
|
731
812
|
if (!existing) {
|
|
732
813
|
return cache;
|
|
733
814
|
}
|
|
734
|
-
|
|
815
|
+
return {
|
|
735
816
|
...cache,
|
|
736
817
|
[inboxNotificationId]: callback(existing)
|
|
737
818
|
};
|
|
738
|
-
return inboxNotifications;
|
|
739
819
|
});
|
|
740
820
|
});
|
|
741
821
|
}
|
|
@@ -744,9 +824,9 @@ var UmbrellaStore = class {
|
|
|
744
824
|
* them, replacing the corresponding optimistic update.
|
|
745
825
|
*/
|
|
746
826
|
updateAllInboxNotifications(optimisticUpdateId, mapFn) {
|
|
747
|
-
|
|
827
|
+
_core.batch.call(void 0, () => {
|
|
748
828
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
749
|
-
this
|
|
829
|
+
this.#updateInboxNotificationsCache((cache) => _core.mapValues.call(void 0, cache, mapFn));
|
|
750
830
|
});
|
|
751
831
|
}
|
|
752
832
|
/**
|
|
@@ -754,9 +834,9 @@ var UmbrellaStore = class {
|
|
|
754
834
|
* optimistic update.
|
|
755
835
|
*/
|
|
756
836
|
deleteInboxNotification(inboxNotificationId, optimisticUpdateId) {
|
|
757
|
-
|
|
837
|
+
_core.batch.call(void 0, () => {
|
|
758
838
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
759
|
-
this
|
|
839
|
+
this.#updateInboxNotificationsCache((cache) => {
|
|
760
840
|
const { [inboxNotificationId]: removed, ...newCache } = cache;
|
|
761
841
|
return removed === void 0 ? cache : newCache;
|
|
762
842
|
});
|
|
@@ -767,18 +847,18 @@ var UmbrellaStore = class {
|
|
|
767
847
|
* update.
|
|
768
848
|
*/
|
|
769
849
|
deleteAllInboxNotifications(optimisticUpdateId) {
|
|
770
|
-
|
|
850
|
+
_core.batch.call(void 0, () => {
|
|
771
851
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
772
|
-
this
|
|
852
|
+
this.#updateInboxNotificationsCache(() => ({}));
|
|
773
853
|
});
|
|
774
854
|
}
|
|
775
855
|
/**
|
|
776
856
|
* Creates an new thread, replacing the corresponding optimistic update.
|
|
777
857
|
*/
|
|
778
858
|
createThread(optimisticUpdateId, thread) {
|
|
779
|
-
|
|
859
|
+
_core.batch.call(void 0, () => {
|
|
780
860
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
781
|
-
this
|
|
861
|
+
this.#mutateThreadsDB((db) => db.upsert(thread));
|
|
782
862
|
});
|
|
783
863
|
}
|
|
784
864
|
/**
|
|
@@ -791,12 +871,12 @@ var UmbrellaStore = class {
|
|
|
791
871
|
* - The thread ID in the cache was updated more recently than the optimistic
|
|
792
872
|
* update's timestamp (if given)
|
|
793
873
|
*/
|
|
794
|
-
updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
|
|
795
|
-
|
|
874
|
+
#updateThread(threadId, optimisticUpdateId, callback, updatedAt) {
|
|
875
|
+
_core.batch.call(void 0, () => {
|
|
796
876
|
if (optimisticUpdateId !== null) {
|
|
797
877
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
798
878
|
}
|
|
799
|
-
this
|
|
879
|
+
this.#mutateThreadsDB((db) => {
|
|
800
880
|
const existing = db.get(threadId);
|
|
801
881
|
if (!existing) return;
|
|
802
882
|
if (!!updatedAt && existing.updatedAt > updatedAt) return;
|
|
@@ -805,7 +885,7 @@ var UmbrellaStore = class {
|
|
|
805
885
|
});
|
|
806
886
|
}
|
|
807
887
|
patchThread(threadId, optimisticUpdateId, patch, updatedAt) {
|
|
808
|
-
return this
|
|
888
|
+
return this.#updateThread(
|
|
809
889
|
threadId,
|
|
810
890
|
optimisticUpdateId,
|
|
811
891
|
(thread) => ({ ...thread, ..._core.compactObject.call(void 0, patch) }),
|
|
@@ -813,7 +893,7 @@ var UmbrellaStore = class {
|
|
|
813
893
|
);
|
|
814
894
|
}
|
|
815
895
|
addReaction(threadId, optimisticUpdateId, commentId, reaction, createdAt) {
|
|
816
|
-
this
|
|
896
|
+
this.#updateThread(
|
|
817
897
|
threadId,
|
|
818
898
|
optimisticUpdateId,
|
|
819
899
|
(thread) => applyAddReaction(thread, commentId, reaction),
|
|
@@ -821,7 +901,7 @@ var UmbrellaStore = class {
|
|
|
821
901
|
);
|
|
822
902
|
}
|
|
823
903
|
removeReaction(threadId, optimisticUpdateId, commentId, emoji, userId, removedAt) {
|
|
824
|
-
this
|
|
904
|
+
this.#updateThread(
|
|
825
905
|
threadId,
|
|
826
906
|
optimisticUpdateId,
|
|
827
907
|
(thread) => applyRemoveReaction(thread, commentId, emoji, userId, removedAt),
|
|
@@ -837,7 +917,7 @@ var UmbrellaStore = class {
|
|
|
837
917
|
* - The thread ID was already deleted from the cache
|
|
838
918
|
*/
|
|
839
919
|
deleteThread(threadId, optimisticUpdateId) {
|
|
840
|
-
return this
|
|
920
|
+
return this.#updateThread(
|
|
841
921
|
threadId,
|
|
842
922
|
optimisticUpdateId,
|
|
843
923
|
// A deletion is actually an update of the deletedAt property internally
|
|
@@ -849,16 +929,16 @@ var UmbrellaStore = class {
|
|
|
849
929
|
* updated correctly, replacing the corresponding optimistic update.
|
|
850
930
|
*/
|
|
851
931
|
createComment(newComment, optimisticUpdateId) {
|
|
852
|
-
|
|
932
|
+
_core.batch.call(void 0, () => {
|
|
853
933
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
854
|
-
const existingThread = this.
|
|
934
|
+
const existingThread = this.baseThreadsDB.get(newComment.threadId);
|
|
855
935
|
if (!existingThread) {
|
|
856
936
|
return;
|
|
857
937
|
}
|
|
858
|
-
this
|
|
938
|
+
this.#mutateThreadsDB(
|
|
859
939
|
(db) => db.upsert(applyUpsertComment(existingThread, newComment))
|
|
860
940
|
);
|
|
861
|
-
this
|
|
941
|
+
this.#updateInboxNotificationsCache((cache) => {
|
|
862
942
|
const existingNotification = Object.values(cache).find(
|
|
863
943
|
(notification) => notification.kind === "thread" && notification.threadId === newComment.threadId
|
|
864
944
|
);
|
|
@@ -877,14 +957,14 @@ var UmbrellaStore = class {
|
|
|
877
957
|
});
|
|
878
958
|
}
|
|
879
959
|
editComment(threadId, optimisticUpdateId, editedComment) {
|
|
880
|
-
return this
|
|
960
|
+
return this.#updateThread(
|
|
881
961
|
threadId,
|
|
882
962
|
optimisticUpdateId,
|
|
883
963
|
(thread) => applyUpsertComment(thread, editedComment)
|
|
884
964
|
);
|
|
885
965
|
}
|
|
886
966
|
deleteComment(threadId, optimisticUpdateId, commentId, deletedAt) {
|
|
887
|
-
return this
|
|
967
|
+
return this.#updateThread(
|
|
888
968
|
threadId,
|
|
889
969
|
optimisticUpdateId,
|
|
890
970
|
(thread) => applyDeleteComment(thread, commentId, deletedAt),
|
|
@@ -892,10 +972,10 @@ var UmbrellaStore = class {
|
|
|
892
972
|
);
|
|
893
973
|
}
|
|
894
974
|
updateThreadAndNotification(thread, inboxNotification) {
|
|
895
|
-
|
|
896
|
-
this
|
|
975
|
+
_core.batch.call(void 0, () => {
|
|
976
|
+
this.#mutateThreadsDB((db) => db.upsertIfNewer(thread));
|
|
897
977
|
if (inboxNotification !== void 0) {
|
|
898
|
-
this
|
|
978
|
+
this.#updateInboxNotificationsCache((cache) => ({
|
|
899
979
|
...cache,
|
|
900
980
|
[inboxNotification.id]: inboxNotification
|
|
901
981
|
}));
|
|
@@ -903,11 +983,11 @@ var UmbrellaStore = class {
|
|
|
903
983
|
});
|
|
904
984
|
}
|
|
905
985
|
updateThreadsAndNotifications(threads, inboxNotifications, deletedThreads = [], deletedInboxNotifications = []) {
|
|
906
|
-
|
|
907
|
-
this
|
|
986
|
+
_core.batch.call(void 0, () => {
|
|
987
|
+
this.#mutateThreadsDB(
|
|
908
988
|
(db) => applyThreadDeltaUpdates(db, { newThreads: threads, deletedThreads })
|
|
909
989
|
);
|
|
910
|
-
this
|
|
990
|
+
this.#updateInboxNotificationsCache(
|
|
911
991
|
(cache) => applyNotificationsUpdates(cache, {
|
|
912
992
|
newInboxNotifications: inboxNotifications,
|
|
913
993
|
deletedNotifications: deletedInboxNotifications
|
|
@@ -920,33 +1000,33 @@ var UmbrellaStore = class {
|
|
|
920
1000
|
* replacing the corresponding optimistic update.
|
|
921
1001
|
*/
|
|
922
1002
|
updateRoomNotificationSettings_confirmOptimisticUpdate(roomId, optimisticUpdateId, settings) {
|
|
923
|
-
|
|
1003
|
+
_core.batch.call(void 0, () => {
|
|
924
1004
|
this.removeOptimisticUpdate(optimisticUpdateId);
|
|
925
|
-
this
|
|
1005
|
+
this.#setNotificationSettings(roomId, settings);
|
|
926
1006
|
});
|
|
927
1007
|
}
|
|
928
1008
|
addOptimisticUpdate(optimisticUpdate) {
|
|
929
1009
|
const id = _core.nanoid.call(void 0, );
|
|
930
1010
|
const newUpdate = { ...optimisticUpdate, id };
|
|
931
|
-
this
|
|
1011
|
+
this.#updateOptimisticUpdatesCache((cache) => [...cache, newUpdate]);
|
|
932
1012
|
return id;
|
|
933
1013
|
}
|
|
934
1014
|
removeOptimisticUpdate(optimisticUpdateId) {
|
|
935
|
-
this
|
|
1015
|
+
this.#updateOptimisticUpdatesCache(
|
|
936
1016
|
(cache) => cache.filter((ou) => ou.id !== optimisticUpdateId)
|
|
937
1017
|
);
|
|
938
1018
|
}
|
|
939
1019
|
async fetchNotificationsDeltaUpdate(signal) {
|
|
940
|
-
const lastRequestedAt = this
|
|
1020
|
+
const lastRequestedAt = this.#notificationsLastRequestedAt;
|
|
941
1021
|
if (lastRequestedAt === null) {
|
|
942
1022
|
return;
|
|
943
1023
|
}
|
|
944
|
-
const result = await this.
|
|
1024
|
+
const result = await this.#client.getInboxNotificationsSince({
|
|
945
1025
|
since: lastRequestedAt,
|
|
946
1026
|
signal
|
|
947
1027
|
});
|
|
948
1028
|
if (lastRequestedAt < result.requestedAt) {
|
|
949
|
-
this
|
|
1029
|
+
this.#notificationsLastRequestedAt = result.requestedAt;
|
|
950
1030
|
}
|
|
951
1031
|
this.updateThreadsAndNotifications(
|
|
952
1032
|
result.threads.updated,
|
|
@@ -956,25 +1036,24 @@ var UmbrellaStore = class {
|
|
|
956
1036
|
);
|
|
957
1037
|
}
|
|
958
1038
|
waitUntilNotificationsLoaded() {
|
|
959
|
-
return this.
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
(permission
|
|
967
|
-
|
|
968
|
-
|
|
1039
|
+
return this.#notifications.waitUntilLoaded();
|
|
1040
|
+
}
|
|
1041
|
+
#updatePermissionHints(newHints) {
|
|
1042
|
+
this.permissionHintsByRoomId.set((prev) => {
|
|
1043
|
+
const permissionsByRoom = { ...prev };
|
|
1044
|
+
for (const [roomId, newPermissions] of Object.entries(newHints)) {
|
|
1045
|
+
const existing = _nullishCoalesce(permissionsByRoom[roomId], () => ( /* @__PURE__ */ new Set()));
|
|
1046
|
+
for (const permission of newPermissions) {
|
|
1047
|
+
existing.add(permission);
|
|
1048
|
+
}
|
|
1049
|
+
permissionsByRoom[roomId] = existing;
|
|
1050
|
+
}
|
|
1051
|
+
return permissionsByRoom;
|
|
969
1052
|
});
|
|
970
|
-
this._store.set((state) => ({
|
|
971
|
-
...state,
|
|
972
|
-
permissionsByRoom
|
|
973
|
-
}));
|
|
974
1053
|
}
|
|
975
1054
|
waitUntilRoomThreadsLoaded(roomId, query) {
|
|
976
1055
|
const threadsFetcher = async (cursor) => {
|
|
977
|
-
const result = await this
|
|
1056
|
+
const result = await this.#client[_core.kInternal].httpClient.getThreads({
|
|
978
1057
|
roomId,
|
|
979
1058
|
cursor,
|
|
980
1059
|
query
|
|
@@ -983,15 +1062,15 @@ var UmbrellaStore = class {
|
|
|
983
1062
|
result.threads,
|
|
984
1063
|
result.inboxNotifications
|
|
985
1064
|
);
|
|
986
|
-
this
|
|
987
|
-
const lastRequestedAt = this.
|
|
1065
|
+
this.#updatePermissionHints(result.permissionHints);
|
|
1066
|
+
const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
|
|
988
1067
|
if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
|
|
989
|
-
this.
|
|
1068
|
+
this.#roomThreadsLastRequestedAtByRoom.set(roomId, result.requestedAt);
|
|
990
1069
|
}
|
|
991
1070
|
return result.nextCursor;
|
|
992
1071
|
};
|
|
993
1072
|
const queryKey = makeRoomThreadsQueryKey(roomId, query);
|
|
994
|
-
let paginatedResource = this.
|
|
1073
|
+
let paginatedResource = this.#roomThreads.get(queryKey);
|
|
995
1074
|
if (paginatedResource === void 0) {
|
|
996
1075
|
paginatedResource = new PaginatedResource(threadsFetcher);
|
|
997
1076
|
}
|
|
@@ -999,18 +1078,18 @@ var UmbrellaStore = class {
|
|
|
999
1078
|
() => (
|
|
1000
1079
|
// Note that the store itself does not change, but it's only vehicle at
|
|
1001
1080
|
// the moment to trigger a re-render, so we'll do a no-op update here.
|
|
1002
|
-
this.
|
|
1081
|
+
this.invalidateEntireStore()
|
|
1003
1082
|
)
|
|
1004
1083
|
);
|
|
1005
|
-
this.
|
|
1084
|
+
this.#roomThreads.set(queryKey, paginatedResource);
|
|
1006
1085
|
return paginatedResource.waitUntilLoaded();
|
|
1007
1086
|
}
|
|
1008
1087
|
async fetchRoomThreadsDeltaUpdate(roomId, signal) {
|
|
1009
|
-
const lastRequestedAt = this.
|
|
1088
|
+
const lastRequestedAt = this.#roomThreadsLastRequestedAtByRoom.get(roomId);
|
|
1010
1089
|
if (lastRequestedAt === void 0) {
|
|
1011
1090
|
return;
|
|
1012
1091
|
}
|
|
1013
|
-
const updates = await this
|
|
1092
|
+
const updates = await this.#client[_core.kInternal].httpClient.getThreadsSince({
|
|
1014
1093
|
roomId,
|
|
1015
1094
|
since: lastRequestedAt,
|
|
1016
1095
|
signal
|
|
@@ -1021,15 +1100,15 @@ var UmbrellaStore = class {
|
|
|
1021
1100
|
updates.threads.deleted,
|
|
1022
1101
|
updates.inboxNotifications.deleted
|
|
1023
1102
|
);
|
|
1024
|
-
this
|
|
1103
|
+
this.#updatePermissionHints(updates.permissionHints);
|
|
1025
1104
|
if (lastRequestedAt < updates.requestedAt) {
|
|
1026
|
-
this.
|
|
1105
|
+
this.#roomThreadsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
|
|
1027
1106
|
}
|
|
1028
1107
|
}
|
|
1029
1108
|
waitUntilUserThreadsLoaded(query) {
|
|
1030
1109
|
const queryKey = makeUserThreadsQueryKey(query);
|
|
1031
1110
|
const threadsFetcher = async (cursor) => {
|
|
1032
|
-
const result = await this
|
|
1111
|
+
const result = await this.#client[_core.kInternal].httpClient.getUserThreads_experimental({
|
|
1033
1112
|
cursor,
|
|
1034
1113
|
query
|
|
1035
1114
|
});
|
|
@@ -1037,13 +1116,13 @@ var UmbrellaStore = class {
|
|
|
1037
1116
|
result.threads,
|
|
1038
1117
|
result.inboxNotifications
|
|
1039
1118
|
);
|
|
1040
|
-
this
|
|
1041
|
-
if (this
|
|
1042
|
-
this
|
|
1119
|
+
this.#updatePermissionHints(result.permissionHints);
|
|
1120
|
+
if (this.#userThreadsLastRequestedAt === null) {
|
|
1121
|
+
this.#userThreadsLastRequestedAt = result.requestedAt;
|
|
1043
1122
|
}
|
|
1044
1123
|
return result.nextCursor;
|
|
1045
1124
|
};
|
|
1046
|
-
let paginatedResource = this.
|
|
1125
|
+
let paginatedResource = this.#userThreads.get(queryKey);
|
|
1047
1126
|
if (paginatedResource === void 0) {
|
|
1048
1127
|
paginatedResource = new PaginatedResource(threadsFetcher);
|
|
1049
1128
|
}
|
|
@@ -1051,23 +1130,34 @@ var UmbrellaStore = class {
|
|
|
1051
1130
|
() => (
|
|
1052
1131
|
// Note that the store itself does not change, but it's only vehicle at
|
|
1053
1132
|
// the moment to trigger a re-render, so we'll do a no-op update here.
|
|
1054
|
-
this.
|
|
1133
|
+
this.invalidateEntireStore()
|
|
1055
1134
|
)
|
|
1056
1135
|
);
|
|
1057
|
-
this.
|
|
1136
|
+
this.#userThreads.set(queryKey, paginatedResource);
|
|
1058
1137
|
return paginatedResource.waitUntilLoaded();
|
|
1059
1138
|
}
|
|
1139
|
+
// TODO(vincent+nimesh) We should really be going over all call sites, and replace this call
|
|
1140
|
+
// with a more specific invalidation!
|
|
1141
|
+
invalidateEntireStore() {
|
|
1142
|
+
_core.batch.call(void 0, () => {
|
|
1143
|
+
this.baseVersionsByRoomId.set((store) => ({ ...store }));
|
|
1144
|
+
this.baseNotificationsById.set((store) => ({ ...store }));
|
|
1145
|
+
this.optimisticUpdates.set((store) => [...store]);
|
|
1146
|
+
this.permissionHintsByRoomId.set((store) => ({ ...store }));
|
|
1147
|
+
this.baseSettingsByRoomId.set((store) => ({ ...store }));
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1060
1150
|
async fetchUserThreadsDeltaUpdate(signal) {
|
|
1061
|
-
const lastRequestedAt = this
|
|
1151
|
+
const lastRequestedAt = this.#userThreadsLastRequestedAt;
|
|
1062
1152
|
if (lastRequestedAt === null) {
|
|
1063
1153
|
return;
|
|
1064
1154
|
}
|
|
1065
|
-
const result = await this
|
|
1155
|
+
const result = await this.#client[_core.kInternal].httpClient.getUserThreadsSince_experimental({
|
|
1066
1156
|
since: lastRequestedAt,
|
|
1067
1157
|
signal
|
|
1068
1158
|
});
|
|
1069
1159
|
if (lastRequestedAt < result.requestedAt) {
|
|
1070
|
-
this
|
|
1160
|
+
this.#notificationsLastRequestedAt = result.requestedAt;
|
|
1071
1161
|
}
|
|
1072
1162
|
this.updateThreadsAndNotifications(
|
|
1073
1163
|
result.threads.updated,
|
|
@@ -1075,14 +1165,14 @@ var UmbrellaStore = class {
|
|
|
1075
1165
|
result.threads.deleted,
|
|
1076
1166
|
result.inboxNotifications.deleted
|
|
1077
1167
|
);
|
|
1078
|
-
this
|
|
1168
|
+
this.#updatePermissionHints(result.permissionHints);
|
|
1079
1169
|
}
|
|
1080
1170
|
waitUntilRoomVersionsLoaded(roomId) {
|
|
1081
1171
|
const queryKey = makeVersionsQueryKey(roomId);
|
|
1082
|
-
let resource = this.
|
|
1172
|
+
let resource = this.#roomVersions.get(queryKey);
|
|
1083
1173
|
if (resource === void 0) {
|
|
1084
1174
|
const versionsFetcher = async () => {
|
|
1085
|
-
const room = this.
|
|
1175
|
+
const room = this.#client.getRoom(roomId);
|
|
1086
1176
|
if (room === null) {
|
|
1087
1177
|
throw new (0, _core.HttpError)(
|
|
1088
1178
|
`Room '${roomId}' is not available on client`,
|
|
@@ -1090,10 +1180,10 @@ var UmbrellaStore = class {
|
|
|
1090
1180
|
);
|
|
1091
1181
|
}
|
|
1092
1182
|
const result = await room[_core.kInternal].listTextVersions();
|
|
1093
|
-
this
|
|
1094
|
-
const lastRequestedAt = this.
|
|
1183
|
+
this.#updateRoomVersions(roomId, result.versions);
|
|
1184
|
+
const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
|
|
1095
1185
|
if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
|
|
1096
|
-
this.
|
|
1186
|
+
this.#roomVersionsLastRequestedAtByRoom.set(
|
|
1097
1187
|
roomId,
|
|
1098
1188
|
result.requestedAt
|
|
1099
1189
|
);
|
|
@@ -1105,36 +1195,36 @@ var UmbrellaStore = class {
|
|
|
1105
1195
|
() => (
|
|
1106
1196
|
// Note that the store itself does not change, but it's only vehicle at
|
|
1107
1197
|
// the moment to trigger a re-render, so we'll do a no-op update here.
|
|
1108
|
-
this.
|
|
1198
|
+
this.invalidateEntireStore()
|
|
1109
1199
|
)
|
|
1110
1200
|
);
|
|
1111
|
-
this.
|
|
1201
|
+
this.#roomVersions.set(queryKey, resource);
|
|
1112
1202
|
return resource.waitUntilLoaded();
|
|
1113
1203
|
}
|
|
1114
1204
|
async fetchRoomVersionsDeltaUpdate(roomId, signal) {
|
|
1115
|
-
const lastRequestedAt = this.
|
|
1205
|
+
const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
|
|
1116
1206
|
if (lastRequestedAt === void 0) {
|
|
1117
1207
|
return;
|
|
1118
1208
|
}
|
|
1119
1209
|
const room = _core.nn.call(void 0,
|
|
1120
|
-
this.
|
|
1210
|
+
this.#client.getRoom(roomId),
|
|
1121
1211
|
`Room with id ${roomId} is not available on client`
|
|
1122
1212
|
);
|
|
1123
1213
|
const updates = await room[_core.kInternal].listTextVersionsSince({
|
|
1124
1214
|
since: lastRequestedAt,
|
|
1125
1215
|
signal
|
|
1126
1216
|
});
|
|
1127
|
-
this
|
|
1217
|
+
this.#updateRoomVersions(roomId, updates.versions);
|
|
1128
1218
|
if (lastRequestedAt < updates.requestedAt) {
|
|
1129
|
-
this.
|
|
1219
|
+
this.#roomVersionsLastRequestedAtByRoom.set(roomId, updates.requestedAt);
|
|
1130
1220
|
}
|
|
1131
1221
|
}
|
|
1132
1222
|
waitUntilRoomNotificationSettingsLoaded(roomId) {
|
|
1133
1223
|
const queryKey = makeNotificationSettingsQueryKey(roomId);
|
|
1134
|
-
let resource = this.
|
|
1224
|
+
let resource = this.#roomNotificationSettings.get(queryKey);
|
|
1135
1225
|
if (resource === void 0) {
|
|
1136
1226
|
const notificationSettingsFetcher = async () => {
|
|
1137
|
-
const room = this.
|
|
1227
|
+
const room = this.#client.getRoom(roomId);
|
|
1138
1228
|
if (room === null) {
|
|
1139
1229
|
throw new (0, _core.HttpError)(
|
|
1140
1230
|
`Room '${roomId}' is not available on client`,
|
|
@@ -1142,7 +1232,7 @@ var UmbrellaStore = class {
|
|
|
1142
1232
|
);
|
|
1143
1233
|
}
|
|
1144
1234
|
const result = await room.getNotificationSettings();
|
|
1145
|
-
this
|
|
1235
|
+
this.#setNotificationSettings(roomId, result);
|
|
1146
1236
|
};
|
|
1147
1237
|
resource = new SinglePageResource(notificationSettingsFetcher);
|
|
1148
1238
|
}
|
|
@@ -1150,28 +1240,25 @@ var UmbrellaStore = class {
|
|
|
1150
1240
|
() => (
|
|
1151
1241
|
// Note that the store itself does not change, but it's only vehicle at
|
|
1152
1242
|
// the moment to trigger a re-render, so we'll do a no-op update here.
|
|
1153
|
-
this.
|
|
1243
|
+
this.invalidateEntireStore()
|
|
1154
1244
|
)
|
|
1155
1245
|
);
|
|
1156
|
-
this.
|
|
1246
|
+
this.#roomNotificationSettings.set(queryKey, resource);
|
|
1157
1247
|
return resource.waitUntilLoaded();
|
|
1158
1248
|
}
|
|
1159
1249
|
async refreshRoomNotificationSettings(roomId, signal) {
|
|
1160
1250
|
const room = _core.nn.call(void 0,
|
|
1161
|
-
this.
|
|
1251
|
+
this.#client.getRoom(roomId),
|
|
1162
1252
|
`Room with id ${roomId} is not available on client`
|
|
1163
1253
|
);
|
|
1164
1254
|
const result = await room.getNotificationSettings({ signal });
|
|
1165
|
-
this
|
|
1255
|
+
this.#setNotificationSettings(roomId, result);
|
|
1166
1256
|
}
|
|
1167
1257
|
};
|
|
1168
|
-
function
|
|
1169
|
-
const threadsDB =
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
settingsByRoomId: { ...state.settingsByRoomId }
|
|
1173
|
-
};
|
|
1174
|
-
for (const optimisticUpdate of state.optimisticUpdates) {
|
|
1258
|
+
function applyOptimisticUpdates_forThreadifications(baseThreadsDB, rawNotificationsById, optimisticUpdates) {
|
|
1259
|
+
const threadsDB = baseThreadsDB.clone();
|
|
1260
|
+
let notificationsById = { ...rawNotificationsById };
|
|
1261
|
+
for (const optimisticUpdate of optimisticUpdates) {
|
|
1175
1262
|
switch (optimisticUpdate.type) {
|
|
1176
1263
|
case "create-thread": {
|
|
1177
1264
|
threadsDB.upsert(optimisticUpdate.thread);
|
|
@@ -1209,15 +1296,13 @@ function internalToExternalState(state, rawThreadsDB) {
|
|
|
1209
1296
|
const thread = threadsDB.get(optimisticUpdate.comment.threadId);
|
|
1210
1297
|
if (thread === void 0) break;
|
|
1211
1298
|
threadsDB.upsert(applyUpsertComment(thread, optimisticUpdate.comment));
|
|
1212
|
-
const inboxNotification = Object.values(
|
|
1213
|
-
computed.notificationsById
|
|
1214
|
-
).find(
|
|
1299
|
+
const inboxNotification = Object.values(notificationsById).find(
|
|
1215
1300
|
(notification) => notification.kind === "thread" && notification.threadId === thread.id
|
|
1216
1301
|
);
|
|
1217
1302
|
if (inboxNotification === void 0) {
|
|
1218
1303
|
break;
|
|
1219
1304
|
}
|
|
1220
|
-
|
|
1305
|
+
notificationsById[inboxNotification.id] = {
|
|
1221
1306
|
...inboxNotification,
|
|
1222
1307
|
notifiedAt: optimisticUpdate.comment.createdAt,
|
|
1223
1308
|
readAt: optimisticUpdate.comment.createdAt
|
|
@@ -1280,23 +1365,23 @@ function internalToExternalState(state, rawThreadsDB) {
|
|
|
1280
1365
|
break;
|
|
1281
1366
|
}
|
|
1282
1367
|
case "mark-inbox-notification-as-read": {
|
|
1283
|
-
const ibn =
|
|
1368
|
+
const ibn = notificationsById[optimisticUpdate.inboxNotificationId];
|
|
1284
1369
|
if (ibn === void 0) {
|
|
1285
1370
|
break;
|
|
1286
1371
|
}
|
|
1287
|
-
|
|
1372
|
+
notificationsById[optimisticUpdate.inboxNotificationId] = {
|
|
1288
1373
|
...ibn,
|
|
1289
1374
|
readAt: optimisticUpdate.readAt
|
|
1290
1375
|
};
|
|
1291
1376
|
break;
|
|
1292
1377
|
}
|
|
1293
1378
|
case "mark-all-inbox-notifications-as-read": {
|
|
1294
|
-
for (const id in
|
|
1295
|
-
const ibn =
|
|
1379
|
+
for (const id in notificationsById) {
|
|
1380
|
+
const ibn = notificationsById[id];
|
|
1296
1381
|
if (ibn === void 0) {
|
|
1297
1382
|
break;
|
|
1298
1383
|
}
|
|
1299
|
-
|
|
1384
|
+
notificationsById[id] = {
|
|
1300
1385
|
...ibn,
|
|
1301
1386
|
readAt: optimisticUpdate.readAt
|
|
1302
1387
|
};
|
|
@@ -1304,38 +1389,44 @@ function internalToExternalState(state, rawThreadsDB) {
|
|
|
1304
1389
|
break;
|
|
1305
1390
|
}
|
|
1306
1391
|
case "delete-inbox-notification": {
|
|
1307
|
-
delete
|
|
1392
|
+
delete notificationsById[optimisticUpdate.inboxNotificationId];
|
|
1308
1393
|
break;
|
|
1309
1394
|
}
|
|
1310
1395
|
case "delete-all-inbox-notifications": {
|
|
1311
|
-
|
|
1396
|
+
notificationsById = {};
|
|
1312
1397
|
break;
|
|
1313
1398
|
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
const sortedNotifications = (
|
|
1402
|
+
// Sort so that the most recent notifications are first
|
|
1403
|
+
Object.values(notificationsById).filter(
|
|
1404
|
+
(ibn) => ibn.kind === "thread" ? threadsDB.get(ibn.threadId) !== void 0 : true
|
|
1405
|
+
).sort((a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime())
|
|
1406
|
+
);
|
|
1407
|
+
return {
|
|
1408
|
+
sortedNotifications,
|
|
1409
|
+
notificationsById,
|
|
1410
|
+
threadsDB
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
function applyOptimisticUpdates_forSettings(baseSettingsByRoomId, optimisticUpdates) {
|
|
1414
|
+
const settingsByRoomId = { ...baseSettingsByRoomId };
|
|
1415
|
+
for (const optimisticUpdate of optimisticUpdates) {
|
|
1416
|
+
switch (optimisticUpdate.type) {
|
|
1314
1417
|
case "update-notification-settings": {
|
|
1315
|
-
const settings =
|
|
1418
|
+
const settings = settingsByRoomId[optimisticUpdate.roomId];
|
|
1316
1419
|
if (settings === void 0) {
|
|
1317
1420
|
break;
|
|
1318
1421
|
}
|
|
1319
|
-
|
|
1422
|
+
settingsByRoomId[optimisticUpdate.roomId] = {
|
|
1320
1423
|
...settings,
|
|
1321
1424
|
...optimisticUpdate.settings
|
|
1322
1425
|
};
|
|
1323
1426
|
}
|
|
1324
1427
|
}
|
|
1325
1428
|
}
|
|
1326
|
-
|
|
1327
|
-
// Sort so that the most recent notifications are first
|
|
1328
|
-
Object.values(computed.notificationsById).filter(
|
|
1329
|
-
(ibn) => ibn.kind === "thread" ? threadsDB.get(ibn.threadId) !== void 0 : true
|
|
1330
|
-
).sort((a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime())
|
|
1331
|
-
);
|
|
1332
|
-
return {
|
|
1333
|
-
cleanedNotifications,
|
|
1334
|
-
notificationsById: computed.notificationsById,
|
|
1335
|
-
settingsByRoomId: computed.settingsByRoomId,
|
|
1336
|
-
threadsDB,
|
|
1337
|
-
versionsByRoomId: state.versionsByRoomId
|
|
1338
|
-
};
|
|
1429
|
+
return settingsByRoomId;
|
|
1339
1430
|
}
|
|
1340
1431
|
function applyThreadDeltaUpdates(db, updates) {
|
|
1341
1432
|
updates.newThreads.forEach((thread) => db.upsertIfNewer(thread));
|
|
@@ -1717,7 +1808,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
|
|
|
1717
1808
|
};
|
|
1718
1809
|
}, [poller]);
|
|
1719
1810
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
1720
|
-
store.
|
|
1811
|
+
store.subscribe1_threads,
|
|
1721
1812
|
store.getInboxNotificationsLoadingState,
|
|
1722
1813
|
store.getInboxNotificationsLoadingState,
|
|
1723
1814
|
selector,
|
|
@@ -1839,7 +1930,7 @@ function useDeleteAllInboxNotifications_withClient(client) {
|
|
|
1839
1930
|
}
|
|
1840
1931
|
function useInboxNotificationThread_withClient(client, inboxNotificationId) {
|
|
1841
1932
|
const { store } = getLiveblocksExtrasForClient(client);
|
|
1842
|
-
const getter = store.
|
|
1933
|
+
const getter = store.get1_both;
|
|
1843
1934
|
const selector = _react.useCallback.call(void 0,
|
|
1844
1935
|
(state) => {
|
|
1845
1936
|
const inboxNotification = _nullishCoalesce(state.notificationsById[inboxNotificationId], () => ( _core.raise.call(void 0, `Inbox notification with ID "${inboxNotificationId}" not found`)));
|
|
@@ -1856,7 +1947,7 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
|
|
|
1856
1947
|
[inboxNotificationId]
|
|
1857
1948
|
);
|
|
1858
1949
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
1859
|
-
store.
|
|
1950
|
+
store.subscribe1_both,
|
|
1860
1951
|
// Re-evaluate if we need to update any time the notification changes over time
|
|
1861
1952
|
getter,
|
|
1862
1953
|
getter,
|
|
@@ -2072,7 +2163,7 @@ function useUserThreads_experimental(options = {
|
|
|
2072
2163
|
[store, options.query]
|
|
2073
2164
|
);
|
|
2074
2165
|
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
2075
|
-
store.
|
|
2166
|
+
store.subscribe1_threads,
|
|
2076
2167
|
getter,
|
|
2077
2168
|
getter,
|
|
2078
2169
|
identity,
|
|
@@ -2281,8 +2372,21 @@ var UpdateNotificationSettingsError = class extends Error {
|
|
|
2281
2372
|
}
|
|
2282
2373
|
};
|
|
2283
2374
|
|
|
2375
|
+
// src/use-signal.ts
|
|
2376
|
+
|
|
2377
|
+
var identity2 = (value) => value;
|
|
2378
|
+
function useSignal(signal, selector, isEqual) {
|
|
2379
|
+
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
2380
|
+
signal.subscribe,
|
|
2381
|
+
signal.get,
|
|
2382
|
+
signal.get,
|
|
2383
|
+
_nullishCoalesce(selector, () => ( identity2)),
|
|
2384
|
+
isEqual
|
|
2385
|
+
);
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2284
2388
|
// src/room.tsx
|
|
2285
|
-
var
|
|
2389
|
+
var _client = require('@liveblocks/client');
|
|
2286
2390
|
|
|
2287
2391
|
|
|
2288
2392
|
|
|
@@ -2331,7 +2435,7 @@ function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
|
|
|
2331
2435
|
// src/room.tsx
|
|
2332
2436
|
var noop3 = () => {
|
|
2333
2437
|
};
|
|
2334
|
-
var
|
|
2438
|
+
var identity3 = (x) => x;
|
|
2335
2439
|
var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\u2019re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you\u2019re ready to upgrade to React 18:
|
|
2336
2440
|
|
|
2337
2441
|
import { unstable_batchedUpdates } from "react-dom"; // or "react-native"
|
|
@@ -2345,7 +2449,7 @@ var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\
|
|
|
2345
2449
|
Why? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;
|
|
2346
2450
|
var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
|
|
2347
2451
|
function useSyncExternalStore2(s, gs, gss) {
|
|
2348
|
-
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss,
|
|
2452
|
+
return _withselectorjs.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss, identity3);
|
|
2349
2453
|
}
|
|
2350
2454
|
var STABLE_EMPTY_LIST = Object.freeze([]);
|
|
2351
2455
|
function alwaysEmptyList() {
|
|
@@ -2387,7 +2491,7 @@ function makeMutationContext(room) {
|
|
|
2387
2491
|
};
|
|
2388
2492
|
}
|
|
2389
2493
|
function getCurrentUserId(client) {
|
|
2390
|
-
const userId = client[_core.kInternal].
|
|
2494
|
+
const userId = client[_core.kInternal].currentUserId.get();
|
|
2391
2495
|
if (userId === void 0) {
|
|
2392
2496
|
return "anonymous";
|
|
2393
2497
|
}
|
|
@@ -2685,7 +2789,7 @@ function RoomProviderInner(props) {
|
|
|
2685
2789
|
return;
|
|
2686
2790
|
}
|
|
2687
2791
|
const { thread, inboxNotification } = info;
|
|
2688
|
-
const existingThread = store.
|
|
2792
|
+
const existingThread = store.get1_threads().threadsDB.getEvenIfDeleted(message.threadId);
|
|
2689
2793
|
switch (message.type) {
|
|
2690
2794
|
case _core.ServerMsgCode.COMMENT_EDITED:
|
|
2691
2795
|
case _core.ServerMsgCode.THREAD_METADATA_UPDATED:
|
|
@@ -2750,6 +2854,52 @@ function useReportTextEditor(editor, rootKey) {
|
|
|
2750
2854
|
return unsubscribe;
|
|
2751
2855
|
}, [room, editor, rootKey]);
|
|
2752
2856
|
}
|
|
2857
|
+
function useYjsProvider() {
|
|
2858
|
+
const room = useRoom();
|
|
2859
|
+
const subscribe = React4.useCallback(
|
|
2860
|
+
(onStoreChange) => {
|
|
2861
|
+
return room[_core.kInternal].yjsProviderDidChange.subscribe(onStoreChange);
|
|
2862
|
+
},
|
|
2863
|
+
[room]
|
|
2864
|
+
);
|
|
2865
|
+
const getSnapshot = React4.useCallback(() => {
|
|
2866
|
+
return room[_core.kInternal].getYjsProvider();
|
|
2867
|
+
}, [room]);
|
|
2868
|
+
return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
|
|
2869
|
+
}
|
|
2870
|
+
function useCreateTextMention() {
|
|
2871
|
+
const room = useRoom();
|
|
2872
|
+
return React4.useCallback(
|
|
2873
|
+
(userId, mentionId) => {
|
|
2874
|
+
room[_core.kInternal].createTextMention(userId, mentionId).catch((err) => {
|
|
2875
|
+
_core.console.error(
|
|
2876
|
+
`Cannot create text mention for user '${userId}' and mention '${mentionId}'`,
|
|
2877
|
+
err
|
|
2878
|
+
);
|
|
2879
|
+
});
|
|
2880
|
+
},
|
|
2881
|
+
[room]
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2884
|
+
function useDeleteTextMention() {
|
|
2885
|
+
const room = useRoom();
|
|
2886
|
+
return React4.useCallback(
|
|
2887
|
+
(mentionId) => {
|
|
2888
|
+
room[_core.kInternal].deleteTextMention(mentionId).catch((err) => {
|
|
2889
|
+
_core.console.error(`Cannot delete text mention '${mentionId}'`, err);
|
|
2890
|
+
});
|
|
2891
|
+
},
|
|
2892
|
+
[room]
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
function useResolveMentionSuggestions() {
|
|
2896
|
+
const client = useClient();
|
|
2897
|
+
return client[_core.kInternal].resolveMentionSuggestions;
|
|
2898
|
+
}
|
|
2899
|
+
function useMentionSuggestionsCache() {
|
|
2900
|
+
const client = useClient();
|
|
2901
|
+
return client[_core.kInternal].mentionSuggestionsCache;
|
|
2902
|
+
}
|
|
2753
2903
|
function useStorageStatus(options) {
|
|
2754
2904
|
const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _14 => _14.smooth]), () => ( false)));
|
|
2755
2905
|
if (smooth) {
|
|
@@ -2859,7 +3009,7 @@ function useSelf(maybeSelector, isEqual) {
|
|
|
2859
3009
|
const room = useRoom();
|
|
2860
3010
|
const subscribe = room.events.self.subscribe;
|
|
2861
3011
|
const getSnapshot = room.getSelf;
|
|
2862
|
-
const selector = _nullishCoalesce(maybeSelector, () => (
|
|
3012
|
+
const selector = _nullishCoalesce(maybeSelector, () => ( identity3));
|
|
2863
3013
|
const wrappedSelector = React4.useCallback(
|
|
2864
3014
|
(me) => me !== null ? selector(me) : null,
|
|
2865
3015
|
[selector]
|
|
@@ -2893,7 +3043,7 @@ function useOthers(selector, isEqual) {
|
|
|
2893
3043
|
subscribe,
|
|
2894
3044
|
getSnapshot,
|
|
2895
3045
|
getServerSnapshot,
|
|
2896
|
-
_nullishCoalesce(selector, () => (
|
|
3046
|
+
_nullishCoalesce(selector, () => ( identity3)),
|
|
2897
3047
|
isEqual
|
|
2898
3048
|
);
|
|
2899
3049
|
}
|
|
@@ -2915,7 +3065,7 @@ function useOthersMapped(itemSelector, itemIsEqual) {
|
|
|
2915
3065
|
return useOthers(wrappedSelector, wrappedIsEqual);
|
|
2916
3066
|
}
|
|
2917
3067
|
function useOthersConnectionIds() {
|
|
2918
|
-
return useOthers(selectorFor_useOthersConnectionIds,
|
|
3068
|
+
return useOthers(selectorFor_useOthersConnectionIds, _client.shallow);
|
|
2919
3069
|
}
|
|
2920
3070
|
var NOT_FOUND = Symbol();
|
|
2921
3071
|
function useOther(connectionId, selector, isEqual) {
|
|
@@ -3035,10 +3185,10 @@ function useThreads(options = {
|
|
|
3035
3185
|
[store, room.id, options.query]
|
|
3036
3186
|
);
|
|
3037
3187
|
const state = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
3038
|
-
store.
|
|
3188
|
+
store.subscribe1_threads,
|
|
3039
3189
|
getter,
|
|
3040
3190
|
getter,
|
|
3041
|
-
|
|
3191
|
+
identity3,
|
|
3042
3192
|
shallow2
|
|
3043
3193
|
// NOTE: Using 2-level-deep shallow check here, because the result of selectThreads() is not stable!
|
|
3044
3194
|
);
|
|
@@ -3131,7 +3281,7 @@ function useDeleteRoomThread(roomId) {
|
|
|
3131
3281
|
(threadId) => {
|
|
3132
3282
|
const { store, onMutationFailure } = getRoomExtrasForClient(client);
|
|
3133
3283
|
const userId = getCurrentUserId(client);
|
|
3134
|
-
const existing = store.
|
|
3284
|
+
const existing = store.get1_threads().threadsDB.get(threadId);
|
|
3135
3285
|
if (_optionalChain([existing, 'optionalAccess', _17 => _17.comments, 'optionalAccess', _18 => _18[0], 'optionalAccess', _19 => _19.userId]) !== userId) {
|
|
3136
3286
|
throw new Error("Only the thread creator can delete the thread");
|
|
3137
3287
|
}
|
|
@@ -3254,7 +3404,7 @@ function useEditRoomComment(roomId) {
|
|
|
3254
3404
|
({ threadId, commentId, body, attachments }) => {
|
|
3255
3405
|
const editedAt = /* @__PURE__ */ new Date();
|
|
3256
3406
|
const { store, onMutationFailure } = getRoomExtrasForClient(client);
|
|
3257
|
-
const existing = store.
|
|
3407
|
+
const existing = store.get1_threads().threadsDB.getEvenIfDeleted(threadId);
|
|
3258
3408
|
if (existing === void 0) {
|
|
3259
3409
|
_core.console.warn(
|
|
3260
3410
|
`Internal unexpected behavior. Cannot edit comment in thread "${threadId}" because the thread does not exist in the cache.`
|
|
@@ -3436,7 +3586,7 @@ function useMarkRoomThreadAsRead(roomId) {
|
|
|
3436
3586
|
(threadId) => {
|
|
3437
3587
|
const { store, onMutationFailure } = getRoomExtrasForClient(client);
|
|
3438
3588
|
const inboxNotification = Object.values(
|
|
3439
|
-
store.
|
|
3589
|
+
store.get1_notifications().notificationsById
|
|
3440
3590
|
).find(
|
|
3441
3591
|
(inboxNotification2) => inboxNotification2.kind === "thread" && inboxNotification2.threadId === threadId
|
|
3442
3592
|
);
|
|
@@ -3548,9 +3698,10 @@ function useMarkRoomThreadAsUnresolved(roomId) {
|
|
|
3548
3698
|
function useThreadSubscription(threadId) {
|
|
3549
3699
|
const client = useClient();
|
|
3550
3700
|
const { store } = getRoomExtrasForClient(client);
|
|
3701
|
+
const signal = store.outputs.threadifications;
|
|
3551
3702
|
const selector = React4.useCallback(
|
|
3552
3703
|
(state) => {
|
|
3553
|
-
const notification = state.
|
|
3704
|
+
const notification = state.sortedNotifications.find(
|
|
3554
3705
|
(inboxNotification) => inboxNotification.kind === "thread" && inboxNotification.threadId === threadId
|
|
3555
3706
|
);
|
|
3556
3707
|
const thread = state.threadsDB.get(threadId);
|
|
@@ -3564,12 +3715,7 @@ function useThreadSubscription(threadId) {
|
|
|
3564
3715
|
},
|
|
3565
3716
|
[threadId]
|
|
3566
3717
|
);
|
|
3567
|
-
return
|
|
3568
|
-
store.subscribe,
|
|
3569
|
-
store.getFullState,
|
|
3570
|
-
store.getFullState,
|
|
3571
|
-
selector
|
|
3572
|
-
);
|
|
3718
|
+
return useSignal(signal, selector, _client.shallow);
|
|
3573
3719
|
}
|
|
3574
3720
|
function useRoomNotificationSettings() {
|
|
3575
3721
|
const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
|
|
@@ -3602,10 +3748,10 @@ function useRoomNotificationSettings() {
|
|
|
3602
3748
|
[store, room.id]
|
|
3603
3749
|
);
|
|
3604
3750
|
const settings = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
3605
|
-
store.
|
|
3751
|
+
store.subscribe2,
|
|
3606
3752
|
getter,
|
|
3607
3753
|
getter,
|
|
3608
|
-
|
|
3754
|
+
identity3,
|
|
3609
3755
|
shallow2
|
|
3610
3756
|
);
|
|
3611
3757
|
return React4.useMemo(() => {
|
|
@@ -3681,10 +3827,10 @@ function useHistoryVersions() {
|
|
|
3681
3827
|
// *next* render after that, a *new* fetch/promise will get created.
|
|
3682
3828
|
);
|
|
3683
3829
|
const state = _withselectorjs.useSyncExternalStoreWithSelector.call(void 0,
|
|
3684
|
-
store.
|
|
3830
|
+
store.subscribe3,
|
|
3685
3831
|
getter,
|
|
3686
3832
|
getter,
|
|
3687
|
-
|
|
3833
|
+
identity3,
|
|
3688
3834
|
shallow2
|
|
3689
3835
|
);
|
|
3690
3836
|
return state;
|
|
@@ -3828,7 +3974,7 @@ function useRoomAttachmentUrl(attachmentId, roomId) {
|
|
|
3828
3974
|
getAttachmentUrlState,
|
|
3829
3975
|
getAttachmentUrlState,
|
|
3830
3976
|
selectorFor_useAttachmentUrl,
|
|
3831
|
-
|
|
3977
|
+
_client.shallow
|
|
3832
3978
|
);
|
|
3833
3979
|
}
|
|
3834
3980
|
function useAttachmentUrlSuspense(attachmentId) {
|
|
@@ -3862,11 +4008,10 @@ function useAttachmentUrlSuspense(attachmentId) {
|
|
|
3862
4008
|
function useRoomPermissions(roomId) {
|
|
3863
4009
|
const client = useClient();
|
|
3864
4010
|
const store = getRoomExtrasForClient(client).store;
|
|
3865
|
-
return
|
|
3866
|
-
store.
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
), () => ( /* @__PURE__ */ new Set()));
|
|
4011
|
+
return useSignal(
|
|
4012
|
+
store.permissionHintsByRoomId,
|
|
4013
|
+
(hints) => _nullishCoalesce(hints[roomId], () => ( /* @__PURE__ */ new Set()))
|
|
4014
|
+
);
|
|
3870
4015
|
}
|
|
3871
4016
|
function createRoomContext(client) {
|
|
3872
4017
|
return getOrCreateRoomContextBundle(client);
|
|
@@ -4007,5 +4152,11 @@ var _useUpdateMyPresence = useUpdateMyPresence;
|
|
|
4007
4152
|
|
|
4008
4153
|
|
|
4009
4154
|
|
|
4010
|
-
|
|
4011
|
-
|
|
4155
|
+
|
|
4156
|
+
|
|
4157
|
+
|
|
4158
|
+
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
exports.RoomContext = RoomContext; exports.useRoomOrNull = useRoomOrNull; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClientOrNull = useClientOrNull; exports.useClient = useClient; exports.LiveblocksProvider = LiveblocksProvider; exports.createLiveblocksContext = createLiveblocksContext; exports.useInboxNotifications = useInboxNotifications; exports.useInboxNotificationsSuspense = useInboxNotificationsSuspense; exports.useMarkAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead; exports.useMarkInboxNotificationAsRead = useMarkInboxNotificationAsRead; exports.useDeleteAllInboxNotifications = useDeleteAllInboxNotifications; exports.useDeleteInboxNotification = useDeleteInboxNotification; exports.useUnreadInboxNotificationsCount = useUnreadInboxNotificationsCount; exports.useUnreadInboxNotificationsCountSuspense = useUnreadInboxNotificationsCountSuspense; exports.useRoomInfo = useRoomInfo; exports.useRoomInfoSuspense = useRoomInfoSuspense; exports._useInboxNotificationThread = _useInboxNotificationThread; exports._useUser = _useUser; exports._useUserSuspense = _useUserSuspense; exports._useUserThreads_experimental = _useUserThreads_experimental; exports._useUserThreadsSuspense_experimental = _useUserThreadsSuspense_experimental; exports.useSyncStatus = useSyncStatus; exports.CreateThreadError = CreateThreadError; exports.useSignal = useSignal; exports.useStatus = useStatus; exports.useReportTextEditor = useReportTextEditor; exports.useYjsProvider = useYjsProvider; exports.useCreateTextMention = useCreateTextMention; exports.useDeleteTextMention = useDeleteTextMention; exports.useResolveMentionSuggestions = useResolveMentionSuggestions; exports.useMentionSuggestionsCache = useMentionSuggestionsCache; exports.useStorageStatus = useStorageStatus; exports.useBatch = useBatch; exports.useLostConnectionListener = useLostConnectionListener; exports.useErrorListener = useErrorListener; exports.useHistory = useHistory; exports.useUndo = useUndo; exports.useRedo = useRedo; exports.useCanUndo = useCanUndo; exports.useCanRedo = useCanRedo; exports.useOthersConnectionIds = useOthersConnectionIds; exports.useCommentsErrorListener = useCommentsErrorListener; exports.useCreateRoomThread = useCreateRoomThread; exports.useDeleteRoomThread = useDeleteRoomThread; exports.useEditRoomThreadMetadata = useEditRoomThreadMetadata; exports.useCreateComment = useCreateComment; exports.useCreateRoomComment = useCreateRoomComment; exports.useEditComment = useEditComment; exports.useEditRoomComment = useEditRoomComment; exports.useDeleteComment = useDeleteComment; exports.useDeleteRoomComment = useDeleteRoomComment; exports.useAddRoomCommentReaction = useAddRoomCommentReaction; exports.useRemoveReaction = useRemoveReaction; exports.useRemoveRoomCommentReaction = useRemoveRoomCommentReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkRoomThreadAsRead = useMarkRoomThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkRoomThreadAsResolved = useMarkRoomThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useMarkRoomThreadAsUnresolved = useMarkRoomThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.useAttachmentUrl = useAttachmentUrl; exports.useRoomAttachmentUrl = useRoomAttachmentUrl; exports.useAttachmentUrlSuspense = useAttachmentUrlSuspense; exports.useRoomPermissions = useRoomPermissions; exports.createRoomContext = createRoomContext; exports._RoomProvider = _RoomProvider; exports._useBroadcastEvent = _useBroadcastEvent; exports._useOthersListener = _useOthersListener; exports._useRoom = _useRoom; exports._useIsInsideRoom = _useIsInsideRoom; exports._useAddReaction = _useAddReaction; exports._useMutation = _useMutation; exports._useCreateThread = _useCreateThread; exports._useDeleteThread = _useDeleteThread; exports._useEditThreadMetadata = _useEditThreadMetadata; exports._useEventListener = _useEventListener; exports._useMyPresence = _useMyPresence; exports._useOthersMapped = _useOthersMapped; exports._useOthersMappedSuspense = _useOthersMappedSuspense; exports._useThreads = _useThreads; exports._useThreadsSuspense = _useThreadsSuspense; exports._useRoomNotificationSettings = _useRoomNotificationSettings; exports._useRoomNotificationSettingsSuspense = _useRoomNotificationSettingsSuspense; exports._useHistoryVersions = _useHistoryVersions; exports._useHistoryVersionsSuspense = _useHistoryVersionsSuspense; exports._useOther = _useOther; exports._useOthers = _useOthers; exports._useOtherSuspense = _useOtherSuspense; exports._useOthersSuspense = _useOthersSuspense; exports._useStorage = _useStorage; exports._useStorageSuspense = _useStorageSuspense; exports._useSelf = _useSelf; exports._useSelfSuspense = _useSelfSuspense; exports._useStorageRoot = _useStorageRoot; exports._useUpdateMyPresence = _useUpdateMyPresence;
|
|
4162
|
+
//# sourceMappingURL=chunk-N33NEN5R.js.map
|