jazz-tools 0.13.16 → 0.13.18
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +19 -0
- package/dist/{chunk-GIZWJXSR.js → chunk-ITSHLDQB.js} +731 -600
- package/dist/chunk-ITSHLDQB.js.map +1 -0
- package/dist/coValues/account.d.ts +5 -4
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/coFeed.d.ts +3 -3
- package/dist/coValues/coFeed.d.ts.map +1 -1
- package/dist/coValues/coList.d.ts +1 -0
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coMap.d.ts +4 -2
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coPlainText.d.ts +2 -2
- package/dist/coValues/coPlainText.d.ts.map +1 -1
- package/dist/coValues/deepLoading.d.ts +1 -9
- package/dist/coValues/deepLoading.d.ts.map +1 -1
- package/dist/coValues/extensions/imageDef.d.ts.map +1 -1
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/inbox.d.ts.map +1 -1
- package/dist/coValues/interfaces.d.ts +4 -1
- package/dist/coValues/interfaces.d.ts.map +1 -1
- package/dist/implementation/createContext.d.ts.map +1 -1
- package/dist/implementation/refs.d.ts +5 -10
- package/dist/implementation/refs.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/subscribe/CoValueCoreSubscription.d.ts +14 -0
- package/dist/subscribe/CoValueCoreSubscription.d.ts.map +1 -0
- package/dist/subscribe/JazzError.d.ts +16 -0
- package/dist/subscribe/JazzError.d.ts.map +1 -0
- package/dist/subscribe/SubscriptionScope.d.ts +42 -0
- package/dist/subscribe/SubscriptionScope.d.ts.map +1 -0
- package/dist/subscribe/index.d.ts +21 -0
- package/dist/subscribe/index.d.ts.map +1 -0
- package/dist/subscribe/types.d.ts +12 -0
- package/dist/subscribe/types.d.ts.map +1 -0
- package/dist/subscribe/utils.d.ts +10 -0
- package/dist/subscribe/utils.d.ts.map +1 -0
- package/dist/testing.js +2 -2
- package/dist/testing.js.map +1 -1
- package/dist/tests/coMap.record.test.d.ts +2 -0
- package/dist/tests/coMap.record.test.d.ts.map +1 -0
- package/dist/tests/utils.d.ts +2 -2
- package/dist/tests/utils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/coValues/account.ts +43 -31
- package/src/coValues/coFeed.ts +28 -13
- package/src/coValues/coList.ts +13 -17
- package/src/coValues/coMap.ts +72 -80
- package/src/coValues/coPlainText.ts +13 -2
- package/src/coValues/deepLoading.ts +4 -277
- package/src/coValues/extensions/imageDef.ts +1 -7
- package/src/coValues/group.ts +7 -6
- package/src/coValues/inbox.ts +4 -11
- package/src/coValues/interfaces.ts +54 -111
- package/src/implementation/createContext.ts +3 -4
- package/src/implementation/invites.ts +2 -2
- package/src/implementation/refs.ts +30 -121
- package/src/internal.ts +1 -2
- package/src/subscribe/CoValueCoreSubscription.ts +71 -0
- package/src/subscribe/JazzError.ts +48 -0
- package/src/subscribe/SubscriptionScope.ts +523 -0
- package/src/subscribe/index.ts +82 -0
- package/src/subscribe/types.ts +7 -0
- package/src/subscribe/utils.ts +36 -0
- package/src/testing.ts +1 -1
- package/src/tests/ContextManager.test.ts +13 -9
- package/src/tests/coFeed.test.ts +104 -4
- package/src/tests/coList.test.ts +304 -115
- package/src/tests/coMap.record.test.ts +325 -0
- package/src/tests/coMap.test.ts +718 -645
- package/src/tests/coPlainText.test.ts +2 -2
- package/src/tests/createContext.test.ts +8 -8
- package/src/tests/deepLoading.test.ts +8 -34
- package/src/tests/groupsAndAccounts.test.ts +6 -4
- package/src/tests/subscribe.test.ts +357 -42
- package/src/tests/utils.ts +8 -6
- package/tsconfig.json +2 -1
- package/dist/chunk-GIZWJXSR.js.map +0 -1
- package/dist/implementation/subscriptionScope.d.ts +0 -34
- package/dist/implementation/subscriptionScope.d.ts.map +0 -1
- package/src/implementation/subscriptionScope.ts +0 -165
package/src/tests/coList.test.ts
CHANGED
@@ -1,27 +1,40 @@
|
|
1
1
|
import { cojsonInternals } from "cojson";
|
2
2
|
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
3
|
-
import { describe, expect, test } from "vitest";
|
3
|
+
import { beforeEach, describe, expect, test, vi } from "vitest";
|
4
4
|
import {
|
5
5
|
Account,
|
6
6
|
CoList,
|
7
7
|
CoMap,
|
8
8
|
Group,
|
9
|
+
Resolved,
|
9
10
|
co,
|
10
11
|
createJazzContextFromExistingCredentials,
|
11
12
|
isControlledAccount,
|
13
|
+
subscribeToCoValue,
|
12
14
|
} from "../index.js";
|
13
15
|
import { randomSessionProvider } from "../internal.js";
|
16
|
+
import { createJazzTestAccount, setupJazzTestSync } from "../testing.js";
|
17
|
+
import { waitFor } from "./utils.js";
|
14
18
|
|
15
19
|
const connectedPeers = cojsonInternals.connectedPeers;
|
16
20
|
|
17
21
|
const Crypto = await WasmCrypto.create();
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
let me = await Account.create({
|
24
|
+
creationProps: { name: "Hermes Puggington" },
|
25
|
+
crypto: Crypto,
|
26
|
+
});
|
27
|
+
|
28
|
+
beforeEach(async () => {
|
29
|
+
await setupJazzTestSync();
|
30
|
+
|
31
|
+
me = await createJazzTestAccount({
|
32
|
+
isCurrentActiveAccount: true,
|
21
33
|
creationProps: { name: "Hermes Puggington" },
|
22
|
-
crypto: Crypto,
|
23
34
|
});
|
35
|
+
});
|
24
36
|
|
37
|
+
describe("Simple CoList operations", async () => {
|
25
38
|
class TestList extends CoList.Of(co.string) {}
|
26
39
|
|
27
40
|
const list = TestList.create(["bread", "butter", "onion"], { owner: me });
|
@@ -347,11 +360,6 @@ describe("Simple CoList operations", async () => {
|
|
347
360
|
});
|
348
361
|
|
349
362
|
describe("CoList applyDiff operations", async () => {
|
350
|
-
const me = await Account.create({
|
351
|
-
creationProps: { name: "Hermes Puggington" },
|
352
|
-
crypto: Crypto,
|
353
|
-
});
|
354
|
-
|
355
363
|
test("applyDiff with primitive values", () => {
|
356
364
|
class StringList extends CoList.Of(co.string) {}
|
357
365
|
const list = StringList.create(["a", "b", "c"], { owner: me });
|
@@ -485,147 +493,328 @@ describe("CoList resolution", async () => {
|
|
485
493
|
expect(list[0]?.[0]?.id).toBeDefined();
|
486
494
|
expect(list[1]?.[0]?.[0]).toBe("c");
|
487
495
|
});
|
496
|
+
});
|
488
497
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
peer1role: "server",
|
494
|
-
peer2role: "client",
|
495
|
-
});
|
496
|
-
if (!isControlledAccount(me)) {
|
497
|
-
throw "me is not a controlled account";
|
498
|
+
describe("CoList subscription", async () => {
|
499
|
+
test("subscription on a locally available list with deep resolve", async () => {
|
500
|
+
class Item extends CoMap {
|
501
|
+
name = co.string;
|
498
502
|
}
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
503
|
+
|
504
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
505
|
+
|
506
|
+
const list = TestList.create(
|
507
|
+
[Item.create({ name: "Item 1" }), Item.create({ name: "Item 2" })],
|
508
|
+
{ owner: me },
|
509
|
+
);
|
510
|
+
|
511
|
+
const updates: Resolved<TestList, { $each: true }>[] = [];
|
512
|
+
const spy = vi.fn((list) => updates.push(list));
|
513
|
+
|
514
|
+
TestList.subscribe(
|
515
|
+
list.id,
|
516
|
+
{
|
517
|
+
resolve: {
|
518
|
+
$each: true,
|
505
519
|
},
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
});
|
520
|
+
},
|
521
|
+
spy,
|
522
|
+
);
|
510
523
|
|
511
|
-
|
524
|
+
expect(spy).not.toHaveBeenCalled();
|
512
525
|
|
513
|
-
expect(
|
514
|
-
expect(loadedList?._refs[0]?.id).toEqual(list[0]!.id);
|
526
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
515
527
|
|
516
|
-
|
517
|
-
|
518
|
-
|
528
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
529
|
+
|
530
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
531
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
532
|
+
|
533
|
+
list[0]!.name = "Updated Item 1";
|
519
534
|
|
520
|
-
expect(
|
521
|
-
|
522
|
-
expect(
|
523
|
-
|
524
|
-
|
525
|
-
expect(
|
526
|
-
|
535
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
536
|
+
|
537
|
+
expect(updates[1]?.[0]?.name).toEqual("Updated Item 1");
|
538
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
539
|
+
|
540
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
541
|
+
});
|
542
|
+
|
543
|
+
test("subscription on a locally available list with autoload", async () => {
|
544
|
+
class Item extends CoMap {
|
545
|
+
name = co.string;
|
546
|
+
}
|
547
|
+
|
548
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
549
|
+
|
550
|
+
const list = TestList.create(
|
551
|
+
[Item.create({ name: "Item 1" }), Item.create({ name: "Item 2" })],
|
552
|
+
{ owner: me },
|
527
553
|
);
|
528
554
|
|
529
|
-
const
|
530
|
-
|
531
|
-
|
555
|
+
const updates: TestList[] = [];
|
556
|
+
const spy = vi.fn((list) => updates.push(list));
|
557
|
+
|
558
|
+
TestList.subscribe(list.id, {}, spy);
|
559
|
+
|
560
|
+
expect(spy).not.toHaveBeenCalled();
|
561
|
+
|
562
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
563
|
+
|
564
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
565
|
+
|
566
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
567
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
568
|
+
|
569
|
+
list[0]!.name = "Updated Item 1";
|
570
|
+
|
571
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
572
|
+
|
573
|
+
expect(updates[1]?.[0]?.name).toEqual("Updated Item 1");
|
574
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
532
575
|
|
533
|
-
expect(
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
576
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
577
|
+
});
|
578
|
+
|
579
|
+
test("subscription on a locally available list with syncResolution", async () => {
|
580
|
+
class Item extends CoMap {
|
581
|
+
name = co.string;
|
582
|
+
}
|
583
|
+
|
584
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
585
|
+
|
586
|
+
const list = TestList.create(
|
587
|
+
[Item.create({ name: "Item 1" }), Item.create({ name: "Item 2" })],
|
588
|
+
{ owner: me },
|
541
589
|
);
|
542
590
|
|
543
|
-
const
|
544
|
-
|
545
|
-
|
591
|
+
const updates: TestList[] = [];
|
592
|
+
const spy = vi.fn((list) => updates.push(list));
|
593
|
+
|
594
|
+
subscribeToCoValue(
|
595
|
+
TestList,
|
596
|
+
list.id,
|
597
|
+
{
|
598
|
+
syncResolution: true,
|
599
|
+
loadAs: Account.getMe(),
|
600
|
+
},
|
601
|
+
spy,
|
546
602
|
);
|
547
603
|
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
expect(
|
552
|
-
|
604
|
+
expect(spy).toHaveBeenCalled();
|
605
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
606
|
+
|
607
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
608
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
609
|
+
|
610
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
611
|
+
|
612
|
+
list[0]!.name = "Updated Item 1";
|
613
|
+
|
614
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
615
|
+
|
616
|
+
expect(updates[1]?.[0]?.name).toEqual("Updated Item 1");
|
617
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
618
|
+
|
619
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
620
|
+
});
|
621
|
+
|
622
|
+
test("subscription on a remotely available list with deep resolve", async () => {
|
623
|
+
class Item extends CoMap {
|
624
|
+
name = co.string;
|
625
|
+
}
|
626
|
+
|
627
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
628
|
+
|
629
|
+
const group = Group.create();
|
630
|
+
group.addMember("everyone", "writer");
|
631
|
+
|
632
|
+
const list = TestList.create(
|
633
|
+
[
|
634
|
+
Item.create({ name: "Item 1" }, group),
|
635
|
+
Item.create({ name: "Item 2" }, group),
|
636
|
+
],
|
637
|
+
group,
|
553
638
|
);
|
554
|
-
|
639
|
+
|
640
|
+
const userB = await createJazzTestAccount();
|
641
|
+
|
642
|
+
const updates: Resolved<TestList, { $each: true }>[] = [];
|
643
|
+
const spy = vi.fn((list) => updates.push(list));
|
644
|
+
|
645
|
+
TestList.subscribe(
|
646
|
+
list.id,
|
647
|
+
{
|
648
|
+
resolve: {
|
649
|
+
$each: true,
|
650
|
+
},
|
651
|
+
loadAs: userB,
|
652
|
+
},
|
653
|
+
spy,
|
654
|
+
);
|
655
|
+
|
656
|
+
expect(spy).not.toHaveBeenCalled();
|
657
|
+
|
658
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
659
|
+
|
660
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
661
|
+
|
662
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
663
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
664
|
+
|
665
|
+
list[0]!.name = "Updated Item 1";
|
666
|
+
|
667
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
668
|
+
|
669
|
+
expect(updates[1]?.[0]?.name).toEqual("Updated Item 1");
|
670
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
671
|
+
|
672
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
555
673
|
});
|
556
674
|
|
557
|
-
test("
|
558
|
-
|
675
|
+
test("subscription on a remotely available list with autoload", async () => {
|
676
|
+
class Item extends CoMap {
|
677
|
+
name = co.string;
|
678
|
+
}
|
559
679
|
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
680
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
681
|
+
|
682
|
+
const group = Group.create();
|
683
|
+
group.addMember("everyone", "writer");
|
684
|
+
|
685
|
+
const list = TestList.create(
|
686
|
+
[
|
687
|
+
Item.create({ name: "Item 1" }, group),
|
688
|
+
Item.create({ name: "Item 2" }, group),
|
689
|
+
],
|
690
|
+
group,
|
691
|
+
);
|
692
|
+
|
693
|
+
const updates: TestList[] = [];
|
694
|
+
const spy = vi.fn((list) => updates.push(list));
|
695
|
+
|
696
|
+
const userB = await createJazzTestAccount();
|
697
|
+
|
698
|
+
TestList.subscribe(
|
699
|
+
list.id,
|
700
|
+
{
|
701
|
+
loadAs: userB,
|
702
|
+
},
|
703
|
+
spy,
|
704
|
+
);
|
705
|
+
|
706
|
+
expect(spy).not.toHaveBeenCalled();
|
707
|
+
|
708
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
709
|
+
|
710
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
711
|
+
|
712
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
713
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
714
|
+
|
715
|
+
list[0]!.name = "Updated Item 1";
|
716
|
+
|
717
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
718
|
+
|
719
|
+
expect(updates[1]?.[0]?.name).toEqual("Updated Item 1");
|
720
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
721
|
+
|
722
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
723
|
+
});
|
724
|
+
|
725
|
+
test("replacing list items triggers updates", async () => {
|
726
|
+
class Item extends CoMap {
|
727
|
+
name = co.string;
|
566
728
|
}
|
567
|
-
me._raw.core.node.syncManager.addPeer(secondPeer);
|
568
|
-
const { account: meOnSecondPeer } =
|
569
|
-
await createJazzContextFromExistingCredentials({
|
570
|
-
credentials: {
|
571
|
-
accountID: me.id,
|
572
|
-
secret: me._raw.agentSecret,
|
573
|
-
},
|
574
|
-
sessionProvider: randomSessionProvider,
|
575
|
-
peersToLoadFrom: [initialAsPeer],
|
576
|
-
crypto: Crypto,
|
577
|
-
});
|
578
729
|
|
579
|
-
|
730
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
731
|
+
|
732
|
+
const list = TestList.create(
|
733
|
+
[Item.create({ name: "Item 1" }), Item.create({ name: "Item 2" })],
|
734
|
+
{ owner: me },
|
735
|
+
);
|
736
|
+
|
737
|
+
const updates: Resolved<TestList, { $each: true }>[] = [];
|
738
|
+
const spy = vi.fn((list) => updates.push(list));
|
580
739
|
|
581
740
|
TestList.subscribe(
|
582
741
|
list.id,
|
583
|
-
{
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
subscribedList?.[0]?.[0]?.[0],
|
588
|
-
);
|
589
|
-
void queue.push(subscribedList);
|
742
|
+
{
|
743
|
+
resolve: {
|
744
|
+
$each: true,
|
745
|
+
},
|
590
746
|
},
|
747
|
+
spy,
|
591
748
|
);
|
592
749
|
|
593
|
-
|
594
|
-
expect(update1?.[0]).toBe(null);
|
750
|
+
expect(spy).not.toHaveBeenCalled();
|
595
751
|
|
596
|
-
|
597
|
-
expect(update2?.[0]).toBeDefined();
|
598
|
-
expect(update2?.[0]?.[0]).toBe(null);
|
752
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
599
753
|
|
600
|
-
|
601
|
-
expect(update3?.[0]?.[0]).toBeDefined();
|
602
|
-
expect(update3?.[0]?.[0]?.[0]).toBe("a");
|
603
|
-
expect(update3?.[0]?.[0]?.joined()).toBe("a,b");
|
754
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
604
755
|
|
605
|
-
|
756
|
+
expect(updates[0]?.[0]?.name).toEqual("Item 1");
|
757
|
+
expect(updates[0]?.[1]?.name).toEqual("Item 2");
|
606
758
|
|
607
|
-
|
608
|
-
expect(update4?.[0]?.[0]?.[0]).toBe("x");
|
759
|
+
list[0] = Item.create({ name: "New Item 1" });
|
609
760
|
|
610
|
-
|
761
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
611
762
|
|
612
|
-
|
613
|
-
|
614
|
-
});
|
763
|
+
expect(updates[1]?.[0]?.name).toEqual("New Item 1");
|
764
|
+
expect(updates[1]?.[1]?.name).toEqual("Item 2");
|
615
765
|
|
616
|
-
|
617
|
-
|
618
|
-
|
766
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
767
|
+
});
|
768
|
+
|
769
|
+
test("pushing a new item triggers updates correctly", async () => {
|
770
|
+
class Item extends CoMap {
|
771
|
+
name = co.string;
|
772
|
+
}
|
773
|
+
|
774
|
+
class TestList extends CoList.Of(co.ref(Item)) {}
|
775
|
+
|
776
|
+
const group = Group.create();
|
777
|
+
group.addMember("everyone", "writer");
|
778
|
+
|
779
|
+
const list = TestList.create(
|
780
|
+
[
|
781
|
+
Item.create({ name: "Item 1" }, group),
|
782
|
+
Item.create({ name: "Item 2" }, group),
|
783
|
+
],
|
784
|
+
group,
|
785
|
+
);
|
786
|
+
|
787
|
+
const updates: TestList[] = [];
|
788
|
+
const spy = vi.fn((list) => updates.push(list));
|
789
|
+
|
790
|
+
const userB = await createJazzTestAccount();
|
791
|
+
|
792
|
+
TestList.subscribe(
|
793
|
+
list.id,
|
794
|
+
{
|
795
|
+
loadAs: userB,
|
796
|
+
resolve: {
|
797
|
+
$each: true,
|
798
|
+
},
|
799
|
+
},
|
800
|
+
(update) => {
|
801
|
+
spy(update);
|
802
|
+
|
803
|
+
// The update should be triggered only when the new item is loaded
|
804
|
+
for (const item of update) {
|
805
|
+
expect(item).toBeDefined();
|
806
|
+
}
|
807
|
+
},
|
808
|
+
);
|
809
|
+
|
810
|
+
await waitFor(() => expect(spy).toHaveBeenCalled());
|
811
|
+
|
812
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
619
813
|
|
620
|
-
|
814
|
+
list.push(Item.create({ name: "Item 3" }, group));
|
621
815
|
|
622
|
-
|
623
|
-
expect(update5?.[0]?.[0]?.[0]).toBe("y");
|
624
|
-
expect(update5?.[0]?.[0]?.joined()).toBe("y,z");
|
816
|
+
await waitFor(() => expect(spy).toHaveBeenCalledTimes(2));
|
625
817
|
|
626
|
-
|
627
|
-
newTwiceNestedList[0] = "w";
|
628
|
-
const update6 = (await queue.next()).value;
|
629
|
-
expect(update6?.[0]?.[0]?.[0]).toBe("w");
|
818
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
630
819
|
});
|
631
820
|
});
|