@roc-db/test-utils 0.2.0-pre.101 → 0.2.0-pre.103

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.js CHANGED
@@ -21,7 +21,8 @@ import { entitySchemaGenerator as entitySchemaGenerator2 } from "roc-db";
21
21
  import { z as z2 } from "zod";
22
22
  var BlockParagraphSchema = entitySchemaGenerator2("BlockParagraph", {
23
23
  data: z2.object({
24
- content: z2.string().optional()
24
+ content: z2.string().optional(),
25
+ mentions: z2.array(z2.string()).optional()
25
26
  }),
26
27
  parents: z2.object({
27
28
  parent: PostRefSchema
@@ -168,7 +169,8 @@ var BlockRefSchema = z13.union([
168
169
  // src/entities/BlockParagraph.ts
169
170
  var BlockParagraph = new Entity4("BlockParagraph", {
170
171
  data: z14.object({
171
- content: z14.string().optional()
172
+ content: z14.string().optional(),
173
+ mentions: z14.array(z14.string()).optional()
172
174
  }),
173
175
  parents: z14.object({
174
176
  parent: z14.union([PostEntity.refSchema, BlockRefSchema])
@@ -235,6 +237,9 @@ var entities = [
235
237
  PostVersion,
236
238
  UserEntity
237
239
  ];
240
+ // src/operations/index.ts
241
+ import { pageEntities, pageMutations, redo, undo } from "roc-db";
242
+
238
243
  // src/operations/applyDraft.ts
239
244
  import { Query, QueryChain, writeOperation } from "roc-db";
240
245
  var applyDraft = writeOperation("applyDraft", DraftRefSchema, (txn) => {
@@ -437,29 +442,62 @@ var deleteDraft = writeOperation13("deleteDraft", DraftRefSchema, (txn) => {
437
442
  return QueryChain6(Query13(() => txn.deleteEntity(ref, true)), Query13(() => txn.deleteChangeSet(ref)));
438
443
  });
439
444
 
440
- // src/operations/deleteOrgSettings.ts
441
- import { Query as Query14, writeOperation as writeOperation14 } from "roc-db";
445
+ // src/operations/deleteUnmentionedBlockParagraph.ts
446
+ import { BadRequestError, Query as Query14, QueryChain as QueryChain7, writeOperation as writeOperation14 } from "roc-db";
442
447
  import { z as z30 } from "zod";
443
- var deleteOrgSettings = writeOperation14("deleteOrgSettings", z30.object({}).optional(), (txn) => Query14(() => txn.deleteEntity("OrgSettings")));
448
+ var deleteUnmentionedBlockParagraph = writeOperation14("deleteUnmentionedBlockParagraph", z30.object({
449
+ ref: BlockParagraphRefSchema,
450
+ mentionedByRef: BlockParagraphRefSchema
451
+ }).strict(), (txn) => {
452
+ const { ref, mentionedByRef } = txn.payload;
453
+ return QueryChain7(Query14(() => txn.readEntity(mentionedByRef)), Query14((mentionedBy) => {
454
+ if (mentionedBy.data.mentions?.includes(ref)) {
455
+ throw new BadRequestError("Delete not allowed. Paragraph is mentioned");
456
+ }
457
+ return txn.readEntity(ref);
458
+ }), Query14((block) => txn.readEntity(block.parents.parent)), Query14((parent) => txn.patchEntity(parent.ref, {
459
+ children: {
460
+ blocks: parent.children.blocks.filter((blockRef) => blockRef !== ref)
461
+ }
462
+ })), Query14(() => txn.deleteEntity(ref)));
463
+ }, { changeSetOnly: true });
464
+
465
+ // src/operations/duplicateBlockParagraph.ts
466
+ import { Query as Query15, QueryChain as QueryChain8, writeOperation as writeOperation15 } from "roc-db";
467
+ import { z as z31 } from "zod";
468
+ var duplicateBlockParagraph = writeOperation15("duplicateBlockParagraph", z31.object({ ref: BlockParagraphRefSchema }).strict(), (txn) => {
469
+ const copyRef = txn.createRef("BlockParagraph");
470
+ return QueryChain8(Query15(() => txn.readEntity(txn.payload.ref)), Query15((source) => txn.readEntity(source.parents.parent)), Query15((parent) => txn.patchEntity(parent.ref, {
471
+ children: { blocks: [...parent.children.blocks, copyRef] }
472
+ })), Query15((_parent, _readParent, source) => txn.createEntity(copyRef, {
473
+ parents: source.parents,
474
+ data: source.data
475
+ })));
476
+ }, { changeSetOnly: true, outputSchema: BlockParagraphSchema });
477
+
478
+ // src/operations/deleteOrgSettings.ts
479
+ import { Query as Query16, writeOperation as writeOperation16 } from "roc-db";
480
+ import { z as z32 } from "zod";
481
+ var deleteOrgSettings = writeOperation16("deleteOrgSettings", z32.object({}).optional(), (txn) => Query16(() => txn.deleteEntity("OrgSettings")));
444
482
 
445
483
  // src/operations/deletePost.ts
446
- import { Query as Query15, writeOperation as writeOperation15 } from "roc-db";
447
- var deletePost = writeOperation15("deletePost", PostRefSchema, (txn) => {
484
+ import { Query as Query17, writeOperation as writeOperation17 } from "roc-db";
485
+ var deletePost = writeOperation17("deletePost", PostRefSchema, (txn) => {
448
486
  const ref = txn.payload;
449
- return Query15(() => txn.deleteEntity(ref, true));
487
+ return Query17(() => txn.deleteEntity(ref, true));
450
488
  });
451
489
 
452
490
  // src/operations/duplicateDraft.ts
453
491
  import {
454
- Query as Query16,
455
- QueryChain as QueryChain7,
456
- writeOperation as writeOperation16
492
+ Query as Query18,
493
+ QueryChain as QueryChain9,
494
+ writeOperation as writeOperation18
457
495
  } from "roc-db";
458
- import { z as z31 } from "zod";
459
- var duplicateDraft = writeOperation16("duplicateDraft", z31.object({ sourceRef: DraftRefSchema, postRef: PostRefSchema }).strict(), (txn) => {
496
+ import { z as z33 } from "zod";
497
+ var duplicateDraft = writeOperation18("duplicateDraft", z33.object({ sourceRef: DraftRefSchema, postRef: PostRefSchema }).strict(), (txn) => {
460
498
  const newDraftRef = txn.createRef("Draft");
461
499
  const { sourceRef, postRef } = txn.payload;
462
- return QueryChain7(Query16(() => txn.createEntity(newDraftRef, { parents: { post: postRef } })), Query16(() => txn.duplicateChangeSetMutations(sourceRef, newDraftRef)), Query16((dup) => {
500
+ return QueryChain9(Query18(() => txn.createEntity(newDraftRef, { parents: { post: postRef } })), Query18(() => txn.duplicateChangeSetMutations(sourceRef, newDraftRef)), Query18((dup) => {
463
501
  const result = dup;
464
502
  return {
465
503
  draftRef: newDraftRef,
@@ -470,28 +508,28 @@ var duplicateDraft = writeOperation16("duplicateDraft", z31.object({ sourceRef:
470
508
  });
471
509
 
472
510
  // src/operations/moveBlocks.ts
473
- import { Query as Query17, QueryChain as QueryChain8, writeOperation as writeOperation17 } from "roc-db";
474
- import { z as z32 } from "zod";
475
- var PayloadSchema3 = z32.object({
476
- refs: z32.array(z32.union([BlockParagraphRefSchema, BlockRowRefSchema])),
477
- targetPosition: z32.number().min(0)
511
+ import { Query as Query19, QueryChain as QueryChain10, writeOperation as writeOperation19 } from "roc-db";
512
+ import { z as z34 } from "zod";
513
+ var PayloadSchema3 = z34.object({
514
+ refs: z34.array(z34.union([BlockParagraphRefSchema, BlockRowRefSchema])),
515
+ targetPosition: z34.number().min(0)
478
516
  }).strict();
479
- var moveBlocks = writeOperation17("moveBlocks", PayloadSchema3, (txn) => {
517
+ var moveBlocks = writeOperation19("moveBlocks", PayloadSchema3, (txn) => {
480
518
  const { refs } = txn.payload;
481
- return QueryChain8(Query17(() => txn.batchReadEntities(refs)), Query17((items) => {
519
+ return QueryChain10(Query19(() => txn.batchReadEntities(refs)), Query19((items) => {
482
520
  return "todo";
483
521
  }));
484
522
  });
485
523
 
486
524
  // src/operations/pageBlocks.ts
487
- import { Query as Query18, readOperation } from "roc-db";
488
- import { z as z33 } from "zod";
489
- var pageBlocks = readOperation("pageBlocks", z33.object({
490
- size: z33.number().default(100),
491
- parentRef: z33.string().optional()
525
+ import { Query as Query20, readOperation } from "roc-db";
526
+ import { z as z35 } from "zod";
527
+ var pageBlocks = readOperation("pageBlocks", z35.object({
528
+ size: z35.number().default(100),
529
+ parentRef: z35.string().optional()
492
530
  }), (txn) => {
493
531
  const { size, parentRef } = txn.payload;
494
- return Query18(() => txn.pageEntities({
532
+ return Query20(() => txn.pageEntities({
495
533
  entities: ["BlockImage", "BlockParagraph"],
496
534
  size,
497
535
  childrenOf: parentRef ? [parentRef] : []
@@ -499,50 +537,50 @@ var pageBlocks = readOperation("pageBlocks", z33.object({
499
537
  });
500
538
 
501
539
  // src/operations/pageEmptyEntitiesArray.ts
502
- import { Query as Query19, readOperation as readOperation2 } from "roc-db";
503
- import { z as z34 } from "zod";
504
- var pageEmptyEntitiesArray = readOperation2("pageEmptyEntitiesArray", z34.object({ size: z34.number().default(100) }), (txn) => {
540
+ import { Query as Query21, readOperation as readOperation2 } from "roc-db";
541
+ import { z as z36 } from "zod";
542
+ var pageEmptyEntitiesArray = readOperation2("pageEmptyEntitiesArray", z36.object({ size: z36.number().default(100) }), (txn) => {
505
543
  const { size } = txn.payload;
506
- return Query19(() => txn.pageEntities({ entities: [], size }));
544
+ return Query21(() => txn.pageEntities({ entities: [], size }));
507
545
  });
508
546
 
509
547
  // src/operations/pagePosts.ts
510
- import { Query as Query20, readOperation as readOperation3 } from "roc-db";
511
- import { z as z35 } from "zod";
512
- var pagePosts = readOperation3("pagePosts", z35.object({ size: z35.number().default(100) }).default({}), (txn) => {
548
+ import { Query as Query22, readOperation as readOperation3 } from "roc-db";
549
+ import { z as z37 } from "zod";
550
+ var pagePosts = readOperation3("pagePosts", z37.object({ size: z37.number().default(100) }).default({}), (txn) => {
513
551
  const { size } = txn.payload;
514
- return Query20(() => txn.pageEntities({ entities: ["Post"], size }));
552
+ return Query22(() => txn.pageEntities({ entities: ["Post"], size }));
515
553
  });
516
554
 
517
555
  // src/operations/pageSplat.ts
518
- import { Query as Query21, readOperation as readOperation4 } from "roc-db";
519
- import { z as z36 } from "zod";
520
- var pageSplat = readOperation4("pageSplat", z36.object({ size: z36.number().default(100) }), (txn) => {
556
+ import { Query as Query23, readOperation as readOperation4 } from "roc-db";
557
+ import { z as z38 } from "zod";
558
+ var pageSplat = readOperation4("pageSplat", z38.object({ size: z38.number().default(100) }), (txn) => {
521
559
  const { size } = txn.payload;
522
- return Query21(() => txn.pageEntities({ entities: "*", size }));
560
+ return Query23(() => txn.pageEntities({ entities: "*", size }));
523
561
  });
524
562
 
525
563
  // src/operations/pagePostsByTag.ts
526
- import { Query as Query22, readOperation as readOperation5 } from "roc-db";
527
- import { z as z37 } from "zod";
528
- var pagePostsByTag = readOperation5("pagePostsByTag", z37.string(), (txn) => {
564
+ import { Query as Query24, readOperation as readOperation5 } from "roc-db";
565
+ import { z as z39 } from "zod";
566
+ var pagePostsByTag = readOperation5("pagePostsByTag", z39.string(), (txn) => {
529
567
  const tag = txn.payload;
530
- return Query22(() => txn.pageEntitiesByIndex("Post", "tags", tag));
568
+ return Query24(() => txn.pageEntitiesByIndex("Post", "tags", tag));
531
569
  });
532
570
 
533
571
  // src/operations/readEntity.ts
534
- import { NotFoundError, Query as Query23, QueryChain as QueryChain9, readOperation as readOperation6 } from "roc-db";
535
- import { z as z38 } from "zod";
536
- var readEntity = readOperation6("readEntity", z38.string(), (txn) => {
572
+ import { NotFoundError, Query as Query25, QueryChain as QueryChain11, readOperation as readOperation6 } from "roc-db";
573
+ import { z as z40 } from "zod";
574
+ var readEntity = readOperation6("readEntity", z40.string(), (txn) => {
537
575
  const ref = txn.payload;
538
- return QueryChain9(Query23(() => txn.readEntity(ref)), Query23((entity) => {
576
+ return QueryChain11(Query25(() => txn.readEntity(ref)), Query25((entity) => {
539
577
  if (!entity) {
540
578
  throw new NotFoundError(ref);
541
579
  }
542
580
  return entity;
543
581
  }));
544
582
  }, {
545
- outputSchema: z38.union([
583
+ outputSchema: z40.union([
546
584
  PostSchema,
547
585
  BlockImageSchema,
548
586
  BlockParagraphSchema
@@ -550,11 +588,11 @@ var readEntity = readOperation6("readEntity", z38.string(), (txn) => {
550
588
  });
551
589
 
552
590
  // src/operations/readMutation.ts
553
- import { NotFoundError as NotFoundError2, Query as Query24, QueryChain as QueryChain10, readOperation as readOperation7 } from "roc-db";
554
- import { z as z39 } from "zod";
555
- var readMutation = readOperation7("readMutation", z39.string(), (txn) => {
591
+ import { NotFoundError as NotFoundError2, Query as Query26, QueryChain as QueryChain12, readOperation as readOperation7 } from "roc-db";
592
+ import { z as z41 } from "zod";
593
+ var readMutation = readOperation7("readMutation", z41.string(), (txn) => {
556
594
  const ref = txn.payload;
557
- return QueryChain10(Query24(() => txn.readMutation(ref)), Query24((entity) => {
595
+ return QueryChain12(Query26(() => txn.readMutation(ref)), Query26((entity) => {
558
596
  if (!entity) {
559
597
  throw new NotFoundError2(ref);
560
598
  }
@@ -563,57 +601,57 @@ var readMutation = readOperation7("readMutation", z39.string(), (txn) => {
563
601
  });
564
602
 
565
603
  // src/operations/readOrgSettings.ts
566
- import { Query as Query25, readOperation as readOperation8 } from "roc-db";
567
- import { z as z40 } from "zod";
568
- var readOrgSettings = readOperation8("readOrgSettings", z40.object({}).optional(), (txn) => Query25(() => txn.readEntity("OrgSettings", true)));
604
+ import { Query as Query27, readOperation as readOperation8 } from "roc-db";
605
+ import { z as z42 } from "zod";
606
+ var readOrgSettings = readOperation8("readOrgSettings", z42.object({}).optional(), (txn) => Query27(() => txn.readEntity("OrgSettings", true)));
569
607
 
570
608
  // src/operations/readPost.ts
571
- import { Query as Query26, readOperation as readOperation9 } from "roc-db";
609
+ import { Query as Query28, readOperation as readOperation9 } from "roc-db";
572
610
  var readPost = readOperation9("readPost", PostRefSchema, (txn) => {
573
611
  const ref = txn.payload;
574
- return Query26(() => txn.readEntity(ref, true));
612
+ return Query28(() => txn.readEntity(ref, true));
575
613
  }, { outputSchema: PostSchema });
576
614
 
577
615
  // src/operations/readPostBySlug.ts
578
- import { Query as Query27, readOperation as readOperation10 } from "roc-db";
579
- import { z as z41 } from "zod";
580
- var readPostBySlug = readOperation10("readPostBySlug", z41.string(), (txn) => {
616
+ import { Query as Query29, readOperation as readOperation10 } from "roc-db";
617
+ import { z as z43 } from "zod";
618
+ var readPostBySlug = readOperation10("readPostBySlug", z43.string(), (txn) => {
581
619
  const slug = txn.payload;
582
- return Query27(() => txn.readEntityByUniqueField("Post", "slug", slug));
620
+ return Query29(() => txn.readEntityByUniqueField("Post", "slug", slug));
583
621
  }, { outputSchema: PostSchema });
584
622
 
585
623
  // src/operations/testTransactionalEdits.ts
586
624
  import { expect } from "bun:test";
587
- import { Query as Query28, QueryChain as QueryChain11, writeOperation as writeOperation18 } from "roc-db";
588
- import { z as z42 } from "zod";
625
+ import { Query as Query30, QueryChain as QueryChain13, writeOperation as writeOperation20 } from "roc-db";
626
+ import { z as z44 } from "zod";
589
627
  var TestCreatePatchDeleteInSameTransaction = (txn, title) => {
590
628
  const postRef = txn.createRef("Post");
591
- return QueryChain11(Query28(() => txn.createEntity(postRef, {
629
+ return QueryChain13(Query30(() => txn.createEntity(postRef, {
592
630
  data: { title, tags: [] },
593
631
  children: { blocks: [] }
594
- })), Query28(() => txn.patchEntity(postRef, { data: { foo: "bar" } })), Query28((post) => {
632
+ })), Query30(() => txn.patchEntity(postRef, { data: { foo: "bar" } })), Query30((post) => {
595
633
  expect(post.data.title).toBe(title);
596
634
  expect(post.data.foo).toBe("bar");
597
- }), Query28(() => txn.patchEntity(postRef, { data: { foo: null, bar: "foo" } })), Query28((post) => {
635
+ }), Query30(() => txn.patchEntity(postRef, { data: { foo: null, bar: "foo" } })), Query30((post) => {
598
636
  expect(post.data.title).toBe(title);
599
637
  expect(post.data.foo).toBeUndefined();
600
638
  expect(post.data.bar).toBe("foo");
601
639
  expect(txn.log).toHaveLength(1);
602
640
  expect(txn.log.get(postRef)?.[0]).toBe("create");
603
- }), Query28((post) => txn.deleteEntity(postRef)), Query28((res) => {
641
+ }), Query30((post) => txn.deleteEntity(postRef)), Query30((res) => {
604
642
  expect(res).toBe(1);
605
643
  expect(txn.log).toHaveLength(0);
606
644
  }));
607
645
  };
608
646
  var TestUpdateAndDeleteInSameTransaction = (txn, ref) => {
609
- return QueryChain11(Query28(() => txn.patchEntity(ref, { data: { foo: "bar" } })), Query28((post) => {
647
+ return QueryChain13(Query30(() => txn.patchEntity(ref, { data: { foo: "bar" } })), Query30((post) => {
610
648
  expect(post.data.foo).toBe("bar");
611
- }), Query28(() => txn.patchEntity(ref, { data: { foo: null, bar: "foo" } })), Query28((post) => {
649
+ }), Query30(() => txn.patchEntity(ref, { data: { foo: null, bar: "foo" } })), Query30((post) => {
612
650
  expect(post.data.foo).toBeUndefined();
613
651
  expect(post.data.bar).toBe("foo");
614
652
  expect(txn.log).toHaveLength(1);
615
653
  expect(txn.log.get(ref)?.[0]).toBe("update");
616
- }), Query28((post) => txn.deleteEntity(ref)), Query28((res) => {
654
+ }), Query30((post) => txn.deleteEntity(ref)), Query30((res) => {
617
655
  expect(res).toBe(1);
618
656
  expect(txn.log).toHaveLength(1);
619
657
  expect(txn.log.get(ref)?.[0]).toBe("delete");
@@ -621,14 +659,14 @@ var TestUpdateAndDeleteInSameTransaction = (txn, ref) => {
621
659
  };
622
660
  var TestCreateOnExistingRef = (txn) => {
623
661
  const ref = txn.createRef("Post");
624
- return QueryChain11(Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })), Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })));
662
+ return QueryChain13(Query30(() => txn.createEntity(ref, { data: { foo: "bar" } })), Query30(() => txn.createEntity(ref, { data: { foo: "bar" } })));
625
663
  };
626
- var PayloadSchema4 = z42.object({
627
- name: z42.string().optional(),
664
+ var PayloadSchema4 = z44.object({
665
+ name: z44.string().optional(),
628
666
  post1ref: PostRefSchema.optional(),
629
667
  post2ref: PostRefSchema.optional()
630
668
  }).strict();
631
- var testTransactionalEdits = writeOperation18("testTransactionalEdits", PayloadSchema4, (txn) => {
669
+ var testTransactionalEdits = writeOperation20("testTransactionalEdits", PayloadSchema4, (txn) => {
632
670
  const { name, post1ref, post2ref } = txn.payload;
633
671
  if (name)
634
672
  return TestCreatePatchDeleteInSameTransaction(txn, name);
@@ -639,38 +677,56 @@ var testTransactionalEdits = writeOperation18("testTransactionalEdits", PayloadS
639
677
  }, {});
640
678
 
641
679
  // src/operations/updateBlockParagraph.ts
642
- import { Query as Query29, writeOperation as writeOperation19 } from "roc-db";
643
- import { z as z43 } from "zod";
644
- var updateBlockParagraph = writeOperation19("updateBlockParagraph", z43.object({
680
+ import { Query as Query31, writeOperation as writeOperation21 } from "roc-db";
681
+ import { z as z45 } from "zod";
682
+ var updateBlockParagraph = writeOperation21("updateBlockParagraph", z45.object({
645
683
  ref: BlockParagraphRefSchema,
646
- content: z43.string()
684
+ content: z45.string()
647
685
  }), (txn) => {
648
686
  const { ref, content } = txn.payload;
649
- return Query29(() => txn.patchEntity(ref, {
687
+ return Query31(() => txn.patchEntity(ref, {
650
688
  data: { content }
651
689
  }));
652
690
  }, { outputSchema: BlockParagraphSchema });
653
691
 
692
+ // src/operations/updateBlockParagraphMentions.ts
693
+ import {
694
+ Query as Query32,
695
+ QueryChain as QueryChain14,
696
+ writeOperation as writeOperation22
697
+ } from "roc-db";
698
+ import { z as z46 } from "zod";
699
+ var PayloadSchema5 = z46.object({
700
+ ref: BlockParagraphRefSchema,
701
+ mentions: z46.array(BlockParagraphRefSchema)
702
+ }).strict();
703
+ var setMentions = (txn) => {
704
+ const { ref, mentions } = txn.payload;
705
+ return QueryChain14(...mentions.map((mention) => Query32(() => txn.readEntity(mention))), Query32(() => txn.patchEntity(ref, { data: { mentions } })));
706
+ };
707
+ var updateBlockParagraphMentions = writeOperation22("updateBlockParagraphMentions", PayloadSchema5, setMentions, { debounce: 10, changeSetOnly: true, outputSchema: BlockParagraphSchema });
708
+ var setBlockParagraphMentions = writeOperation22("setBlockParagraphMentions", PayloadSchema5, setMentions, { changeSetOnly: true, outputSchema: BlockParagraphSchema });
709
+
654
710
  // src/operations/updateOrgSettingsName.ts
655
- import { Query as Query30, writeOperation as writeOperation20 } from "roc-db";
656
- import { z as z44 } from "zod";
657
- var updateOrgSettingsName = writeOperation20("updateOrgSettingsName", z44.object({ name: z44.string() }), (txn) => {
711
+ import { Query as Query33, writeOperation as writeOperation23 } from "roc-db";
712
+ import { z as z47 } from "zod";
713
+ var updateOrgSettingsName = writeOperation23("updateOrgSettingsName", z47.object({ name: z47.string() }), (txn) => {
658
714
  const { name } = txn.payload;
659
- return Query30(() => txn.patchEntity("OrgSettings", { data: { name } }));
715
+ return Query33(() => txn.patchEntity("OrgSettings", { data: { name } }));
660
716
  }, { debounce: 10 });
661
717
 
662
718
  // src/operations/updatePost.ts
663
- import { Query as Query31, writeOperation as writeOperation21 } from "roc-db";
664
- import { z as z45 } from "zod";
665
- var PayloadSchema5 = z45.object({
719
+ import { Query as Query34, writeOperation as writeOperation24 } from "roc-db";
720
+ import { z as z48 } from "zod";
721
+ var PayloadSchema6 = z48.object({
666
722
  ref: PostRefSchema,
667
- title: z45.string().optional(),
668
- tags: z45.array(z45.string()).optional().default([]),
723
+ title: z48.string().optional(),
724
+ tags: z48.array(z48.string()).optional().default([]),
669
725
  authorRef: UserRefSchema.optional()
670
726
  });
671
- var updatePost = writeOperation21("updatePost", PayloadSchema5, (txn) => {
727
+ var updatePost = writeOperation24("updatePost", PayloadSchema6, (txn) => {
672
728
  const { ref, authorRef, ...data } = txn.payload;
673
- return Query31(() => txn.updateEntity(ref, {
729
+ return Query34(() => txn.updateEntity(ref, {
674
730
  data,
675
731
  parents: { author: authorRef },
676
732
  children: { blocks: [] }
@@ -678,43 +734,43 @@ var updatePost = writeOperation21("updatePost", PayloadSchema5, (txn) => {
678
734
  }, { outputSchema: PostSchema });
679
735
 
680
736
  // src/operations/updatePostDescription.ts
681
- import { Query as Query32, writeOperation as writeOperation22 } from "roc-db";
682
- import { z as z46 } from "zod";
683
- var updatePostDescription = writeOperation22("updatePostDescription", z46.object({ ref: PostRefSchema, description: z46.string() }), (txn) => {
737
+ import { Query as Query35, writeOperation as writeOperation25 } from "roc-db";
738
+ import { z as z49 } from "zod";
739
+ var updatePostDescription = writeOperation25("updatePostDescription", z49.object({ ref: PostRefSchema, description: z49.string() }), (txn) => {
684
740
  const { ref, description } = txn.payload;
685
- return Query32(() => txn.patchEntity(ref, { data: { description } }));
741
+ return Query35(() => txn.patchEntity(ref, { data: { description } }));
686
742
  }, { debounce: 10, changeSetOnly: true, outputSchema: PostSchema });
687
743
 
688
744
  // src/operations/updatePostSlug.ts
689
- import { Query as Query33, writeOperation as writeOperation23 } from "roc-db";
690
- import { z as z47 } from "zod";
691
- var updatePostSlug = writeOperation23("updatePostSlug", z47.object({ ref: PostRefSchema, slug: z47.string() }), (txn) => {
745
+ import { Query as Query36, writeOperation as writeOperation26 } from "roc-db";
746
+ import { z as z50 } from "zod";
747
+ var updatePostSlug = writeOperation26("updatePostSlug", z50.object({ ref: PostRefSchema, slug: z50.string() }), (txn) => {
692
748
  const { ref, slug } = txn.payload;
693
- return Query33(() => txn.patchEntity(ref, { data: { slug } }));
749
+ return Query36(() => txn.patchEntity(ref, { data: { slug } }));
694
750
  }, { debounce: 10, outputSchema: PostSchema });
695
751
 
696
752
  // src/operations/updatePostTags.ts
697
- import { Query as Query34, writeOperation as writeOperation24 } from "roc-db";
698
- import { z as z48 } from "zod";
699
- var updatePostTags = writeOperation24("updatePostTags", z48.object({ ref: PostRefSchema, tags: z48.array(z48.string()) }), (txn) => {
753
+ import { Query as Query37, writeOperation as writeOperation27 } from "roc-db";
754
+ import { z as z51 } from "zod";
755
+ var updatePostTags = writeOperation27("updatePostTags", z51.object({ ref: PostRefSchema, tags: z51.array(z51.string()) }), (txn) => {
700
756
  const { ref, tags } = txn.payload;
701
- return Query34(() => txn.patchEntity(ref, { data: { tags } }));
757
+ return Query37(() => txn.patchEntity(ref, { data: { tags } }));
702
758
  }, { debounce: 10, outputSchema: PostSchema });
703
759
 
704
760
  // src/operations/updatePostTitle.ts
705
- import { Query as Query35, writeOperation as writeOperation25 } from "roc-db";
706
- import { z as z49 } from "zod";
707
- var updatePostTitle = writeOperation25("updatePostTitle", z49.object({ ref: PostRefSchema, title: z49.string() }), (txn) => {
761
+ import { Query as Query38, writeOperation as writeOperation28 } from "roc-db";
762
+ import { z as z52 } from "zod";
763
+ var updatePostTitle = writeOperation28("updatePostTitle", z52.object({ ref: PostRefSchema, title: z52.string() }), (txn) => {
708
764
  const { ref, title } = txn.payload;
709
- return Query35(() => txn.patchEntity(ref, { data: { title } }));
765
+ return Query38(() => txn.patchEntity(ref, { data: { title } }));
710
766
  }, { debounce: 10, outputSchema: PostSchema });
711
767
 
712
768
  // src/operations/crudBySlug.ts
713
- import { Query as Query36, QueryChain as QueryChain12, writeOperation as writeOperation26 } from "roc-db";
714
- import { z as z50 } from "zod";
715
- var crudBySlug = writeOperation26("crudBySlug", z50.object({ slug: z50.string(), newSlug: z50.string() }), (txn) => {
769
+ import { Query as Query39, QueryChain as QueryChain15, writeOperation as writeOperation29 } from "roc-db";
770
+ import { z as z53 } from "zod";
771
+ var crudBySlug = writeOperation29("crudBySlug", z53.object({ slug: z53.string(), newSlug: z53.string() }), (txn) => {
716
772
  const { slug, newSlug } = txn.payload;
717
- return QueryChain12(Query36(() => txn.readEntityByUniqueField("Post", "slug", slug)), Query36((post) => txn.patchEntity(post.ref, { data: { slug: newSlug } })), Query36(() => txn.readEntityByUniqueField("Post", "slug", newSlug)), Query36((post) => txn.deleteEntity(post.ref)), Query36(() => {
773
+ return QueryChain15(Query39(() => txn.readEntityByUniqueField("Post", "slug", slug)), Query39((post) => txn.patchEntity(post.ref, { data: { slug: newSlug } })), Query39(() => txn.readEntityByUniqueField("Post", "slug", newSlug)), Query39((post) => txn.deleteEntity(post.ref)), Query39(() => {
718
774
  return [
719
775
  txn.readEntityByUniqueField("Post", "slug", slug, false),
720
776
  txn.readEntityByUniqueField("Post", "slug", newSlug, false)
@@ -724,6 +780,10 @@ var crudBySlug = writeOperation26("crudBySlug", z50.object({ slug: z50.string(),
724
780
 
725
781
  // src/operations/index.ts
726
782
  var operations = [
783
+ pageMutations,
784
+ pageEntities,
785
+ undo,
786
+ redo,
727
787
  applyDraft,
728
788
  createBlockImage,
729
789
  createBlockTitle,
@@ -738,6 +798,8 @@ var operations = [
738
798
  crudBySlug,
739
799
  deleteBlocks,
740
800
  deleteDraft,
801
+ deleteUnmentionedBlockParagraph,
802
+ duplicateBlockParagraph,
741
803
  deleteOrgSettings,
742
804
  deletePost,
743
805
  duplicateDraft,
@@ -754,6 +816,8 @@ var operations = [
754
816
  pageSplat,
755
817
  testTransactionalEdits,
756
818
  updateBlockParagraph,
819
+ updateBlockParagraphMentions,
820
+ setBlockParagraphMentions,
757
821
  updateOrgSettingsName,
758
822
  updatePost,
759
823
  updatePostDescription,
@@ -764,13 +828,13 @@ var operations = [
764
828
  // src/testAdapterImplementation.ts
765
829
  import { beforeAll, describe, expect as expect2, test } from "bun:test";
766
830
  import {
767
- BadRequestError,
831
+ BadRequestError as BadRequestError2,
768
832
  ConflictError,
769
833
  Entity as Entity9,
770
834
  NotFoundError as NotFoundError3,
771
835
  Snowflake
772
836
  } from "roc-db";
773
- import { z as z51 } from "zod";
837
+ import { z as z54 } from "zod";
774
838
  import { faker } from "@faker-js/faker";
775
839
  var snowflake = new Snowflake(10, 10);
776
840
  var prepareChangeSetTest = async (adapter, adapter2) => {
@@ -961,7 +1025,7 @@ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
961
1025
  expect2(() => adapter1.updatePostDescription({
962
1026
  ref: postRef,
963
1027
  description: "Description 1"
964
- })).toThrow(BadRequestError);
1028
+ })).toThrow(BadRequestError2);
965
1029
  });
966
1030
  test("delete (deleteEntity function)", async () => {
967
1031
  const currentPost = await adapter1.readPost(postRef);
@@ -1018,7 +1082,7 @@ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
1018
1082
  expect2(mutation2.log[0][1]).toBe("delete");
1019
1083
  expect2(() => adapter1.testTransactionalEdits({
1020
1084
  post2ref: post2.ref
1021
- })).toThrow(BadRequestError);
1085
+ })).toThrow(BadRequestError2);
1022
1086
  });
1023
1087
  });
1024
1088
  describe("OrgSettings singleton", () => {
@@ -1094,12 +1158,12 @@ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
1094
1158
  test("constructor rejects singleton + uniqueDataKeys", () => {
1095
1159
  expect2(() => new Entity9("Bad", {
1096
1160
  singleton: true,
1097
- data: z51.object({ name: z51.string() }),
1161
+ data: z54.object({ name: z54.string() }),
1098
1162
  uniqueDataKeys: ["name"]
1099
1163
  })).toThrow(/singleton/);
1100
1164
  });
1101
1165
  test("createRef throws on unregistered entity", async () => {
1102
- expect2(() => adapter.createUnknownRef()).toThrow(BadRequestError);
1166
+ expect2(() => adapter.createUnknownRef()).toThrow(BadRequestError2);
1103
1167
  });
1104
1168
  });
1105
1169
  describe("paging", () => {
@@ -1232,7 +1296,7 @@ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
1232
1296
  });
1233
1297
  test("invalid changeSetRef throws error", async () => {
1234
1298
  const changeSetAdapter2 = adapter1.changeSet("Draft/123");
1235
- expect2(() => changeSetAdapter2.createPost({ title: "Title 1" })).toThrow(BadRequestError);
1299
+ expect2(() => changeSetAdapter2.createPost({ title: "Title 1" })).toThrow(BadRequestError2);
1236
1300
  });
1237
1301
  test("duplicateDraft (txn.duplicateChangeSetMutations) produces an independent copy with remapped refs", async () => {
1238
1302
  const [post2] = await adapter1.createPost({
@@ -1424,6 +1488,329 @@ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
1424
1488
  });
1425
1489
  });
1426
1490
  });
1491
+ describe("debounce ordering", () => {
1492
+ const tick = () => Bun.sleep(2);
1493
+ const createSyncQueue = (server) => {
1494
+ const queue = [];
1495
+ return {
1496
+ add: ([result, mutation]) => {
1497
+ const index = queue.findIndex((m) => m.ref === mutation.ref);
1498
+ if (index === -1)
1499
+ queue.push(mutation);
1500
+ else
1501
+ queue[index] = mutation;
1502
+ return result;
1503
+ },
1504
+ flush: async () => {
1505
+ while (queue.length) {
1506
+ await tick();
1507
+ await server.persistOptimisticMutations([queue[0]]);
1508
+ queue.shift();
1509
+ }
1510
+ }
1511
+ };
1512
+ };
1513
+ const replay = async (source) => {
1514
+ const mutations = await source.pageMutations({ size: 1000 });
1515
+ const replayed = await createAdapter({ optimistic: true });
1516
+ await replayed.loadMutations(mutations);
1517
+ return replayed;
1518
+ };
1519
+ const setupClient = async () => {
1520
+ const server = await createAdapter();
1521
+ const client = await createAdapter({ optimistic: true });
1522
+ const queue = createSyncQueue(server);
1523
+ const post = queue.add(await client.createPost({ title: "Post", tags: [] }));
1524
+ const draft = queue.add(await client.createDraft({ postRef: post.ref }));
1525
+ const changeSet = client.changeSet(draft.ref);
1526
+ const createParagraph = async () => queue.add(await changeSet.createBlockParagraph({
1527
+ parentRef: post.ref
1528
+ })).block;
1529
+ const holder = await createParagraph();
1530
+ await queue.flush();
1531
+ return {
1532
+ server,
1533
+ queue,
1534
+ post,
1535
+ draft,
1536
+ changeSet,
1537
+ createParagraph,
1538
+ holder
1539
+ };
1540
+ };
1541
+ test("forward: a version that reads an entity created after the previous version syncs", async () => {
1542
+ const { server, queue, draft, changeSet, createParagraph, holder } = await setupClient();
1543
+ queue.add(await changeSet.updateBlockParagraphMentions({
1544
+ ref: holder.ref,
1545
+ mentions: []
1546
+ }));
1547
+ const mentioned = await createParagraph();
1548
+ queue.add(await changeSet.updateBlockParagraphMentions({
1549
+ ref: holder.ref,
1550
+ mentions: [mentioned.ref]
1551
+ }));
1552
+ await queue.flush();
1553
+ const replayed = (await replay(server)).changeSet(draft.ref);
1554
+ const replayedHolder = await replayed.readEntity(holder.ref);
1555
+ expect2(replayedHolder.data.mentions).toEqual([mentioned.ref]);
1556
+ });
1557
+ test("reverse: a version that frees an entity before it is deleted replays", async () => {
1558
+ const {
1559
+ server,
1560
+ queue,
1561
+ post,
1562
+ draft,
1563
+ changeSet,
1564
+ createParagraph,
1565
+ holder
1566
+ } = await setupClient();
1567
+ const first = await createParagraph();
1568
+ const second = await createParagraph();
1569
+ const third = await createParagraph();
1570
+ queue.add(await changeSet.setBlockParagraphMentions({
1571
+ ref: holder.ref,
1572
+ mentions: [first.ref]
1573
+ }));
1574
+ await queue.flush();
1575
+ queue.add(await changeSet.updateBlockParagraphMentions({
1576
+ ref: holder.ref,
1577
+ mentions: [second.ref]
1578
+ }));
1579
+ await queue.flush();
1580
+ queue.add(await changeSet.deleteUnmentionedBlockParagraph({
1581
+ ref: first.ref,
1582
+ mentionedByRef: holder.ref
1583
+ }));
1584
+ await queue.flush();
1585
+ queue.add(await changeSet.updateBlockParagraphMentions({
1586
+ ref: holder.ref,
1587
+ mentions: [third.ref]
1588
+ }));
1589
+ await queue.flush();
1590
+ const replayed = (await replay(server)).changeSet(draft.ref);
1591
+ const replayedHolder = await replayed.readEntity(holder.ref);
1592
+ expect2(replayedHolder.data.mentions).toEqual([third.ref]);
1593
+ const replayedPost = await replayed.readEntity(post.ref);
1594
+ expect2(replayedPost.children.blocks).not.toContain(first.ref);
1595
+ });
1596
+ test("copy: an entity copied between two versions keeps the version it copied", async () => {
1597
+ const { server, queue, draft, changeSet, createParagraph, holder } = await setupClient();
1598
+ const first = await createParagraph();
1599
+ const second = await createParagraph();
1600
+ queue.add(await changeSet.updateBlockParagraphMentions({
1601
+ ref: holder.ref,
1602
+ mentions: [first.ref]
1603
+ }));
1604
+ await queue.flush();
1605
+ const copy = queue.add(await changeSet.duplicateBlockParagraph({ ref: holder.ref }));
1606
+ await queue.flush();
1607
+ queue.add(await changeSet.updateBlockParagraphMentions({
1608
+ ref: holder.ref,
1609
+ mentions: [second.ref]
1610
+ }));
1611
+ await queue.flush();
1612
+ expect2(copy.data.mentions).toEqual([first.ref]);
1613
+ const replayed = (await replay(server)).changeSet(draft.ref);
1614
+ const replayedCopy = await replayed.readEntity(copy.ref);
1615
+ expect2(replayedCopy.data.mentions).toEqual([first.ref]);
1616
+ const replayedHolder = await replayed.readEntity(holder.ref);
1617
+ expect2(replayedHolder.data.mentions).toEqual([second.ref]);
1618
+ });
1619
+ test("server-side: non-optimistic versions around another write replay", async () => {
1620
+ const server = await createAdapter();
1621
+ const [post] = await server.createPost({ title: "Post", tags: [] });
1622
+ const [draft] = await server.createDraft({ postRef: post.ref });
1623
+ const changeSet = server.changeSet(draft.ref);
1624
+ const [{ block: holder }] = await changeSet.createBlockParagraph({
1625
+ parentRef: post.ref
1626
+ });
1627
+ await changeSet.updateBlockParagraphMentions({
1628
+ ref: holder.ref,
1629
+ mentions: []
1630
+ });
1631
+ await tick();
1632
+ const [{ block: mentioned }] = await changeSet.createBlockParagraph({ parentRef: post.ref });
1633
+ await tick();
1634
+ await changeSet.updateBlockParagraphMentions({
1635
+ ref: holder.ref,
1636
+ mentions: [mentioned.ref]
1637
+ });
1638
+ await changeSet.createBlockParagraph({ parentRef: post.ref });
1639
+ const replayed = (await replay(server)).changeSet(draft.ref);
1640
+ const replayedHolder = await replayed.readEntity(holder.ref);
1641
+ expect2(replayedHolder.data.mentions).toEqual([mentioned.ref]);
1642
+ });
1643
+ test("old client: merged versions whose row is no longer last persist once and replay", async () => {
1644
+ const {
1645
+ server,
1646
+ queue,
1647
+ post,
1648
+ draft,
1649
+ changeSet,
1650
+ createParagraph,
1651
+ holder
1652
+ } = await setupClient();
1653
+ const first = await createParagraph();
1654
+ const second = await createParagraph();
1655
+ const third = await createParagraph();
1656
+ queue.add(await changeSet.setBlockParagraphMentions({
1657
+ ref: holder.ref,
1658
+ mentions: [first.ref]
1659
+ }));
1660
+ const [, versionMutation] = await changeSet.updateBlockParagraphMentions({
1661
+ ref: holder.ref,
1662
+ mentions: [second.ref]
1663
+ });
1664
+ queue.add([undefined, versionMutation]);
1665
+ queue.add(await changeSet.deleteUnmentionedBlockParagraph({
1666
+ ref: first.ref,
1667
+ mentionedByRef: holder.ref
1668
+ }));
1669
+ await queue.flush();
1670
+ const mergedPayload = { ref: holder.ref, mentions: [third.ref] };
1671
+ await tick();
1672
+ const resentTimestamp = new Date().toISOString();
1673
+ await server.persistOptimisticMutations([
1674
+ {
1675
+ ...versionMutation,
1676
+ payload: mergedPayload,
1677
+ debounceCount: versionMutation.debounceCount + 1,
1678
+ timestamp: resentTimestamp
1679
+ }
1680
+ ]);
1681
+ await expect2((async () => server.persistOptimisticMutations([
1682
+ {
1683
+ ...versionMutation,
1684
+ payload: mergedPayload,
1685
+ debounceCount: versionMutation.debounceCount + 1,
1686
+ timestamp: resentTimestamp
1687
+ }
1688
+ ]))()).rejects.toThrow("Mutation already synced");
1689
+ await tick();
1690
+ const finalPayload = { ref: holder.ref, mentions: [] };
1691
+ await server.persistOptimisticMutations([
1692
+ {
1693
+ ...versionMutation,
1694
+ payload: finalPayload,
1695
+ debounceCount: versionMutation.debounceCount + 2,
1696
+ timestamp: new Date().toISOString()
1697
+ }
1698
+ ]);
1699
+ const stored = await server.pageMutations({ size: 1000 });
1700
+ const versions = stored.filter((m) => m.operation.name === "updateBlockParagraphMentions");
1701
+ expect2(versions).toHaveLength(2);
1702
+ expect2(versions.map((m) => m.payload)).toContainEqual({
1703
+ ref: holder.ref,
1704
+ mentions: [second.ref]
1705
+ });
1706
+ expect2(versions.map((m) => m.payload)).toContainEqual(finalPayload);
1707
+ const replayed = (await replay(server)).changeSet(draft.ref);
1708
+ const replayedHolder = await replayed.readEntity(holder.ref);
1709
+ expect2(replayedHolder.data.mentions).toEqual([]);
1710
+ const replayedPost = await replayed.readEntity(post.ref);
1711
+ expect2(replayedPost.children.blocks).not.toContain(first.ref);
1712
+ });
1713
+ test("old client: a merged version and a write depending on it in one batch replay in order", async () => {
1714
+ const { server, queue, draft, changeSet, createParagraph, holder } = await setupClient();
1715
+ const first = await createParagraph();
1716
+ const second = await createParagraph();
1717
+ const [, versionMutation] = await changeSet.updateBlockParagraphMentions({
1718
+ ref: holder.ref,
1719
+ mentions: [first.ref]
1720
+ });
1721
+ queue.add([undefined, versionMutation]);
1722
+ await queue.flush();
1723
+ await createParagraph();
1724
+ await queue.flush();
1725
+ await tick();
1726
+ const [, version] = await changeSet.updateBlockParagraphMentions({
1727
+ ref: holder.ref,
1728
+ mentions: [second.ref]
1729
+ });
1730
+ const mergedVersion = {
1731
+ ...versionMutation,
1732
+ payload: version.payload,
1733
+ debounceCount: versionMutation.debounceCount + 1,
1734
+ timestamp: version.timestamp
1735
+ };
1736
+ await tick();
1737
+ const [, deleteMutation] = await changeSet.deleteUnmentionedBlockParagraph({
1738
+ ref: first.ref,
1739
+ mentionedByRef: holder.ref
1740
+ });
1741
+ await tick();
1742
+ await server.persistOptimisticMutations([
1743
+ mergedVersion,
1744
+ deleteMutation
1745
+ ]);
1746
+ const replayed = (await replay(server)).changeSet(draft.ref);
1747
+ const replayedHolder = await replayed.readEntity(holder.ref);
1748
+ expect2(replayedHolder.data.mentions).toEqual([second.ref]);
1749
+ });
1750
+ test("consecutive versions coalesce into the row after an intervening write", async () => {
1751
+ const { changeSet, createParagraph, holder } = await setupClient();
1752
+ const [, version1] = await changeSet.updateBlockParagraphMentions({
1753
+ ref: holder.ref,
1754
+ mentions: []
1755
+ });
1756
+ await tick();
1757
+ const mentioned = await createParagraph();
1758
+ await tick();
1759
+ const [, version2] = await changeSet.updateBlockParagraphMentions({
1760
+ ref: holder.ref,
1761
+ mentions: [mentioned.ref]
1762
+ });
1763
+ const [, version3] = await changeSet.updateBlockParagraphMentions({
1764
+ ref: holder.ref,
1765
+ mentions: []
1766
+ });
1767
+ expect2(version2.ref).not.toBe(version1.ref);
1768
+ expect2(version3.ref).toBe(version2.ref);
1769
+ expect2(version3.debounceCount).toBe(version2.debounceCount + 1);
1770
+ });
1771
+ test("another identity's write in the changeSet, or the identity's own write elsewhere, ends coalescing", async () => {
1772
+ const engineArgs = await generateArgs();
1773
+ const adapterA = await createAdapter({
1774
+ session: { identityRef: "User/A" },
1775
+ engineArgs
1776
+ });
1777
+ const adapterB = await createAdapter({
1778
+ session: { identityRef: "User/B" },
1779
+ engineArgs
1780
+ });
1781
+ const [post] = await adapterA.createPost({
1782
+ title: "Post",
1783
+ tags: []
1784
+ });
1785
+ const [draft] = await adapterA.createDraft({ postRef: post.ref });
1786
+ const changeSetA = adapterA.changeSet(draft.ref);
1787
+ const changeSetB = adapterB.changeSet(draft.ref);
1788
+ const [{ block: holder }] = await changeSetA.createBlockParagraph({
1789
+ parentRef: post.ref
1790
+ });
1791
+ const update = async () => {
1792
+ await tick();
1793
+ const [, mutation] = await changeSetA.updateBlockParagraphMentions({
1794
+ ref: holder.ref,
1795
+ mentions: []
1796
+ });
1797
+ return mutation;
1798
+ };
1799
+ const version1 = await update();
1800
+ await tick();
1801
+ await changeSetB.createBlockParagraph({ parentRef: post.ref });
1802
+ const version2 = await update();
1803
+ await tick();
1804
+ await adapterA.createPost({ title: "Elsewhere", tags: [] });
1805
+ const version3 = await update();
1806
+ await tick();
1807
+ await adapterB.createPost({ title: "Not A", tags: [] });
1808
+ const version4 = await update();
1809
+ expect2(version2.ref).not.toBe(version1.ref);
1810
+ expect2(version3.ref).not.toBe(version2.ref);
1811
+ expect2(version4.ref).toBe(version3.ref);
1812
+ });
1813
+ });
1427
1814
  };
1428
1815
  // src/inMemoryAdapter.ts
1429
1816
  import { createInMemoryAdapter } from "@roc-db/in-memory";
@@ -2,6 +2,7 @@ import { Entity } from "roc-db";
2
2
  import { z } from "zod";
3
3
  export declare const BlockParagraph: Entity<"BlockParagraph", z.ZodObject<{
4
4
  content: z.ZodOptional<z.ZodString>;
5
+ mentions: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
6
  }, z.core.$strip>, z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
6
7
  parent: z.ZodUnion<readonly [z.ZodType<`Post/${number}`, `Post/${number}`, z.core.$ZodTypeInternals<`Post/${number}`, `Post/${number}`>>, z.ZodUnion<readonly [z.ZodTemplateLiteral<`BlockParagraph/${number}`>, z.ZodTemplateLiteral<`BlockRow/${number}`>]>]>;
7
8
  }, z.core.$strip>, z.ZodObject<{}, z.core.$strip>, false>;
@@ -18,6 +18,7 @@ export declare const entities: (import("roc-db").Entity<"Draft", import("zod").Z
18
18
  author: import("zod").ZodOptional<import("zod").ZodTemplateLiteral<`User/${number}`>>;
19
19
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{}, import("zod/v4/core").$strip>, false> | import("roc-db").Entity<"BlockParagraph", import("zod").ZodObject<{
20
20
  content: import("zod").ZodOptional<import("zod").ZodString>;
21
+ mentions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
21
22
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
22
23
  parent: import("zod").ZodUnion<readonly [import("zod").ZodType<`Post/${number}`, `Post/${number}`, import("zod/v4/core").$ZodTypeInternals<`Post/${number}`, `Post/${number}`>>, import("zod").ZodUnion<readonly [import("zod").ZodTemplateLiteral<`BlockParagraph/${number}`>, import("zod").ZodTemplateLiteral<`BlockRow/${number}`>]>]>;
23
24
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{}, import("zod/v4/core").$strip>, false> | import("roc-db").Entity<"BlockRow", import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ export declare const deleteUnmentionedBlockParagraph: import("roc-db").WriteOperation<"deleteUnmentionedBlockParagraph", z.ZodObject<{
3
+ ref: z.ZodTemplateLiteral<`BlockParagraph/${number}`>;
4
+ mentionedByRef: z.ZodTemplateLiteral<`BlockParagraph/${number}`>;
5
+ }, z.core.$strict>>;
@@ -0,0 +1,4 @@
1
+ import { z } from "zod";
2
+ export declare const duplicateBlockParagraph: import("roc-db").WriteOperation<"duplicateBlockParagraph", z.ZodObject<{
3
+ ref: z.ZodTemplateLiteral<`BlockParagraph/${number}`>;
4
+ }, z.core.$strict>>;
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export declare const updateBlockParagraphMentions: import("roc-db").WriteOperation<"updateBlockParagraphMentions", z.ZodObject<{
3
+ ref: z.ZodTemplateLiteral<`BlockParagraph/${number}`>;
4
+ mentions: z.ZodArray<z.ZodTemplateLiteral<`BlockParagraph/${number}`>>;
5
+ }, z.core.$strict>>;
6
+ export declare const setBlockParagraphMentions: import("roc-db").WriteOperation<"setBlockParagraphMentions", z.ZodObject<{
7
+ ref: z.ZodTemplateLiteral<`BlockParagraph/${number}`>;
8
+ mentions: z.ZodArray<z.ZodTemplateLiteral<`BlockParagraph/${number}`>>;
9
+ }, z.core.$strict>>;
@@ -12,6 +12,7 @@ export declare const BlockParagraphSchema: z.ZodObject<{
12
12
  }, z.core.$strict>>;
13
13
  data: z.ZodNonOptional<z.ZodObject<{
14
14
  content: z.ZodOptional<z.ZodString>;
15
+ mentions: z.ZodOptional<z.ZodArray<z.ZodString>>;
15
16
  }, z.core.$strip>>;
16
17
  children: z.ZodNonOptional<z.ZodObject<{}, z.core.$strip>>;
17
18
  parents: z.ZodNonOptional<z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roc-db/test-utils",
3
- "version": "0.2.0-pre.101",
3
+ "version": "0.2.0-pre.103",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {