@liveblocks/core 2.15.1 → 2.16.0-toolbars1
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 +287 -248
- package/dist/index.d.ts +287 -248
- package/dist/index.js +2903 -2833
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +443 -373
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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.16.0-toolbars1";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -170,9 +170,6 @@ var errorWithTitle = wrapWithTitle("error");
|
|
|
170
170
|
function raise(msg) {
|
|
171
171
|
throw new Error(msg);
|
|
172
172
|
}
|
|
173
|
-
function isPlainObject(blob) {
|
|
174
|
-
return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
|
|
175
|
-
}
|
|
176
173
|
function entries(obj) {
|
|
177
174
|
return Object.entries(obj);
|
|
178
175
|
}
|
|
@@ -385,19 +382,319 @@ function makeBufferableEventSource() {
|
|
|
385
382
|
};
|
|
386
383
|
}
|
|
387
384
|
|
|
385
|
+
// src/lib/freeze.ts
|
|
386
|
+
var freeze = process.env.NODE_ENV === "production" ? (
|
|
387
|
+
/* istanbul ignore next */
|
|
388
|
+
(x) => x
|
|
389
|
+
) : Object.freeze;
|
|
390
|
+
|
|
391
|
+
// src/lib/signals.ts
|
|
392
|
+
var kSinks = Symbol("kSinks");
|
|
393
|
+
var kTrigger = Symbol("kTrigger");
|
|
394
|
+
var signalsToTrigger = null;
|
|
395
|
+
var trackedReads = null;
|
|
396
|
+
function batch(callback) {
|
|
397
|
+
if (signalsToTrigger !== null) {
|
|
398
|
+
callback();
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
signalsToTrigger = /* @__PURE__ */ new Set();
|
|
402
|
+
try {
|
|
403
|
+
callback();
|
|
404
|
+
} finally {
|
|
405
|
+
for (const signal of signalsToTrigger) {
|
|
406
|
+
signal[kTrigger]();
|
|
407
|
+
}
|
|
408
|
+
signalsToTrigger = null;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function enqueueTrigger(signal) {
|
|
412
|
+
if (!signalsToTrigger) raise("Expected to be in an active batch");
|
|
413
|
+
signalsToTrigger.add(signal);
|
|
414
|
+
}
|
|
415
|
+
function merge(target, patch) {
|
|
416
|
+
let updated = false;
|
|
417
|
+
const newValue = { ...target };
|
|
418
|
+
Object.keys(patch).forEach((k) => {
|
|
419
|
+
const key = k;
|
|
420
|
+
const val = patch[key];
|
|
421
|
+
if (newValue[key] !== val) {
|
|
422
|
+
if (val === void 0) {
|
|
423
|
+
delete newValue[key];
|
|
424
|
+
} else {
|
|
425
|
+
newValue[key] = val;
|
|
426
|
+
}
|
|
427
|
+
updated = true;
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
return updated ? newValue : target;
|
|
431
|
+
}
|
|
432
|
+
var AbstractSignal = class {
|
|
433
|
+
/** @internal */
|
|
434
|
+
equals;
|
|
435
|
+
#eventSource;
|
|
436
|
+
/** @internal */
|
|
437
|
+
[kSinks];
|
|
438
|
+
constructor(equals) {
|
|
439
|
+
this.equals = equals ?? Object.is;
|
|
440
|
+
this.#eventSource = makeEventSource();
|
|
441
|
+
this[kSinks] = /* @__PURE__ */ new Set();
|
|
442
|
+
this.get = this.get.bind(this);
|
|
443
|
+
this.subscribe = this.subscribe.bind(this);
|
|
444
|
+
this.subscribeOnce = this.subscribeOnce.bind(this);
|
|
445
|
+
}
|
|
446
|
+
[Symbol.dispose]() {
|
|
447
|
+
this.#eventSource[Symbol.dispose]();
|
|
448
|
+
this.#eventSource = "(disposed)";
|
|
449
|
+
this.equals = "(disposed)";
|
|
450
|
+
}
|
|
451
|
+
get hasWatchers() {
|
|
452
|
+
if (this.#eventSource.count() > 0) return true;
|
|
453
|
+
for (const sink of this[kSinks]) {
|
|
454
|
+
if (sink.hasWatchers) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
[kTrigger]() {
|
|
461
|
+
this.#eventSource.notify();
|
|
462
|
+
for (const sink of this[kSinks]) {
|
|
463
|
+
enqueueTrigger(sink);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
subscribe(callback) {
|
|
467
|
+
if (this.#eventSource.count() === 0) {
|
|
468
|
+
this.get();
|
|
469
|
+
}
|
|
470
|
+
return this.#eventSource.subscribe(callback);
|
|
471
|
+
}
|
|
472
|
+
subscribeOnce(callback) {
|
|
473
|
+
const unsub = this.subscribe(() => {
|
|
474
|
+
unsub();
|
|
475
|
+
return callback();
|
|
476
|
+
});
|
|
477
|
+
return unsub;
|
|
478
|
+
}
|
|
479
|
+
waitUntil() {
|
|
480
|
+
throw new Error("waitUntil not supported on Signals");
|
|
481
|
+
}
|
|
482
|
+
markSinksDirty() {
|
|
483
|
+
for (const sink of this[kSinks]) {
|
|
484
|
+
sink.markDirty();
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
addSink(sink) {
|
|
488
|
+
this[kSinks].add(sink);
|
|
489
|
+
}
|
|
490
|
+
removeSink(sink) {
|
|
491
|
+
this[kSinks].delete(sink);
|
|
492
|
+
}
|
|
493
|
+
asReadonly() {
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var Signal = class extends AbstractSignal {
|
|
498
|
+
#value;
|
|
499
|
+
constructor(value, equals) {
|
|
500
|
+
super(equals);
|
|
501
|
+
this.#value = freeze(value);
|
|
502
|
+
}
|
|
503
|
+
[Symbol.dispose]() {
|
|
504
|
+
super[Symbol.dispose]();
|
|
505
|
+
this.#value = "(disposed)";
|
|
506
|
+
}
|
|
507
|
+
get() {
|
|
508
|
+
trackedReads?.add(this);
|
|
509
|
+
return this.#value;
|
|
510
|
+
}
|
|
511
|
+
set(newValue) {
|
|
512
|
+
batch(() => {
|
|
513
|
+
if (typeof newValue === "function") {
|
|
514
|
+
newValue = newValue(this.#value);
|
|
515
|
+
}
|
|
516
|
+
if (!this.equals(this.#value, newValue)) {
|
|
517
|
+
this.#value = freeze(newValue);
|
|
518
|
+
this.markSinksDirty();
|
|
519
|
+
enqueueTrigger(this);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
var PatchableSignal = class extends Signal {
|
|
525
|
+
constructor(data) {
|
|
526
|
+
super(freeze(compactObject(data)));
|
|
527
|
+
}
|
|
528
|
+
set() {
|
|
529
|
+
throw new Error("Don't call .set() directly, use .patch()");
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Patches the current object.
|
|
533
|
+
*/
|
|
534
|
+
patch(patch) {
|
|
535
|
+
super.set((old) => merge(old, patch));
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
var INITIAL = Symbol();
|
|
539
|
+
var DerivedSignal = class _DerivedSignal extends AbstractSignal {
|
|
540
|
+
#prevValue;
|
|
541
|
+
#dirty;
|
|
542
|
+
// When true, the value in #value may not be up-to-date and needs re-checking
|
|
543
|
+
#sources;
|
|
544
|
+
#deps;
|
|
545
|
+
#transform;
|
|
546
|
+
// prettier-ignore
|
|
547
|
+
static from(...args) {
|
|
548
|
+
const last = args.pop();
|
|
549
|
+
if (typeof last !== "function")
|
|
550
|
+
raise("Invalid .from() call, last argument expected to be a function");
|
|
551
|
+
if (typeof args[args.length - 1] === "function") {
|
|
552
|
+
const equals = last;
|
|
553
|
+
const transform = args.pop();
|
|
554
|
+
return new _DerivedSignal(args, transform, equals);
|
|
555
|
+
} else {
|
|
556
|
+
const transform = last;
|
|
557
|
+
return new _DerivedSignal(args, transform);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
constructor(deps, transform, equals) {
|
|
561
|
+
super(equals);
|
|
562
|
+
this.#dirty = true;
|
|
563
|
+
this.#prevValue = INITIAL;
|
|
564
|
+
this.#deps = deps;
|
|
565
|
+
this.#sources = /* @__PURE__ */ new Set();
|
|
566
|
+
this.#transform = transform;
|
|
567
|
+
}
|
|
568
|
+
[Symbol.dispose]() {
|
|
569
|
+
for (const src of this.#sources) {
|
|
570
|
+
src.removeSink(this);
|
|
571
|
+
}
|
|
572
|
+
this.#prevValue = "(disposed)";
|
|
573
|
+
this.#sources = "(disposed)";
|
|
574
|
+
this.#deps = "(disposed)";
|
|
575
|
+
this.#transform = "(disposed)";
|
|
576
|
+
}
|
|
577
|
+
get isDirty() {
|
|
578
|
+
return this.#dirty;
|
|
579
|
+
}
|
|
580
|
+
#recompute() {
|
|
581
|
+
const oldTrackedReads = trackedReads;
|
|
582
|
+
let derived;
|
|
583
|
+
trackedReads = /* @__PURE__ */ new Set();
|
|
584
|
+
try {
|
|
585
|
+
derived = this.#transform(...this.#deps.map((p) => p.get()));
|
|
586
|
+
} finally {
|
|
587
|
+
const oldSources = this.#sources;
|
|
588
|
+
this.#sources = /* @__PURE__ */ new Set();
|
|
589
|
+
for (const sig of trackedReads) {
|
|
590
|
+
this.#sources.add(sig);
|
|
591
|
+
oldSources.delete(sig);
|
|
592
|
+
}
|
|
593
|
+
for (const oldSource of oldSources) {
|
|
594
|
+
oldSource.removeSink(this);
|
|
595
|
+
}
|
|
596
|
+
for (const newSource of this.#sources) {
|
|
597
|
+
newSource.addSink(this);
|
|
598
|
+
}
|
|
599
|
+
trackedReads = oldTrackedReads;
|
|
600
|
+
}
|
|
601
|
+
this.#dirty = false;
|
|
602
|
+
if (!this.equals(this.#prevValue, derived)) {
|
|
603
|
+
this.#prevValue = derived;
|
|
604
|
+
return true;
|
|
605
|
+
}
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
markDirty() {
|
|
609
|
+
if (!this.#dirty) {
|
|
610
|
+
this.#dirty = true;
|
|
611
|
+
this.markSinksDirty();
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
get() {
|
|
615
|
+
if (this.#dirty) {
|
|
616
|
+
this.#recompute();
|
|
617
|
+
}
|
|
618
|
+
trackedReads?.add(this);
|
|
619
|
+
return this.#prevValue;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Called by the Signal system if one or more of the dependent signals have
|
|
623
|
+
* changed. In the case of a DerivedSignal, we'll only want to re-evaluate
|
|
624
|
+
* the actual value if it's being watched, or any of their sinks are being
|
|
625
|
+
* watched actively.
|
|
626
|
+
*/
|
|
627
|
+
[kTrigger]() {
|
|
628
|
+
if (!this.hasWatchers) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
const updated = this.#recompute();
|
|
632
|
+
if (updated) {
|
|
633
|
+
super[kTrigger]();
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
var MutableSignal = class extends AbstractSignal {
|
|
638
|
+
#state;
|
|
639
|
+
constructor(initialState) {
|
|
640
|
+
super();
|
|
641
|
+
this.#state = initialState;
|
|
642
|
+
}
|
|
643
|
+
[Symbol.dispose]() {
|
|
644
|
+
super[Symbol.dispose]();
|
|
645
|
+
this.#state = "(disposed)";
|
|
646
|
+
}
|
|
647
|
+
get() {
|
|
648
|
+
trackedReads?.add(this);
|
|
649
|
+
return this.#state;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Invokes a callback function that is allowed to mutate the given state
|
|
653
|
+
* value. Do not change the value outside of the callback.
|
|
654
|
+
*
|
|
655
|
+
* If the callback explicitly returns `false`, it's assumed that the state
|
|
656
|
+
* was not changed.
|
|
657
|
+
*/
|
|
658
|
+
mutate(callback) {
|
|
659
|
+
batch(() => {
|
|
660
|
+
const result = callback ? callback(this.#state) : true;
|
|
661
|
+
if (result !== null && typeof result === "object" && "then" in result) {
|
|
662
|
+
raise("MutableSignal.mutate() does not support async callbacks");
|
|
663
|
+
}
|
|
664
|
+
if (result !== false) {
|
|
665
|
+
this.markSinksDirty();
|
|
666
|
+
enqueueTrigger(this);
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
|
|
388
672
|
// src/lib/stringify.ts
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
673
|
+
var EXPLICIT_UNDEFINED_PLACEHOLDER = "_explicit_undefined";
|
|
674
|
+
function replacer(_key, value) {
|
|
675
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).sort().reduce((sorted, key) => {
|
|
676
|
+
sorted[key] = value[key];
|
|
677
|
+
return sorted;
|
|
678
|
+
}, {}) : value === void 0 ? EXPLICIT_UNDEFINED_PLACEHOLDER : value;
|
|
679
|
+
}
|
|
680
|
+
function reviver(key, value) {
|
|
681
|
+
if (!key && value === EXPLICIT_UNDEFINED_PLACEHOLDER) {
|
|
682
|
+
return void 0;
|
|
683
|
+
}
|
|
684
|
+
if (value && typeof value === "object") {
|
|
685
|
+
for (const k in value) {
|
|
686
|
+
if (value[k] === EXPLICIT_UNDEFINED_PLACEHOLDER) {
|
|
687
|
+
Object.defineProperty(value, k, { value: void 0 });
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return value;
|
|
692
|
+
}
|
|
693
|
+
function stringify(value) {
|
|
694
|
+
return JSON.stringify(value, replacer);
|
|
695
|
+
}
|
|
696
|
+
function unstringify(value) {
|
|
697
|
+
return JSON.parse(value, reviver);
|
|
401
698
|
}
|
|
402
699
|
|
|
403
700
|
// src/lib/batch.ts
|
|
@@ -492,57 +789,58 @@ var Batch = class {
|
|
|
492
789
|
}
|
|
493
790
|
};
|
|
494
791
|
function createBatchStore(batch2) {
|
|
495
|
-
const
|
|
496
|
-
const eventSource2 = makeEventSource();
|
|
792
|
+
const signal = new MutableSignal(/* @__PURE__ */ new Map());
|
|
497
793
|
function getCacheKey(args) {
|
|
498
794
|
return stringify(args);
|
|
499
795
|
}
|
|
500
|
-
function
|
|
501
|
-
|
|
502
|
-
|
|
796
|
+
function update(cacheKey, state) {
|
|
797
|
+
signal.mutate((cache) => {
|
|
798
|
+
cache.set(cacheKey, state);
|
|
799
|
+
});
|
|
503
800
|
}
|
|
504
801
|
function invalidate(inputs) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
802
|
+
signal.mutate((cache) => {
|
|
803
|
+
if (Array.isArray(inputs)) {
|
|
804
|
+
for (const input of inputs) {
|
|
805
|
+
cache.delete(getCacheKey(input));
|
|
806
|
+
}
|
|
807
|
+
} else {
|
|
808
|
+
cache.clear();
|
|
508
809
|
}
|
|
509
|
-
}
|
|
510
|
-
cache.clear();
|
|
511
|
-
}
|
|
512
|
-
eventSource2.notify();
|
|
810
|
+
});
|
|
513
811
|
}
|
|
514
|
-
async function
|
|
812
|
+
async function enqueue(input) {
|
|
515
813
|
const cacheKey = getCacheKey(input);
|
|
814
|
+
const cache = signal.get();
|
|
516
815
|
if (cache.has(cacheKey)) {
|
|
517
816
|
return;
|
|
518
817
|
}
|
|
519
818
|
try {
|
|
520
|
-
|
|
819
|
+
update(cacheKey, { isLoading: true });
|
|
521
820
|
const result = await batch2.get(input);
|
|
522
|
-
|
|
821
|
+
update(cacheKey, { isLoading: false, data: result });
|
|
523
822
|
} catch (error3) {
|
|
524
|
-
|
|
823
|
+
update(cacheKey, {
|
|
525
824
|
isLoading: false,
|
|
526
825
|
error: error3
|
|
527
826
|
});
|
|
528
827
|
}
|
|
529
828
|
}
|
|
530
|
-
function
|
|
829
|
+
function getItemState(input) {
|
|
531
830
|
const cacheKey = getCacheKey(input);
|
|
831
|
+
const cache = signal.get();
|
|
532
832
|
return cache.get(cacheKey);
|
|
533
833
|
}
|
|
534
834
|
function _cacheKeys() {
|
|
835
|
+
const cache = signal.get();
|
|
535
836
|
return [...cache.keys()];
|
|
536
837
|
}
|
|
537
|
-
function getBatch() {
|
|
538
|
-
return batch2;
|
|
539
|
-
}
|
|
540
838
|
return {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
839
|
+
subscribe: signal.subscribe,
|
|
840
|
+
enqueue,
|
|
841
|
+
getItemState,
|
|
544
842
|
invalidate,
|
|
545
|
-
|
|
843
|
+
batch: batch2,
|
|
546
844
|
_cacheKeys
|
|
547
845
|
};
|
|
548
846
|
}
|
|
@@ -583,6 +881,44 @@ function createInboxNotificationId() {
|
|
|
583
881
|
return createOptimisticId(INBOX_NOTIFICATION_ID_PREFIX);
|
|
584
882
|
}
|
|
585
883
|
|
|
884
|
+
// src/lib/DefaultMap.ts
|
|
885
|
+
var DefaultMap = class extends Map {
|
|
886
|
+
#defaultFn;
|
|
887
|
+
/**
|
|
888
|
+
* If the default function is not provided to the constructor, it has to be
|
|
889
|
+
* provided in each .getOrCreate() call individually.
|
|
890
|
+
*/
|
|
891
|
+
constructor(defaultFn, entries2) {
|
|
892
|
+
super(entries2);
|
|
893
|
+
this.#defaultFn = defaultFn;
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Gets the value at the given key, or creates it.
|
|
897
|
+
*
|
|
898
|
+
* Difference from normal Map: if the key does not exist, it will be created
|
|
899
|
+
* on the fly using the factory function, and that value will get returned
|
|
900
|
+
* instead of `undefined`.
|
|
901
|
+
*/
|
|
902
|
+
getOrCreate(key, defaultFn) {
|
|
903
|
+
if (super.has(key)) {
|
|
904
|
+
return super.get(key);
|
|
905
|
+
} else {
|
|
906
|
+
const fn = defaultFn ?? this.#defaultFn ?? raise("DefaultMap used without a factory function");
|
|
907
|
+
const value = fn(key);
|
|
908
|
+
this.set(key, value);
|
|
909
|
+
return value;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
// src/lib/guards.ts
|
|
915
|
+
function isPlainObject(blob) {
|
|
916
|
+
return blob !== null && typeof blob === "object" && Object.prototype.toString.call(blob) === "[object Object]";
|
|
917
|
+
}
|
|
918
|
+
function isStartsWithOperator(blob) {
|
|
919
|
+
return isPlainObject(blob) && typeof blob.startsWith === "string";
|
|
920
|
+
}
|
|
921
|
+
|
|
586
922
|
// src/lib/objectToQuery.ts
|
|
587
923
|
var identifierRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
588
924
|
function objectToQuery(obj) {
|
|
@@ -597,10 +933,12 @@ function objectToQuery(obj) {
|
|
|
597
933
|
}
|
|
598
934
|
if (isSimpleValue(value)) {
|
|
599
935
|
keyValuePairs.push([key, value]);
|
|
600
|
-
} else if (
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
936
|
+
} else if (isPlainObject(value)) {
|
|
937
|
+
if (isStartsWithOperator(value)) {
|
|
938
|
+
keyValuePairsWithOperator.push([key, value]);
|
|
939
|
+
} else {
|
|
940
|
+
indexedKeys.push([key, value]);
|
|
941
|
+
}
|
|
604
942
|
}
|
|
605
943
|
});
|
|
606
944
|
filterList = [
|
|
@@ -617,7 +955,7 @@ function objectToQuery(obj) {
|
|
|
617
955
|
}
|
|
618
956
|
if (isSimpleValue(nestedValue)) {
|
|
619
957
|
nKeyValuePairs.push([formatFilterKey(key, nestedKey), nestedValue]);
|
|
620
|
-
} else if (
|
|
958
|
+
} else if (isStartsWithOperator(nestedValue)) {
|
|
621
959
|
nKeyValuePairsWithOperator.push([
|
|
622
960
|
formatFilterKey(key, nestedKey),
|
|
623
961
|
nestedValue
|
|
@@ -659,16 +997,7 @@ var getFiltersFromKeyValuePairsWithOperator = (keyValuePairsWithOperator) => {
|
|
|
659
997
|
return filters;
|
|
660
998
|
};
|
|
661
999
|
var isSimpleValue = (value) => {
|
|
662
|
-
|
|
663
|
-
return true;
|
|
664
|
-
}
|
|
665
|
-
return false;
|
|
666
|
-
};
|
|
667
|
-
var isValueWithOperator = (value) => {
|
|
668
|
-
if (typeof value === "object" && value !== null && "startsWith" in value) {
|
|
669
|
-
return true;
|
|
670
|
-
}
|
|
671
|
-
return false;
|
|
1000
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
672
1001
|
};
|
|
673
1002
|
var formatFilter = (key, operator, value) => {
|
|
674
1003
|
return `${key}${operator}${value}`;
|
|
@@ -1083,40 +1412,31 @@ function createApiClient({
|
|
|
1083
1412
|
}
|
|
1084
1413
|
}
|
|
1085
1414
|
}
|
|
1086
|
-
const
|
|
1415
|
+
const attachmentUrlsBatchStoresByRoom = new DefaultMap((roomId) => {
|
|
1416
|
+
const batch2 = new Batch(
|
|
1417
|
+
async (batchedAttachmentIds) => {
|
|
1418
|
+
const attachmentIds = batchedAttachmentIds.flat();
|
|
1419
|
+
const { urls } = await httpClient.post(
|
|
1420
|
+
url`/v2/c/rooms/${roomId}/attachments/presigned-urls`,
|
|
1421
|
+
await authManager.getAuthValue({
|
|
1422
|
+
requestedScope: "comments:read",
|
|
1423
|
+
roomId
|
|
1424
|
+
}),
|
|
1425
|
+
{ attachmentIds }
|
|
1426
|
+
);
|
|
1427
|
+
return urls.map(
|
|
1428
|
+
(url2) => url2 ?? new Error("There was an error while getting this attachment's URL")
|
|
1429
|
+
);
|
|
1430
|
+
},
|
|
1431
|
+
{ delay: 50 }
|
|
1432
|
+
);
|
|
1433
|
+
return createBatchStore(batch2);
|
|
1434
|
+
});
|
|
1087
1435
|
function getOrCreateAttachmentUrlsStore(roomId) {
|
|
1088
|
-
|
|
1089
|
-
if (store === void 0) {
|
|
1090
|
-
const batch2 = new Batch(
|
|
1091
|
-
async (batchedAttachmentIds) => {
|
|
1092
|
-
const attachmentIds = batchedAttachmentIds.flat();
|
|
1093
|
-
const { urls } = await httpClient.post(
|
|
1094
|
-
url`/v2/c/rooms/${roomId}/attachments/presigned-urls`,
|
|
1095
|
-
await authManager.getAuthValue({
|
|
1096
|
-
requestedScope: "comments:read",
|
|
1097
|
-
roomId
|
|
1098
|
-
}),
|
|
1099
|
-
{
|
|
1100
|
-
attachmentIds
|
|
1101
|
-
}
|
|
1102
|
-
);
|
|
1103
|
-
return urls.map(
|
|
1104
|
-
(url2) => url2 ?? new Error(
|
|
1105
|
-
"There was an error while getting this attachment's URL"
|
|
1106
|
-
)
|
|
1107
|
-
);
|
|
1108
|
-
},
|
|
1109
|
-
{
|
|
1110
|
-
delay: 50
|
|
1111
|
-
}
|
|
1112
|
-
);
|
|
1113
|
-
store = createBatchStore(batch2);
|
|
1114
|
-
getAttachmentUrlsBatchStoreByRoom.set(roomId, store);
|
|
1115
|
-
}
|
|
1116
|
-
return store;
|
|
1436
|
+
return attachmentUrlsBatchStoresByRoom.getOrCreate(roomId);
|
|
1117
1437
|
}
|
|
1118
1438
|
function getAttachmentUrl(options) {
|
|
1119
|
-
const batch2 = getOrCreateAttachmentUrlsStore(options.roomId).
|
|
1439
|
+
const batch2 = getOrCreateAttachmentUrlsStore(options.roomId).batch;
|
|
1120
1440
|
return batch2.get(options.attachmentId);
|
|
1121
1441
|
}
|
|
1122
1442
|
async function getNotificationSettings(options) {
|
|
@@ -1142,33 +1462,25 @@ function createApiClient({
|
|
|
1142
1462
|
options.settings
|
|
1143
1463
|
);
|
|
1144
1464
|
}
|
|
1145
|
-
const
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
{
|
|
1163
|
-
delay: 50
|
|
1164
|
-
}
|
|
1165
|
-
);
|
|
1166
|
-
markInboxNotificationsAsReadBatchByRoom.set(roomId, batch2);
|
|
1167
|
-
}
|
|
1168
|
-
return batch2;
|
|
1169
|
-
}
|
|
1465
|
+
const markAsReadBatchesByRoom = new DefaultMap(
|
|
1466
|
+
(roomId) => new Batch(
|
|
1467
|
+
async (batchedInboxNotificationIds) => {
|
|
1468
|
+
const inboxNotificationIds = batchedInboxNotificationIds.flat();
|
|
1469
|
+
await httpClient.post(
|
|
1470
|
+
url`/v2/c/rooms/${roomId}/inbox-notifications/read`,
|
|
1471
|
+
await authManager.getAuthValue({
|
|
1472
|
+
requestedScope: "comments:read",
|
|
1473
|
+
roomId
|
|
1474
|
+
}),
|
|
1475
|
+
{ inboxNotificationIds }
|
|
1476
|
+
);
|
|
1477
|
+
return inboxNotificationIds;
|
|
1478
|
+
},
|
|
1479
|
+
{ delay: 50 }
|
|
1480
|
+
)
|
|
1481
|
+
);
|
|
1170
1482
|
async function markRoomInboxNotificationAsRead(options) {
|
|
1171
|
-
const batch2 =
|
|
1483
|
+
const batch2 = markAsReadBatchesByRoom.getOrCreate(options.roomId);
|
|
1172
1484
|
return batch2.get(options.inboxNotificationId);
|
|
1173
1485
|
}
|
|
1174
1486
|
async function createTextMention(options) {
|
|
@@ -2166,6 +2478,7 @@ function toNewConnectionStatus(machine) {
|
|
|
2166
2478
|
return machine.context.successCount > 0 ? "reconnecting" : "connecting";
|
|
2167
2479
|
case "@idle.failed":
|
|
2168
2480
|
return "disconnected";
|
|
2481
|
+
// istanbul ignore next
|
|
2169
2482
|
default:
|
|
2170
2483
|
return assertNever(state, "Unknown state");
|
|
2171
2484
|
}
|
|
@@ -3046,6 +3359,12 @@ function setupDevTools(getAllRooms) {
|
|
|
3046
3359
|
_devtoolsSetupHasRun = true;
|
|
3047
3360
|
onMessageFromPanel.subscribe((msg) => {
|
|
3048
3361
|
switch (msg.msg) {
|
|
3362
|
+
// When a devtool panel sends an explicit "connect" message back to this
|
|
3363
|
+
// live running client (in response to the "wake-up-devtools" message,
|
|
3364
|
+
// or when the devtool panel is opened for the first time), it means that it's okay to
|
|
3365
|
+
// start emitting messages.
|
|
3366
|
+
// Before this explicit acknowledgement, any call to sendToPanel() will
|
|
3367
|
+
// be a no-op.
|
|
3049
3368
|
case "connect": {
|
|
3050
3369
|
activateBridge(true);
|
|
3051
3370
|
for (const roomId of getAllRooms()) {
|
|
@@ -3186,6 +3505,8 @@ function linkDevTools(roomId, room) {
|
|
|
3186
3505
|
// roomChannelListeners registry
|
|
3187
3506
|
onMessageFromPanel.subscribe((msg) => {
|
|
3188
3507
|
switch (msg.msg) {
|
|
3508
|
+
// Sent by the devtool panel when it wants to receive the sync stream
|
|
3509
|
+
// for a room
|
|
3189
3510
|
case "room::subscribe": {
|
|
3190
3511
|
if (msg.roomId === roomId) {
|
|
3191
3512
|
startSyncStream(room);
|
|
@@ -3214,267 +3535,6 @@ function unlinkDevTools(roomId) {
|
|
|
3214
3535
|
});
|
|
3215
3536
|
}
|
|
3216
3537
|
|
|
3217
|
-
// src/lib/freeze.ts
|
|
3218
|
-
var freeze = process.env.NODE_ENV === "production" ? (
|
|
3219
|
-
/* istanbul ignore next */
|
|
3220
|
-
(x) => x
|
|
3221
|
-
) : Object.freeze;
|
|
3222
|
-
|
|
3223
|
-
// src/lib/signals.ts
|
|
3224
|
-
var kSinks = Symbol("kSinks");
|
|
3225
|
-
var kTrigger = Symbol("kTrigger");
|
|
3226
|
-
var signalsToTrigger = null;
|
|
3227
|
-
function batch(callback) {
|
|
3228
|
-
if (signalsToTrigger !== null) {
|
|
3229
|
-
callback();
|
|
3230
|
-
return;
|
|
3231
|
-
}
|
|
3232
|
-
signalsToTrigger = /* @__PURE__ */ new Set();
|
|
3233
|
-
try {
|
|
3234
|
-
callback();
|
|
3235
|
-
} finally {
|
|
3236
|
-
for (const signal of signalsToTrigger) {
|
|
3237
|
-
signal[kTrigger]();
|
|
3238
|
-
}
|
|
3239
|
-
signalsToTrigger = null;
|
|
3240
|
-
}
|
|
3241
|
-
}
|
|
3242
|
-
function enqueueTrigger(signal) {
|
|
3243
|
-
if (!signalsToTrigger) raise("Expected to be in an active batch");
|
|
3244
|
-
signalsToTrigger.add(signal);
|
|
3245
|
-
}
|
|
3246
|
-
function merge(target, patch) {
|
|
3247
|
-
let updated = false;
|
|
3248
|
-
const newValue = { ...target };
|
|
3249
|
-
Object.keys(patch).forEach((k) => {
|
|
3250
|
-
const key = k;
|
|
3251
|
-
const val = patch[key];
|
|
3252
|
-
if (newValue[key] !== val) {
|
|
3253
|
-
if (val === void 0) {
|
|
3254
|
-
delete newValue[key];
|
|
3255
|
-
} else {
|
|
3256
|
-
newValue[key] = val;
|
|
3257
|
-
}
|
|
3258
|
-
updated = true;
|
|
3259
|
-
}
|
|
3260
|
-
});
|
|
3261
|
-
return updated ? newValue : target;
|
|
3262
|
-
}
|
|
3263
|
-
var AbstractSignal = class {
|
|
3264
|
-
/** @internal */
|
|
3265
|
-
equals;
|
|
3266
|
-
#eventSource;
|
|
3267
|
-
/** @internal */
|
|
3268
|
-
[kSinks];
|
|
3269
|
-
constructor(equals) {
|
|
3270
|
-
this.equals = equals ?? Object.is;
|
|
3271
|
-
this.#eventSource = makeEventSource();
|
|
3272
|
-
this[kSinks] = /* @__PURE__ */ new Set();
|
|
3273
|
-
this.get = this.get.bind(this);
|
|
3274
|
-
this.subscribe = this.subscribe.bind(this);
|
|
3275
|
-
this.subscribeOnce = this.subscribeOnce.bind(this);
|
|
3276
|
-
}
|
|
3277
|
-
[Symbol.dispose]() {
|
|
3278
|
-
this.#eventSource[Symbol.dispose]();
|
|
3279
|
-
this.#eventSource = "(disposed)";
|
|
3280
|
-
this.equals = "(disposed)";
|
|
3281
|
-
}
|
|
3282
|
-
get hasWatchers() {
|
|
3283
|
-
if (this.#eventSource.count() > 0) return true;
|
|
3284
|
-
for (const sink of this[kSinks]) {
|
|
3285
|
-
if (sink.hasWatchers) {
|
|
3286
|
-
return true;
|
|
3287
|
-
}
|
|
3288
|
-
}
|
|
3289
|
-
return false;
|
|
3290
|
-
}
|
|
3291
|
-
[kTrigger]() {
|
|
3292
|
-
this.#eventSource.notify();
|
|
3293
|
-
for (const sink of this[kSinks]) {
|
|
3294
|
-
enqueueTrigger(sink);
|
|
3295
|
-
}
|
|
3296
|
-
}
|
|
3297
|
-
subscribe(callback) {
|
|
3298
|
-
return this.#eventSource.subscribe(callback);
|
|
3299
|
-
}
|
|
3300
|
-
subscribeOnce(callback) {
|
|
3301
|
-
const unsub = this.subscribe(() => {
|
|
3302
|
-
unsub();
|
|
3303
|
-
return callback();
|
|
3304
|
-
});
|
|
3305
|
-
return unsub;
|
|
3306
|
-
}
|
|
3307
|
-
waitUntil() {
|
|
3308
|
-
throw new Error("waitUntil not supported on Signals");
|
|
3309
|
-
}
|
|
3310
|
-
markSinksDirty() {
|
|
3311
|
-
for (const sink of this[kSinks]) {
|
|
3312
|
-
sink.markDirty();
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
addSink(sink) {
|
|
3316
|
-
this[kSinks].add(sink);
|
|
3317
|
-
}
|
|
3318
|
-
removeSink(sink) {
|
|
3319
|
-
this[kSinks].delete(sink);
|
|
3320
|
-
}
|
|
3321
|
-
asReadonly() {
|
|
3322
|
-
return this;
|
|
3323
|
-
}
|
|
3324
|
-
};
|
|
3325
|
-
var Signal = class extends AbstractSignal {
|
|
3326
|
-
#value;
|
|
3327
|
-
constructor(value, equals) {
|
|
3328
|
-
super(equals);
|
|
3329
|
-
this.#value = freeze(value);
|
|
3330
|
-
}
|
|
3331
|
-
[Symbol.dispose]() {
|
|
3332
|
-
super[Symbol.dispose]();
|
|
3333
|
-
this.#value = "(disposed)";
|
|
3334
|
-
}
|
|
3335
|
-
get() {
|
|
3336
|
-
return this.#value;
|
|
3337
|
-
}
|
|
3338
|
-
set(newValue) {
|
|
3339
|
-
batch(() => {
|
|
3340
|
-
if (typeof newValue === "function") {
|
|
3341
|
-
newValue = newValue(this.#value);
|
|
3342
|
-
}
|
|
3343
|
-
if (!this.equals(this.#value, newValue)) {
|
|
3344
|
-
this.#value = freeze(newValue);
|
|
3345
|
-
this.markSinksDirty();
|
|
3346
|
-
enqueueTrigger(this);
|
|
3347
|
-
}
|
|
3348
|
-
});
|
|
3349
|
-
}
|
|
3350
|
-
};
|
|
3351
|
-
var PatchableSignal = class extends Signal {
|
|
3352
|
-
constructor(data) {
|
|
3353
|
-
super(freeze(compactObject(data)));
|
|
3354
|
-
}
|
|
3355
|
-
set() {
|
|
3356
|
-
throw new Error("Don't call .set() directly, use .patch()");
|
|
3357
|
-
}
|
|
3358
|
-
/**
|
|
3359
|
-
* Patches the current object.
|
|
3360
|
-
*/
|
|
3361
|
-
patch(patch) {
|
|
3362
|
-
super.set((old) => merge(old, patch));
|
|
3363
|
-
}
|
|
3364
|
-
};
|
|
3365
|
-
var INITIAL = Symbol();
|
|
3366
|
-
var DerivedSignal = class _DerivedSignal extends AbstractSignal {
|
|
3367
|
-
#prevValue;
|
|
3368
|
-
#dirty;
|
|
3369
|
-
// When true, the value in #value may not be up-to-date and needs re-checking
|
|
3370
|
-
#parents;
|
|
3371
|
-
#transform;
|
|
3372
|
-
// prettier-ignore
|
|
3373
|
-
static from(...args) {
|
|
3374
|
-
const last = args.pop();
|
|
3375
|
-
if (typeof last !== "function")
|
|
3376
|
-
raise("Invalid .from() call, last argument expected to be a function");
|
|
3377
|
-
if (typeof args[args.length - 1] === "function") {
|
|
3378
|
-
const equals = last;
|
|
3379
|
-
const transform = args.pop();
|
|
3380
|
-
return new _DerivedSignal(args, transform, equals);
|
|
3381
|
-
} else {
|
|
3382
|
-
const transform = last;
|
|
3383
|
-
return new _DerivedSignal(args, transform);
|
|
3384
|
-
}
|
|
3385
|
-
}
|
|
3386
|
-
constructor(parents, transform, equals) {
|
|
3387
|
-
super(equals);
|
|
3388
|
-
this.#dirty = true;
|
|
3389
|
-
this.#prevValue = INITIAL;
|
|
3390
|
-
this.#parents = parents;
|
|
3391
|
-
this.#transform = transform;
|
|
3392
|
-
for (const parent of parents) {
|
|
3393
|
-
parent.addSink(this);
|
|
3394
|
-
}
|
|
3395
|
-
}
|
|
3396
|
-
[Symbol.dispose]() {
|
|
3397
|
-
for (const parent of this.#parents) {
|
|
3398
|
-
parent.removeSink(this);
|
|
3399
|
-
}
|
|
3400
|
-
this.#prevValue = "(disposed)";
|
|
3401
|
-
this.#parents = "(disposed)";
|
|
3402
|
-
this.#transform = "(disposed)";
|
|
3403
|
-
}
|
|
3404
|
-
get isDirty() {
|
|
3405
|
-
return this.#dirty;
|
|
3406
|
-
}
|
|
3407
|
-
#recompute() {
|
|
3408
|
-
const derived = this.#transform(...this.#parents.map((p) => p.get()));
|
|
3409
|
-
this.#dirty = false;
|
|
3410
|
-
if (!this.equals(this.#prevValue, derived)) {
|
|
3411
|
-
this.#prevValue = derived;
|
|
3412
|
-
return true;
|
|
3413
|
-
}
|
|
3414
|
-
return false;
|
|
3415
|
-
}
|
|
3416
|
-
markDirty() {
|
|
3417
|
-
if (!this.#dirty) {
|
|
3418
|
-
this.#dirty = true;
|
|
3419
|
-
this.markSinksDirty();
|
|
3420
|
-
}
|
|
3421
|
-
}
|
|
3422
|
-
get() {
|
|
3423
|
-
if (this.#dirty) {
|
|
3424
|
-
this.#recompute();
|
|
3425
|
-
}
|
|
3426
|
-
return this.#prevValue;
|
|
3427
|
-
}
|
|
3428
|
-
/**
|
|
3429
|
-
* Called by the Signal system if one or more of the dependent signals have
|
|
3430
|
-
* changed. In the case of a DerivedSignal, we'll only want to re-evaluate
|
|
3431
|
-
* the actual value if it's being watched, or any of their sinks are being
|
|
3432
|
-
* watched actively.
|
|
3433
|
-
*/
|
|
3434
|
-
[kTrigger]() {
|
|
3435
|
-
if (!this.hasWatchers) {
|
|
3436
|
-
return;
|
|
3437
|
-
}
|
|
3438
|
-
const updated = this.#recompute();
|
|
3439
|
-
if (updated) {
|
|
3440
|
-
super[kTrigger]();
|
|
3441
|
-
}
|
|
3442
|
-
}
|
|
3443
|
-
};
|
|
3444
|
-
var MutableSignal = class extends AbstractSignal {
|
|
3445
|
-
#state;
|
|
3446
|
-
constructor(initialState) {
|
|
3447
|
-
super();
|
|
3448
|
-
this.#state = initialState;
|
|
3449
|
-
}
|
|
3450
|
-
[Symbol.dispose]() {
|
|
3451
|
-
super[Symbol.dispose]();
|
|
3452
|
-
this.#state = "(disposed)";
|
|
3453
|
-
}
|
|
3454
|
-
get() {
|
|
3455
|
-
return this.#state;
|
|
3456
|
-
}
|
|
3457
|
-
/**
|
|
3458
|
-
* Invokes a callback function that is allowed to mutate the given state
|
|
3459
|
-
* value. Do not change the value outside of the callback.
|
|
3460
|
-
*
|
|
3461
|
-
* If the callback explicitly returns `false`, it's assumed that the state
|
|
3462
|
-
* was not changed.
|
|
3463
|
-
*/
|
|
3464
|
-
mutate(callback) {
|
|
3465
|
-
batch(() => {
|
|
3466
|
-
const result = callback ? callback(this.#state) : true;
|
|
3467
|
-
if (result !== null && typeof result === "object" && "then" in result) {
|
|
3468
|
-
raise("MutableSignal.mutate() does not support async callbacks");
|
|
3469
|
-
}
|
|
3470
|
-
if (result !== false) {
|
|
3471
|
-
this.markSinksDirty();
|
|
3472
|
-
enqueueTrigger(this);
|
|
3473
|
-
}
|
|
3474
|
-
});
|
|
3475
|
-
}
|
|
3476
|
-
};
|
|
3477
|
-
|
|
3478
3538
|
// src/lib/position.ts
|
|
3479
3539
|
var MIN_CODE = 32;
|
|
3480
3540
|
var MAX_CODE = 126;
|
|
@@ -6889,6 +6949,7 @@ function createRoom(options, config) {
|
|
|
6889
6949
|
processInitialStorage(message);
|
|
6890
6950
|
break;
|
|
6891
6951
|
}
|
|
6952
|
+
// Write event
|
|
6892
6953
|
case 201 /* UPDATE_STORAGE */: {
|
|
6893
6954
|
const applyResult = applyOps(message.ops, false);
|
|
6894
6955
|
for (const [key, value] of applyResult.updates.storageUpdates) {
|
|
@@ -6899,6 +6960,11 @@ function createRoom(options, config) {
|
|
|
6899
6960
|
}
|
|
6900
6961
|
break;
|
|
6901
6962
|
}
|
|
6963
|
+
// Receiving a RejectedOps message in the client means that the server is no
|
|
6964
|
+
// longer in sync with the client. Trying to synchronize the client again by
|
|
6965
|
+
// rolling back particular Ops may be hard/impossible. It's fine to not try and
|
|
6966
|
+
// accept the out-of-sync reality and throw an error. We look at this kind of bug
|
|
6967
|
+
// as a developer-owned bug. In production, these errors are not expected to happen.
|
|
6902
6968
|
case 299 /* REJECT_STORAGE_OP */: {
|
|
6903
6969
|
errorWithTitle(
|
|
6904
6970
|
"Storage mutation rejection error",
|
|
@@ -7560,6 +7626,7 @@ function makeClassicSubscribeFn(events) {
|
|
|
7560
7626
|
return events.comments.subscribe(
|
|
7561
7627
|
callback
|
|
7562
7628
|
);
|
|
7629
|
+
// istanbul ignore next
|
|
7563
7630
|
default:
|
|
7564
7631
|
return assertNever(
|
|
7565
7632
|
first,
|
|
@@ -8842,6 +8909,7 @@ export {
|
|
|
8842
8909
|
ClientMsgCode,
|
|
8843
8910
|
CommentsApiError,
|
|
8844
8911
|
CrdtType,
|
|
8912
|
+
DefaultMap,
|
|
8845
8913
|
DerivedSignal,
|
|
8846
8914
|
HttpError,
|
|
8847
8915
|
LiveList,
|
|
@@ -8896,6 +8964,7 @@ export {
|
|
|
8896
8964
|
isLiveNode,
|
|
8897
8965
|
isPlainObject,
|
|
8898
8966
|
isRootCrdt,
|
|
8967
|
+
isStartsWithOperator,
|
|
8899
8968
|
kInternal,
|
|
8900
8969
|
legacy_patchImmutableObject,
|
|
8901
8970
|
lsonToJson,
|
|
@@ -8917,6 +8986,7 @@ export {
|
|
|
8917
8986
|
toAbsoluteUrl,
|
|
8918
8987
|
toPlainLson,
|
|
8919
8988
|
tryParseJson,
|
|
8989
|
+
unstringify,
|
|
8920
8990
|
url,
|
|
8921
8991
|
urljoin,
|
|
8922
8992
|
wait,
|