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

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.
Files changed (78) hide show
  1. package/dist/index.js +1233 -303
  2. package/dist/types/entities/BlockImageEntity.d.ts +7 -0
  3. package/dist/types/entities/BlockParagraph.d.ts +7 -0
  4. package/dist/types/entities/BlockRow.d.ts +7 -0
  5. package/dist/types/entities/Draft.d.ts +8 -0
  6. package/dist/types/entities/OrgSettingsEntity.d.ts +10 -0
  7. package/dist/types/entities/PostEntity.d.ts +12 -0
  8. package/dist/types/entities/PostVersion.d.ts +8 -0
  9. package/dist/types/entities/UserEntity.d.ts +5 -0
  10. package/dist/types/entities/index.d.ts +41 -0
  11. package/dist/types/index.d.ts +2 -1
  12. package/dist/types/operations/applyDraft.d.ts +1 -0
  13. package/dist/types/operations/createBlockImage.d.ts +5 -15
  14. package/dist/types/operations/createBlockParagraph.d.ts +5 -15
  15. package/dist/types/operations/createBlockRow.d.ts +4 -15
  16. package/dist/types/operations/createBlockRowReadingRoot.d.ts +13 -0
  17. package/dist/types/operations/createBlockTitle.d.ts +4 -15
  18. package/dist/types/operations/createDraft.d.ts +4 -15
  19. package/dist/types/operations/createOrgSettings.d.ts +6 -0
  20. package/dist/types/operations/createPost.d.ts +6 -19
  21. package/dist/types/operations/createUnknownRef.d.ts +2 -0
  22. package/dist/types/operations/createUser.d.ts +4 -0
  23. package/dist/types/operations/crudBySlug.d.ts +5 -0
  24. package/dist/types/operations/deleteBlocks.d.ts +2 -0
  25. package/dist/types/operations/deleteDraft.d.ts +1 -0
  26. package/dist/types/operations/deleteOrgSettings.d.ts +2 -0
  27. package/dist/types/operations/deletePost.d.ts +1 -9
  28. package/dist/types/operations/duplicateDraft.d.ts +10 -0
  29. package/dist/types/operations/index.d.ts +1 -157
  30. package/dist/types/operations/moveBlocks.d.ts +5 -0
  31. package/dist/types/operations/pageBlocks.d.ts +1 -0
  32. package/dist/types/operations/pageEmptyEntitiesArray.d.ts +1 -0
  33. package/dist/types/operations/pagePosts.d.ts +1 -0
  34. package/dist/types/operations/pagePostsByTag.d.ts +1 -0
  35. package/dist/types/operations/pageSplat.d.ts +1 -0
  36. package/dist/types/operations/readMutation.d.ts +1 -0
  37. package/dist/types/operations/readOrgSettings.d.ts +2 -0
  38. package/dist/types/operations/readPostBySlug.d.ts +1 -0
  39. package/dist/types/operations/testTransactionalEdits.d.ts +6 -0
  40. package/dist/types/operations/updateBlockParagraph.d.ts +5 -15
  41. package/dist/types/operations/updateOrgSettingsName.d.ts +4 -0
  42. package/dist/types/operations/updatePost.d.ts +7 -21
  43. package/dist/types/operations/updatePostDescription.d.ts +5 -0
  44. package/dist/types/operations/updatePostSlug.d.ts +5 -0
  45. package/dist/types/operations/updatePostTags.d.ts +5 -0
  46. package/dist/types/operations/updatePostTitle.d.ts +5 -17
  47. package/dist/types/schemas/BlockImageRefSchema.d.ts +1 -1
  48. package/dist/types/schemas/BlockImageSchema.d.ts +20 -31
  49. package/dist/types/schemas/BlockParagraphRefSchema.d.ts +1 -1
  50. package/dist/types/schemas/BlockParagraphSchema.d.ts +20 -31
  51. package/dist/types/schemas/BlockRefSchema.d.ts +1 -1
  52. package/dist/types/schemas/BlockRowRefSchema.d.ts +1 -1
  53. package/dist/types/schemas/BlockRowSchema.d.ts +21 -31
  54. package/dist/types/schemas/BlockTitleSchema.d.ts +20 -31
  55. package/dist/types/schemas/CreatePostMutationSchema.d.ts +14 -44
  56. package/dist/types/schemas/CreateUserMutationSchema.d.ts +13 -35
  57. package/dist/types/schemas/DraftRefSchema.d.ts +1 -1
  58. package/dist/types/schemas/DraftSchema.d.ts +18 -31
  59. package/dist/types/schemas/PostRefSchema.d.ts +1 -1
  60. package/dist/types/schemas/PostSchema.d.ts +25 -31
  61. package/dist/types/schemas/PostVersionRefSchema.d.ts +1 -0
  62. package/dist/types/schemas/UpdatePostMutationSchema.d.ts +16 -50
  63. package/dist/types/schemas/UpdatePostTitleMutationSchema.d.ts +14 -40
  64. package/dist/types/schemas/UserRefSchema.d.ts +1 -1
  65. package/dist/types/schemas/index.d.ts +0 -31
  66. package/dist/types/setup/index.d.ts +11 -0
  67. package/dist/types/testAdapterImplementation.d.ts +1 -1
  68. package/package.json +8 -4
  69. package/dist/types/operations/deleteBlock.d.ts +0 -11
  70. package/dist/types/schemas/BlockTitleRefSchema.d.ts +0 -1
  71. package/dist/types/schemas/CreateBlockImageMutationSchema.d.ts +0 -40
  72. package/dist/types/schemas/CreateBlockParagraphMutationSchema.d.ts +0 -40
  73. package/dist/types/schemas/CreateBlockRowMutationSchema.d.ts +0 -40
  74. package/dist/types/schemas/CreateBlockTitleMutationSchema.d.ts +0 -40
  75. package/dist/types/schemas/CreateDraftMutationSchema.d.ts +0 -40
  76. package/dist/types/schemas/DeleteBlockMutationSchema.d.ts +0 -30
  77. package/dist/types/schemas/DeletePostMutationSchema.d.ts +0 -29
  78. package/dist/types/schemas/UpdateBlockParagraphMutationSchema.d.ts +0 -45
package/dist/index.js CHANGED
@@ -2,17 +2,12 @@
2
2
  import { entitySchemaGenerator } from "roc-db";
3
3
  import { z } from "zod";
4
4
 
5
- // src/schemas/BlockImageRefSchema.ts
6
- import { refSchemaGenerator } from "roc-db";
7
- var BlockImageRefSchema = refSchemaGenerator("BlockImage");
8
-
9
5
  // src/schemas/PostRefSchema.ts
10
- import { refSchemaGenerator as refSchemaGenerator2 } from "roc-db";
11
- var PostRefSchema = refSchemaGenerator2("Post");
6
+ import { refSchemaGenerator } from "roc-db";
7
+ var PostRefSchema = refSchemaGenerator("Post");
12
8
 
13
9
  // src/schemas/BlockImageSchema.ts
14
10
  var BlockImageSchema = entitySchemaGenerator("BlockImage", {
15
- ref: BlockImageRefSchema,
16
11
  data: z.object({
17
12
  url: z.string().url()
18
13
  }),
@@ -24,14 +19,7 @@ var BlockImageSchema = entitySchemaGenerator("BlockImage", {
24
19
  // src/schemas/BlockParagraphSchema.ts
25
20
  import { entitySchemaGenerator as entitySchemaGenerator2 } from "roc-db";
26
21
  import { z as z2 } from "zod";
27
-
28
- // src/schemas/BlockParagraphRefSchema.ts
29
- import { refSchemaGenerator as refSchemaGenerator3 } from "roc-db";
30
- var BlockParagraphRefSchema = refSchemaGenerator3("BlockParagraph");
31
-
32
- // src/schemas/BlockParagraphSchema.ts
33
22
  var BlockParagraphSchema = entitySchemaGenerator2("BlockParagraph", {
34
- ref: BlockParagraphRefSchema,
35
23
  data: z2.object({
36
24
  content: z2.string().optional()
37
25
  }),
@@ -43,14 +31,7 @@ var BlockParagraphSchema = entitySchemaGenerator2("BlockParagraph", {
43
31
  // src/schemas/BlockTitleSchema.ts
44
32
  import { entitySchemaGenerator as entitySchemaGenerator3 } from "roc-db";
45
33
  import { z as z3 } from "zod";
46
-
47
- // src/schemas/BlockTitleRefSchema.ts
48
- import { refSchemaGenerator as refSchemaGenerator4 } from "roc-db";
49
- var BlockTitleRefSchema = refSchemaGenerator4("BlockTitle");
50
-
51
- // src/schemas/BlockTitleSchema.ts
52
34
  var BlockTitleSchema = entitySchemaGenerator3("BlockTitle", {
53
- ref: BlockTitleRefSchema,
54
35
  data: z3.object({
55
36
  content: z3.string()
56
37
  }),
@@ -62,16 +43,9 @@ var BlockTitleSchema = entitySchemaGenerator3("BlockTitle", {
62
43
  // src/schemas/DraftSchema.ts
63
44
  import { entitySchemaGenerator as entitySchemaGenerator4 } from "roc-db";
64
45
  import { z as z4 } from "zod";
65
-
66
- // src/schemas/DraftRefSchema.ts
67
- import { refSchemaGenerator as refSchemaGenerator5 } from "roc-db";
68
- var DraftRefSchema = refSchemaGenerator5("Draft");
69
-
70
- // src/schemas/DraftSchema.ts
71
46
  var DraftSchema = entitySchemaGenerator4("Draft", {
72
- ref: DraftRefSchema,
73
- data: z4.object({
74
- postRef: PostRefSchema
47
+ parents: z4.object({
48
+ post: PostRefSchema
75
49
  })
76
50
  });
77
51
 
@@ -80,12 +54,11 @@ import { entitySchemaGenerator as entitySchemaGenerator5 } from "roc-db";
80
54
  import { z as z5 } from "zod";
81
55
 
82
56
  // src/schemas/UserRefSchema.ts
83
- import { refSchemaGenerator as refSchemaGenerator6 } from "roc-db";
84
- var UserRefSchema = refSchemaGenerator6("User");
57
+ import { refSchemaGenerator as refSchemaGenerator2 } from "roc-db";
58
+ var UserRefSchema = refSchemaGenerator2("User");
85
59
 
86
60
  // src/schemas/PostSchema.ts
87
61
  var PostSchema = entitySchemaGenerator5("Post", {
88
- ref: PostRefSchema,
89
62
  data: z5.object({
90
63
  title: z5.string(),
91
64
  text: z5.string().optional(),
@@ -95,414 +68,1371 @@ var PostSchema = entitySchemaGenerator5("Post", {
95
68
  parents: z5.object({ author: UserRefSchema.optional() }),
96
69
  children: z5.object({ blocks: z5.array(z5.string()) })
97
70
  });
71
+
72
+ // src/entities/Draft.ts
73
+ import { Entity } from "roc-db";
74
+ import { z as z6 } from "zod";
75
+
76
+ // src/schemas/PostVersionRefSchema.ts
77
+ import { refSchemaGenerator as refSchemaGenerator3 } from "roc-db";
78
+ var PostVersionRefSchema = refSchemaGenerator3("PostVersion");
79
+
80
+ // src/entities/Draft.ts
81
+ var Draft = new Entity("Draft", {
82
+ changeSet: true,
83
+ data: z6.object({
84
+ appliedAt: z6.string().optional()
85
+ }),
86
+ parents: z6.object({
87
+ post: PostRefSchema,
88
+ version: PostVersionRefSchema.optional()
89
+ })
90
+ });
91
+
92
+ // src/schemas/DraftRefSchema.ts
93
+ var DraftRefSchema = Draft.refSchema;
98
94
  // src/schemas/CreatePostMutationSchema.ts
99
95
  import { mutationSchemaGenerator } from "roc-db";
100
- import { z as z6 } from "zod";
101
- var CreatePostMutationSchema = mutationSchemaGenerator("createPost", z6.object({
102
- title: z6.string(),
103
- slug: z6.string().optional(),
104
- tags: z6.array(z6.string()).default([])
96
+ import { z as z7 } from "zod";
97
+ var CreatePostMutationSchema = mutationSchemaGenerator("createPost", z7.object({
98
+ title: z7.string(),
99
+ slug: z7.string().optional(),
100
+ tags: z7.array(z7.string()).default([])
105
101
  }).strict());
106
102
  // src/schemas/CreateUserMutationSchema.ts
107
103
  import { mutationSchemaGenerator as mutationSchemaGenerator2 } from "roc-db";
108
- import { z as z7 } from "zod";
109
- var CreateUserMutationSchema = mutationSchemaGenerator2("createUser", z7.object({ email: z7.string() }));
104
+ import { z as z8 } from "zod";
105
+ var CreateUserMutationSchema = mutationSchemaGenerator2("createUser", z8.object({ email: z8.string() }));
110
106
  // src/schemas/UpdatePostMutationSchema.ts
111
107
  import { mutationSchemaGenerator as mutationSchemaGenerator3 } from "roc-db";
112
- import { z as z8 } from "zod";
113
- var UpdatePostMutationSchema = mutationSchemaGenerator3("updatePost", z8.object({
108
+ import { z as z9 } from "zod";
109
+ var UpdatePostMutationSchema = mutationSchemaGenerator3("updatePost", z9.object({
114
110
  ref: PostRefSchema,
115
- title: z8.string().optional(),
116
- tags: z8.array(z8.string()).optional().default([]),
117
- authorRef: UserRefSchema.optional().optional()
111
+ title: z9.string().optional(),
112
+ tags: z9.array(z9.string()).optional().default([]),
113
+ authorRef: UserRefSchema.optional()
118
114
  }));
119
115
  // src/schemas/UpdatePostTitleMutationSchema.ts
120
116
  import { mutationSchemaGenerator as mutationSchemaGenerator4 } from "roc-db";
121
- import { z as z9 } from "zod";
122
- var UpdatePostTitleMutationSchema = mutationSchemaGenerator4("updatePostTitle", z9.object({ ref: PostRefSchema, title: z9.string() }));
123
- // src/schemas/index.ts
124
- var entities = [
125
- BlockImageSchema,
126
- BlockParagraphSchema,
127
- BlockTitleSchema,
128
- DraftSchema,
129
- PostSchema
130
- ];
131
- // src/operations/createBlockImage.ts
132
- import { Query, writeOperation } from "roc-db";
133
-
134
- // src/schemas/CreateBlockImageMutationSchema.ts
135
- import { mutationSchemaGenerator as mutationSchemaGenerator5 } from "roc-db";
136
117
  import { z as z10 } from "zod";
137
- var CreateBlockImageMutationSchema = mutationSchemaGenerator5("createBlockImage", z10.object({ postRef: PostRefSchema }).strict(), undefined, true);
118
+ var UpdatePostTitleMutationSchema = mutationSchemaGenerator4("updatePostTitle", z10.object({ ref: PostRefSchema, title: z10.string() }));
119
+ // src/entities/BlockImageEntity.ts
120
+ import { Entity as Entity2 } from "roc-db";
121
+ import { z as z11 } from "zod";
122
+ var BlockImageEntity = new Entity2("BlockImage", {
123
+ data: z11.object({
124
+ url: z11.string().url()
125
+ }),
126
+ parents: z11.object({
127
+ parent: PostRefSchema
128
+ })
129
+ });
138
130
 
139
- // src/operations/createBlockImage.ts
140
- var createBlockImage = writeOperation(CreateBlockImageMutationSchema, BlockImageSchema, (txn) => {
141
- const ref = txn.createRef("BlockImage");
142
- const { postRef } = txn.payload;
143
- return Query(() => txn.createEntity(ref, { parents: { post: postRef } }));
144
- }, { changeSetOnly: true });
131
+ // src/entities/BlockParagraph.ts
132
+ import { Entity as Entity4 } from "roc-db";
133
+ import { z as z14 } from "zod";
145
134
 
146
- // src/operations/createBlockParagraph.ts
147
- import { Query as Query2, QueryChain, writeOperation as writeOperation2 } from "roc-db";
135
+ // src/entities/PostEntity.ts
136
+ import { Entity as Entity3 } from "roc-db";
137
+ import { z as z12 } from "zod";
138
+ var PostEntity = new Entity3("Post", {
139
+ data: z12.object({
140
+ title: z12.string(),
141
+ text: z12.string().optional(),
142
+ tags: z12.array(z12.string()),
143
+ slug: z12.string().optional()
144
+ }),
145
+ parents: z12.object({ author: UserRefSchema.optional() }),
146
+ children: z12.object({ blocks: z12.array(z12.string()) }),
147
+ indexedDataKeys: ["tags", "slug"],
148
+ uniqueDataKeys: ["slug"]
149
+ });
148
150
 
149
- // src/schemas/CreateBlockParagraphMutationSchema.ts
150
- import { mutationSchemaGenerator as mutationSchemaGenerator6 } from "roc-db";
151
- import { z as z11 } from "zod";
151
+ // src/schemas/BlockRefSchema.ts
152
+ import { z as z13 } from "zod";
153
+
154
+ // src/schemas/BlockParagraphRefSchema.ts
155
+ import { refSchemaGenerator as refSchemaGenerator4 } from "roc-db";
156
+ var BlockParagraphRefSchema = refSchemaGenerator4("BlockParagraph");
152
157
 
153
158
  // src/schemas/BlockRowRefSchema.ts
154
- import { refSchemaGenerator as refSchemaGenerator7 } from "roc-db";
155
- var BlockRowRefSchema = refSchemaGenerator7("BlockRow");
159
+ import { refSchemaGenerator as refSchemaGenerator5 } from "roc-db";
160
+ var BlockRowRefSchema = refSchemaGenerator5("BlockRow");
156
161
 
157
- // src/schemas/CreateBlockParagraphMutationSchema.ts
158
- var CreateBlockParagraphMutationSchema = mutationSchemaGenerator6("createBlockParagraph", z11.object({ parentRef: z11.union([PostRefSchema, BlockRowRefSchema]) }).strict(), undefined, true);
162
+ // src/schemas/BlockRefSchema.ts
163
+ var BlockRefSchema = z13.union([
164
+ BlockParagraphRefSchema,
165
+ BlockRowRefSchema
166
+ ]);
159
167
 
160
- // src/operations/createBlockParagraph.ts
161
- var createBlockParagrah = writeOperation2(CreateBlockParagraphMutationSchema, BlockParagraphSchema, (txn) => {
162
- const ref = txn.createRef("BlockParagraph");
163
- const { parentRef } = txn.payload;
164
- return QueryChain(Query2(() => txn.readEntity(parentRef, true)), Query2((parent) => txn.patchEntity(parentRef, {
165
- children: { blocks: [...parent.children.blocks, ref] }
166
- })), Query2(() => txn.createEntity(ref, { parents: { parent: parentRef } })), Query2((block, updatedParent) => ({ block, updatedParent })));
168
+ // src/entities/BlockParagraph.ts
169
+ var BlockParagraph = new Entity4("BlockParagraph", {
170
+ data: z14.object({
171
+ content: z14.string().optional()
172
+ }),
173
+ parents: z14.object({
174
+ parent: z14.union([PostEntity.refSchema, BlockRefSchema])
175
+ })
176
+ });
177
+
178
+ // src/entities/BlockRow.ts
179
+ import { Entity as Entity5 } from "roc-db";
180
+ import { z as z15 } from "zod";
181
+ var BlockRow = new Entity5("BlockRow", {
182
+ children: z15.object({
183
+ blocks: z15.array(BlockRefSchema)
184
+ }),
185
+ parents: z15.object({
186
+ parent: z15.union([PostEntity.refSchema, BlockRefSchema])
187
+ })
188
+ });
189
+
190
+ // src/entities/OrgSettingsEntity.ts
191
+ import { Entity as Entity6 } from "roc-db";
192
+ import { z as z16 } from "zod";
193
+ var OrgSettingsEntity = new Entity6("OrgSettings", {
194
+ singleton: true,
195
+ data: z16.object({
196
+ name: z16.string(),
197
+ theme: z16.string().optional()
198
+ }),
199
+ parents: z16.object({ primaryAdmin: UserRefSchema.optional() }),
200
+ children: z16.object({ featuredPosts: z16.array(z16.string()) })
201
+ });
202
+
203
+ // src/entities/PostVersion.ts
204
+ import { Entity as Entity7 } from "roc-db";
205
+ import { z as z17 } from "zod";
206
+ var PostVersion = new Entity7("PostVersion", {
207
+ version: true,
208
+ data: z17.object({
209
+ version: z17.number(),
210
+ snapshot: z17.array(z17.any())
211
+ }),
212
+ parents: z17.object({ post: PostRefSchema }),
213
+ indexedDataKeys: ["version"],
214
+ uniqueDataKeys: ["slug"]
215
+ });
216
+
217
+ // src/entities/UserEntity.ts
218
+ import { Entity as Entity8 } from "roc-db";
219
+ import { z as z18 } from "zod";
220
+ var UserEntity = new Entity8("User", {
221
+ data: z18.object({
222
+ email: z18.string().email()
223
+ }),
224
+ uniqueDataKeys: ["email"]
225
+ });
226
+
227
+ // src/entities/index.ts
228
+ var entities = [
229
+ BlockImageEntity,
230
+ BlockParagraph,
231
+ BlockRow,
232
+ Draft,
233
+ OrgSettingsEntity,
234
+ PostEntity,
235
+ PostVersion,
236
+ UserEntity
237
+ ];
238
+ // src/operations/applyDraft.ts
239
+ import { Query, QueryChain, writeOperation } from "roc-db";
240
+ var applyDraft = writeOperation("applyDraft", DraftRefSchema, (txn) => {
241
+ const ref = txn.payload;
242
+ const versionRef = txn.createRef("PostVersion");
243
+ return QueryChain(Query(() => txn.applyChangeSet(ref)), Query(() => txn.patchEntity(ref, {
244
+ data: { appliedAt: txn.timestamp }
245
+ })), Query((draft) => txn.childRefsOf(draft.parents.post, true)), Query((childRefs, draft) => txn.batchReadEntities([draft.parents.post, ...childRefs])), Query((childEntities, _, draft) => txn.createEntity(versionRef, {
246
+ data: {
247
+ version: 1,
248
+ snapshot: childEntities
249
+ },
250
+ parents: {
251
+ post: draft.parents.post
252
+ }
253
+ })));
254
+ });
255
+
256
+ // src/operations/createBlockImage.ts
257
+ import { Query as Query2, writeOperation as writeOperation2 } from "roc-db";
258
+ import { z as z19 } from "zod";
259
+ var createBlockImage = writeOperation2("createBlockImage", z19.object({ parentRef: PostRefSchema, url: z19.string().url() }).strict(), (txn) => {
260
+ const ref = txn.createRef("BlockImage");
261
+ const { parentRef, url } = txn.payload;
262
+ return Query2(() => txn.createEntity(ref, {
263
+ data: { url },
264
+ parents: { parent: parentRef }
265
+ }));
167
266
  }, { changeSetOnly: true });
168
267
 
169
- // src/operations/createBlockRow.ts
268
+ // src/operations/createBlockParagraph.ts
170
269
  import { Query as Query3, QueryChain as QueryChain2, writeOperation as writeOperation3 } from "roc-db";
171
-
172
- // src/schemas/CreateBlockRowMutationSchema.ts
173
- import { mutationSchemaGenerator as mutationSchemaGenerator7 } from "roc-db";
174
- import { z as z12 } from "zod";
175
- var CreateBlockRowMutationSchema = mutationSchemaGenerator7("createBlockRow", z12.object({ parentRef: z12.union([PostRefSchema, BlockRowRefSchema]) }).strict(), undefined, true);
270
+ import { z as z20 } from "zod";
271
+ var createBlockParagrah = writeOperation3("createBlockParagraph", z20.object({
272
+ parentRef: z20.union([PostRefSchema, BlockRowRefSchema]),
273
+ content: z20.string().optional()
274
+ }).strict(), (txn) => {
275
+ const ref = txn.createRef("BlockParagraph");
276
+ const { parentRef, content } = txn.payload;
277
+ return QueryChain2(Query3(() => txn.readEntity(parentRef, true)), Query3((parent) => txn.patchEntity(parentRef, {
278
+ children: { blocks: [...parent.children.blocks, ref] }
279
+ })), Query3(() => txn.createEntity(ref, {
280
+ parents: { parent: parentRef },
281
+ data: { content }
282
+ })), Query3((block, updatedParent) => ({ block, updatedParent })));
283
+ }, {
284
+ changeSetOnly: true,
285
+ outputSchema: z20.object({
286
+ block: z20.any(),
287
+ updatedParent: z20.any()
288
+ })
289
+ });
176
290
 
177
291
  // src/operations/createBlockRow.ts
178
- var createBlockRow = writeOperation3(CreateBlockRowMutationSchema, BlockParagraphSchema, (txn) => {
292
+ import { Query as Query4, QueryChain as QueryChain3, writeOperation as writeOperation4 } from "roc-db";
293
+ import { z as z21 } from "zod";
294
+ var createBlockRow = writeOperation4("createBlockRow", z21.object({ parentRef: z21.union([PostRefSchema, BlockRowRefSchema]) }).strict(), (txn) => {
179
295
  const ref = txn.createRef("BlockRow");
180
296
  const { parentRef } = txn.payload;
181
- return QueryChain2(Query3(() => txn.readEntity(parentRef)), Query3((parent) => {
297
+ return QueryChain3(Query4(() => txn.readEntity(parentRef)), Query4((parent) => {
182
298
  return txn.patchEntity(parentRef, {
183
299
  children: { blocks: [...parent.children.blocks, ref] }
184
300
  });
185
- }), Query3(() => txn.createEntity(ref, {
301
+ }), Query4(() => txn.createEntity(ref, {
186
302
  children: { blocks: [] },
187
303
  parents: { parent: parentRef }
188
- })), Query3((block, updatedParent) => ({ block, updatedParent })));
189
- }, { changeSetOnly: true });
190
-
191
- // src/operations/createBlockTitle.ts
192
- import { Query as Query4, writeOperation as writeOperation4 } from "roc-db";
304
+ })), Query4((block, updatedParent) => ({ block, updatedParent })));
305
+ }, {
306
+ changeSetOnly: true,
307
+ outputSchema: z21.object({
308
+ block: z21.any(),
309
+ updatedParent: z21.any()
310
+ })
311
+ });
193
312
 
194
- // src/schemas/CreateBlockTitleMutationSchema.ts
195
- import { mutationSchemaGenerator as mutationSchemaGenerator8 } from "roc-db";
196
- import { z as z13 } from "zod";
197
- var CreateBlockTitleMutationSchema = mutationSchemaGenerator8("createBlockTitle", z13.object({ parentRef: z13.union([PostRefSchema, BlockRowRefSchema]) }).strict(), undefined, true);
313
+ // src/operations/createBlockRowReadingRoot.ts
314
+ import { Query as Query5, QueryChain as QueryChain4, writeOperation as writeOperation5 } from "roc-db";
315
+ import { z as z22 } from "zod";
316
+ var createBlockRowReadingRoot = writeOperation5("createBlockRowReadingRoot", z22.object({ parentRef: z22.union([PostRefSchema, BlockRowRefSchema]) }).strict(), (txn) => {
317
+ const ref = txn.createRef("BlockRow");
318
+ const { parentRef } = txn.payload;
319
+ return QueryChain4(Query5(() => {
320
+ if (txn.changeSetRef)
321
+ txn.readEntity(txn.changeSetRef);
322
+ }), Query5(() => txn.readEntity(parentRef)), Query5((parent) => txn.patchEntity(parentRef, {
323
+ children: { blocks: [...parent.children.blocks, ref] }
324
+ })), Query5(() => txn.createEntity(ref, {
325
+ children: { blocks: [] },
326
+ parents: { parent: parentRef }
327
+ })), Query5((block) => ({ block })));
328
+ }, {
329
+ changeSetOnly: true,
330
+ outputSchema: z22.object({ block: z22.any() })
331
+ });
198
332
 
199
333
  // src/operations/createBlockTitle.ts
200
- var createBlockTitle = writeOperation4(CreateBlockTitleMutationSchema, BlockTitleSchema, (txn) => {
334
+ import { Query as Query6, writeOperation as writeOperation6 } from "roc-db";
335
+ import { z as z23 } from "zod";
336
+ var PayloadSchema = z23.object({ parentRef: z23.union([PostRefSchema, BlockRowRefSchema]) }).strict();
337
+ var createBlockTitle = writeOperation6("createBlockTitle", PayloadSchema, (txn) => {
201
338
  const ref = txn.createRef("BlockTitle");
202
- const { postRef } = txn.payload;
203
- return Query4(() => txn.createEntity(ref, { parents: { post: postRef } }));
204
- }, { changeSetOnly: true });
205
-
206
- // src/operations/createDraft.ts
207
- import { Query as Query5, writeOperation as writeOperation5 } from "roc-db";
208
-
209
- // src/schemas/CreateDraftMutationSchema.ts
210
- import { mutationSchemaGenerator as mutationSchemaGenerator9 } from "roc-db";
211
- import { z as z14 } from "zod";
212
- var CreateDraftMutationSchema = mutationSchemaGenerator9("createDraft", z14.object({ postRef: PostRefSchema }).strict());
339
+ const { parentRef } = txn.payload;
340
+ return Query6(() => txn.createEntity(ref, { parents: { post: parentRef } }));
341
+ }, { changeSetOnly: true, outputSchema: BlockTitleSchema });
213
342
 
214
343
  // src/operations/createDraft.ts
215
- var createDraft = writeOperation5(CreateDraftMutationSchema, DraftSchema, (txn) => {
344
+ import { Query as Query7, writeOperation as writeOperation7 } from "roc-db";
345
+ import { z as z24 } from "zod";
346
+ var createDraft = writeOperation7("createDraft", z24.object({ postRef: PostRefSchema }).strict(), (txn) => {
216
347
  const ref = txn.createRef("Draft");
217
348
  const { postRef } = txn.payload;
218
- return Query5(() => txn.createEntity(ref, {
349
+ return Query7(() => txn.createEntity(ref, {
219
350
  parents: {
220
351
  post: postRef
221
352
  }
222
353
  }));
354
+ }, { outputSchema: DraftSchema });
355
+
356
+ // src/operations/createOrgSettings.ts
357
+ import { Query as Query8, writeOperation as writeOperation8 } from "roc-db";
358
+ import { z as z25 } from "zod";
359
+ var createOrgSettings = writeOperation8("createOrgSettings", z25.object({
360
+ name: z25.string(),
361
+ theme: z25.string().optional(),
362
+ primaryAdmin: UserRefSchema.optional()
363
+ }), (txn) => {
364
+ const ref = txn.createRef("OrgSettings");
365
+ const { name, theme, primaryAdmin } = txn.payload;
366
+ return Query8(() => txn.createEntity(ref, {
367
+ data: { name, theme },
368
+ parents: { primaryAdmin },
369
+ children: { featuredPosts: [] }
370
+ }));
223
371
  });
224
372
 
225
373
  // src/operations/createPost.ts
226
- import { Query as Query6, writeOperation as writeOperation6 } from "roc-db";
227
- var createPost = writeOperation6(CreatePostMutationSchema, PostSchema, (txn) => {
374
+ import { Query as Query9, writeOperation as writeOperation9 } from "roc-db";
375
+ import { z as z26 } from "zod";
376
+ var PayloadSchema2 = z26.object({
377
+ title: z26.string(),
378
+ slug: z26.string().optional(),
379
+ tags: z26.array(z26.string()).default([])
380
+ }).strict();
381
+ var createPost = writeOperation9("createPost", PayloadSchema2, (txn) => {
228
382
  const ref = txn.createRef("Post");
229
383
  const { title, slug, tags } = txn.payload;
230
- return Query6(() => txn.createEntity(ref, {
384
+ return Query9(() => txn.createEntity(ref, {
231
385
  data: { title, tags, slug },
232
386
  children: { blocks: [] }
233
387
  }));
234
388
  });
235
389
 
236
- // src/operations/deleteBlock.ts
237
- import { Query as Query7, QueryChain as QueryChain3, writeOperation as writeOperation7 } from "roc-db";
390
+ // src/operations/createUnknownRef.ts
391
+ import { Query as Query10, writeOperation as writeOperation10 } from "roc-db";
392
+ import { z as z27 } from "zod";
393
+ var createUnknownRef = writeOperation10("createUnknownRef", z27.object({}).optional(), (txn) => Query10(() => txn.createRef("NotARegisteredEntity")));
238
394
 
239
- // src/schemas/DeleteBlockMutationSchema.ts
240
- import { mutationSchemaGenerator as mutationSchemaGenerator10 } from "roc-db";
241
- import { z as z15 } from "zod";
242
- var DeleteBlockMutationSchema = mutationSchemaGenerator10("deleteBlock", z15.union([BlockParagraphRefSchema, BlockImageRefSchema]));
395
+ // src/operations/createUser.ts
396
+ import { Query as Query11, writeOperation as writeOperation11 } from "roc-db";
397
+ import { z as z28 } from "zod";
398
+ var createUser = writeOperation11("createUser", z28.object({ email: z28.string() }), (txn) => {
399
+ const ref = txn.createRef("User");
400
+ const { email } = txn.payload;
401
+ return Query11(() => txn.createEntity(ref, { data: { email } }));
402
+ });
403
+
404
+ // src/operations/deleteBlocks.ts
405
+ import { Query as Query12, QueryChain as QueryChain5, writeOperation as writeOperation12 } from "roc-db";
406
+ import { z as z29 } from "zod";
407
+
408
+ // src/schemas/BlockImageRefSchema.ts
409
+ import { refSchemaGenerator as refSchemaGenerator6 } from "roc-db";
410
+ var BlockImageRefSchema = refSchemaGenerator6("BlockImage");
243
411
 
244
- // src/operations/deleteBlock.ts
245
- var deleteBlock = writeOperation7(DeleteBlockMutationSchema, PostSchema, (txn) => {
246
- const blockRef = txn.payload;
247
- return QueryChain3(Query7(() => txn.readEntity(blockRef, true)), Query7((block) => txn.readEntity(block.parents.post, true)), Query7((post) => {
412
+ // src/operations/deleteBlocks.ts
413
+ var DeleteBlockQuery = (txn, blockRef) => {
414
+ return QueryChain5(Query12(() => txn.readEntity(blockRef)), Query12((block) => {
415
+ return txn.readEntity(block.parents.parent, true);
416
+ }), Query12((post) => {
248
417
  return txn.patchEntity(post.ref, {
249
- data: {
250
- blockRefs: post.data.blockRefs.filter((ref) => ref !== blockRef)
418
+ children: {
419
+ blocks: post.children.blocks.filter((ref) => ref !== blockRef)
251
420
  }
252
421
  });
253
- }), Query7(() => txn.deleteEntity(blockRef)), Query7((_, updatedPost) => {
254
- return updatedPost;
255
- }));
422
+ }), Query12(() => txn.deleteEntity(blockRef)));
423
+ };
424
+ var deleteBlocks = writeOperation12("deleteBlocks", z29.array(z29.union([
425
+ BlockParagraphRefSchema,
426
+ BlockImageRefSchema,
427
+ BlockRowRefSchema
428
+ ])), (txn) => {
429
+ const refs = txn.payload;
430
+ return QueryChain5(...refs.map((ref) => DeleteBlockQuery(txn, ref)));
256
431
  }, { changeSetOnly: true });
257
432
 
258
- // src/operations/deletePost.ts
259
- import { Query as Query8, writeOperation as writeOperation8 } from "roc-db";
433
+ // src/operations/deleteDraft.ts
434
+ import { Query as Query13, QueryChain as QueryChain6, writeOperation as writeOperation13 } from "roc-db";
435
+ var deleteDraft = writeOperation13("deleteDraft", DraftRefSchema, (txn) => {
436
+ const ref = txn.payload;
437
+ return QueryChain6(Query13(() => txn.deleteEntity(ref, true)), Query13(() => txn.deleteChangeSet(ref)));
438
+ });
260
439
 
261
- // src/schemas/DeletePostMutationSchema.ts
262
- import { mutationSchemaGenerator as mutationSchemaGenerator11 } from "roc-db";
263
- var DeletePostMutationSchema = mutationSchemaGenerator11("deletePost", PostRefSchema);
440
+ // src/operations/deleteOrgSettings.ts
441
+ import { Query as Query14, writeOperation as writeOperation14 } from "roc-db";
442
+ import { z as z30 } from "zod";
443
+ var deleteOrgSettings = writeOperation14("deleteOrgSettings", z30.object({}).optional(), (txn) => Query14(() => txn.deleteEntity("OrgSettings")));
264
444
 
265
445
  // src/operations/deletePost.ts
266
- var deletePost = writeOperation8(DeletePostMutationSchema, undefined, (txn) => {
446
+ import { Query as Query15, writeOperation as writeOperation15 } from "roc-db";
447
+ var deletePost = writeOperation15("deletePost", PostRefSchema, (txn) => {
267
448
  const ref = txn.payload;
268
- return Query8(() => txn.deleteEntity(ref, true));
449
+ return Query15(() => txn.deleteEntity(ref, true));
450
+ });
451
+
452
+ // src/operations/duplicateDraft.ts
453
+ import {
454
+ Query as Query16,
455
+ QueryChain as QueryChain7,
456
+ writeOperation as writeOperation16
457
+ } from "roc-db";
458
+ import { z as z31 } from "zod";
459
+ var duplicateDraft = writeOperation16("duplicateDraft", z31.object({ sourceRef: DraftRefSchema, postRef: PostRefSchema }).strict(), (txn) => {
460
+ const newDraftRef = txn.createRef("Draft");
461
+ const { sourceRef, postRef } = txn.payload;
462
+ return QueryChain7(Query16(() => txn.createEntity(newDraftRef, { parents: { post: postRef } })), Query16(() => txn.duplicateChangeSetMutations(sourceRef, newDraftRef)), Query16((dup) => {
463
+ const result = dup;
464
+ return {
465
+ draftRef: newDraftRef,
466
+ mutations: result.mutations,
467
+ refMap: result.refMap
468
+ };
469
+ }));
470
+ });
471
+
472
+ // 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)
478
+ }).strict();
479
+ var moveBlocks = writeOperation17("moveBlocks", PayloadSchema3, (txn) => {
480
+ const { refs } = txn.payload;
481
+ return QueryChain8(Query17(() => txn.batchReadEntities(refs)), Query17((items) => {
482
+ return "todo";
483
+ }));
484
+ });
485
+
486
+ // 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()
492
+ }), (txn) => {
493
+ const { size, parentRef } = txn.payload;
494
+ return Query18(() => txn.pageEntities({
495
+ entities: ["BlockImage", "BlockParagraph"],
496
+ size,
497
+ childrenOf: parentRef ? [parentRef] : []
498
+ }));
499
+ });
500
+
501
+ // 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) => {
505
+ const { size } = txn.payload;
506
+ return Query19(() => txn.pageEntities({ entities: [], size }));
507
+ });
508
+
509
+ // 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) => {
513
+ const { size } = txn.payload;
514
+ return Query20(() => txn.pageEntities({ entities: ["Post"], size }));
515
+ });
516
+
517
+ // 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) => {
521
+ const { size } = txn.payload;
522
+ return Query21(() => txn.pageEntities({ entities: "*", size }));
523
+ });
524
+
525
+ // 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) => {
529
+ const tag = txn.payload;
530
+ return Query22(() => txn.pageEntitiesByIndex("Post", "tags", tag));
269
531
  });
270
532
 
271
533
  // src/operations/readEntity.ts
272
- import { NotFoundError, Query as Query9, QueryChain as QueryChain4, readOperation } from "roc-db";
273
- import { z as z16 } from "zod";
274
- var readEntity = readOperation("readEntity", z16.string(), z16.union([PostSchema, BlockImageSchema, BlockParagraphSchema]), (txn) => {
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) => {
275
537
  const ref = txn.payload;
276
- return QueryChain4(Query9(() => txn.readEntity(ref)), Query9((entity) => {
538
+ return QueryChain9(Query23(() => txn.readEntity(ref)), Query23((entity) => {
277
539
  if (!entity) {
278
540
  throw new NotFoundError(ref);
279
541
  }
280
542
  return entity;
281
543
  }));
544
+ }, {
545
+ outputSchema: z38.union([
546
+ PostSchema,
547
+ BlockImageSchema,
548
+ BlockParagraphSchema
549
+ ])
282
550
  });
283
551
 
284
- // src/operations/readPost.ts
285
- import { Query as Query10, readOperation as readOperation2 } from "roc-db";
286
- var readPost = readOperation2("readPost", PostRefSchema, PostSchema, (txn) => {
552
+ // 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) => {
287
556
  const ref = txn.payload;
288
- return Query10(() => txn.readEntity(ref));
557
+ return QueryChain10(Query24(() => txn.readMutation(ref)), Query24((entity) => {
558
+ if (!entity) {
559
+ throw new NotFoundError2(ref);
560
+ }
561
+ return entity;
562
+ }));
289
563
  });
290
564
 
291
- // src/operations/updateBlockParagraph.ts
292
- import { Query as Query11, writeOperation as writeOperation9 } from "roc-db";
565
+ // 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)));
293
569
 
294
- // src/schemas/UpdateBlockParagraphMutationSchema.ts
295
- import { mutationSchemaGenerator as mutationSchemaGenerator12 } from "roc-db";
296
- import { z as z17 } from "zod";
297
- var UpdateBlockParagraphMutationSchema = mutationSchemaGenerator12("updateBlockParagraph", z17.object({
298
- ref: BlockParagraphRefSchema,
299
- content: z17.string()
300
- }));
570
+ // src/operations/readPost.ts
571
+ import { Query as Query26, readOperation as readOperation9 } from "roc-db";
572
+ var readPost = readOperation9("readPost", PostRefSchema, (txn) => {
573
+ const ref = txn.payload;
574
+ return Query26(() => txn.readEntity(ref, true));
575
+ }, { outputSchema: PostSchema });
576
+
577
+ // 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) => {
581
+ const slug = txn.payload;
582
+ return Query27(() => txn.readEntityByUniqueField("Post", "slug", slug));
583
+ }, { outputSchema: PostSchema });
584
+
585
+ // src/operations/testTransactionalEdits.ts
586
+ 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";
589
+ var TestCreatePatchDeleteInSameTransaction = (txn, title) => {
590
+ const postRef = txn.createRef("Post");
591
+ return QueryChain11(Query28(() => txn.createEntity(postRef, {
592
+ data: { title, tags: [] },
593
+ children: { blocks: [] }
594
+ })), Query28(() => txn.patchEntity(postRef, { data: { foo: "bar" } })), Query28((post) => {
595
+ expect(post.data.title).toBe(title);
596
+ expect(post.data.foo).toBe("bar");
597
+ }), Query28(() => txn.patchEntity(postRef, { data: { foo: null, bar: "foo" } })), Query28((post) => {
598
+ expect(post.data.title).toBe(title);
599
+ expect(post.data.foo).toBeUndefined();
600
+ expect(post.data.bar).toBe("foo");
601
+ expect(txn.log).toHaveLength(1);
602
+ expect(txn.log.get(postRef)?.[0]).toBe("create");
603
+ }), Query28((post) => txn.deleteEntity(postRef)), Query28((res) => {
604
+ expect(res).toBe(1);
605
+ expect(txn.log).toHaveLength(0);
606
+ }));
607
+ };
608
+ var TestUpdateAndDeleteInSameTransaction = (txn, ref) => {
609
+ return QueryChain11(Query28(() => txn.patchEntity(ref, { data: { foo: "bar" } })), Query28((post) => {
610
+ expect(post.data.foo).toBe("bar");
611
+ }), Query28(() => txn.patchEntity(ref, { data: { foo: null, bar: "foo" } })), Query28((post) => {
612
+ expect(post.data.foo).toBeUndefined();
613
+ expect(post.data.bar).toBe("foo");
614
+ expect(txn.log).toHaveLength(1);
615
+ expect(txn.log.get(ref)?.[0]).toBe("update");
616
+ }), Query28((post) => txn.deleteEntity(ref)), Query28((res) => {
617
+ expect(res).toBe(1);
618
+ expect(txn.log).toHaveLength(1);
619
+ expect(txn.log.get(ref)?.[0]).toBe("delete");
620
+ }));
621
+ };
622
+ var TestCreateOnExistingRef = (txn) => {
623
+ const ref = txn.createRef("Post");
624
+ return QueryChain11(Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })), Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })));
625
+ };
626
+ var PayloadSchema4 = z42.object({
627
+ name: z42.string().optional(),
628
+ post1ref: PostRefSchema.optional(),
629
+ post2ref: PostRefSchema.optional()
630
+ }).strict();
631
+ var testTransactionalEdits = writeOperation18("testTransactionalEdits", PayloadSchema4, (txn) => {
632
+ const { name, post1ref, post2ref } = txn.payload;
633
+ if (name)
634
+ return TestCreatePatchDeleteInSameTransaction(txn, name);
635
+ if (post1ref)
636
+ return TestUpdateAndDeleteInSameTransaction(txn, post1ref);
637
+ if (post2ref)
638
+ return TestCreateOnExistingRef(txn);
639
+ }, {});
301
640
 
302
641
  // src/operations/updateBlockParagraph.ts
303
- var updateBlockParagraph = writeOperation9(UpdateBlockParagraphMutationSchema, BlockParagraphRefSchema, (txn) => {
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({
645
+ ref: BlockParagraphRefSchema,
646
+ content: z43.string()
647
+ }), (txn) => {
304
648
  const { ref, content } = txn.payload;
305
- return Query11(() => txn.patchEntity(ref, {
649
+ return Query29(() => txn.patchEntity(ref, {
306
650
  data: { content }
307
651
  }));
308
- });
652
+ }, { outputSchema: BlockParagraphSchema });
653
+
654
+ // 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) => {
658
+ const { name } = txn.payload;
659
+ return Query30(() => txn.patchEntity("OrgSettings", { data: { name } }));
660
+ }, { debounce: 10 });
309
661
 
310
662
  // src/operations/updatePost.ts
311
- import { Query as Query12, writeOperation as writeOperation10 } from "roc-db";
312
- var updatePost = writeOperation10(UpdatePostMutationSchema, PostSchema, (txn) => {
663
+ import { Query as Query31, writeOperation as writeOperation21 } from "roc-db";
664
+ import { z as z45 } from "zod";
665
+ var PayloadSchema5 = z45.object({
666
+ ref: PostRefSchema,
667
+ title: z45.string().optional(),
668
+ tags: z45.array(z45.string()).optional().default([]),
669
+ authorRef: UserRefSchema.optional()
670
+ });
671
+ var updatePost = writeOperation21("updatePost", PayloadSchema5, (txn) => {
313
672
  const { ref, authorRef, ...data } = txn.payload;
314
- return Query12(() => txn.updateEntity(ref, {
673
+ return Query31(() => txn.updateEntity(ref, {
315
674
  data,
316
675
  parents: { author: authorRef },
317
676
  children: { blocks: [] }
318
677
  }));
319
- });
678
+ }, { outputSchema: PostSchema });
679
+
680
+ // 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) => {
684
+ const { ref, description } = txn.payload;
685
+ return Query32(() => txn.patchEntity(ref, { data: { description } }));
686
+ }, { debounce: 10, changeSetOnly: true, outputSchema: PostSchema });
687
+
688
+ // 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) => {
692
+ const { ref, slug } = txn.payload;
693
+ return Query33(() => txn.patchEntity(ref, { data: { slug } }));
694
+ }, { debounce: 10, outputSchema: PostSchema });
695
+
696
+ // 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) => {
700
+ const { ref, tags } = txn.payload;
701
+ return Query34(() => txn.patchEntity(ref, { data: { tags } }));
702
+ }, { debounce: 10, outputSchema: PostSchema });
320
703
 
321
704
  // src/operations/updatePostTitle.ts
322
- import { Query as Query13, writeOperation as writeOperation11 } from "roc-db";
323
- var updatePostTitle = writeOperation11(UpdatePostTitleMutationSchema, PostSchema, (txn) => {
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) => {
324
708
  const { ref, title } = txn.payload;
325
- return Query13(() => txn.patchEntity(ref, { data: { title } }));
326
- }, { debounce: 10 });
709
+ return Query35(() => txn.patchEntity(ref, { data: { title } }));
710
+ }, { debounce: 10, outputSchema: PostSchema });
711
+
712
+ // 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) => {
716
+ 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(() => {
718
+ return [
719
+ txn.readEntityByUniqueField("Post", "slug", slug, false),
720
+ txn.readEntityByUniqueField("Post", "slug", newSlug, false)
721
+ ];
722
+ }));
723
+ });
327
724
 
328
725
  // src/operations/index.ts
329
726
  var operations = [
727
+ applyDraft,
330
728
  createBlockImage,
331
729
  createBlockTitle,
332
730
  createBlockParagrah,
333
731
  createBlockRow,
732
+ createBlockRowReadingRoot,
334
733
  createDraft,
734
+ createOrgSettings,
335
735
  createPost,
336
- deleteBlock,
736
+ createUnknownRef,
737
+ createUser,
738
+ crudBySlug,
739
+ deleteBlocks,
740
+ deleteDraft,
741
+ deleteOrgSettings,
337
742
  deletePost,
743
+ duplicateDraft,
744
+ readPostBySlug,
745
+ moveBlocks,
746
+ pagePostsByTag,
747
+ pageBlocks,
338
748
  readEntity,
749
+ readMutation,
750
+ readOrgSettings,
339
751
  readPost,
752
+ pageEmptyEntitiesArray,
753
+ pagePosts,
754
+ pageSplat,
755
+ testTransactionalEdits,
340
756
  updateBlockParagraph,
757
+ updateOrgSettingsName,
341
758
  updatePost,
759
+ updatePostDescription,
760
+ updatePostSlug,
761
+ updatePostTags,
342
762
  updatePostTitle
343
763
  ];
344
764
  // src/testAdapterImplementation.ts
345
- import { beforeAll, describe, expect, test } from "bun:test";
346
- import { BadRequestError, NotFoundError as NotFoundError2 } from "roc-db";
347
- var prepareChangeSetTest = async (adapter) => {
348
- const [post] = await adapter.createPost({
765
+ import { beforeAll, describe, expect as expect2, test } from "bun:test";
766
+ import {
767
+ BadRequestError,
768
+ ConflictError,
769
+ Entity as Entity9,
770
+ NotFoundError as NotFoundError3,
771
+ Snowflake
772
+ } from "roc-db";
773
+ import { z as z51 } from "zod";
774
+ import { faker } from "@faker-js/faker";
775
+ var snowflake = new Snowflake(10, 10);
776
+ var prepareChangeSetTest = async (adapter, adapter2) => {
777
+ const [post, createPostMutation] = await adapter.createPost({
349
778
  title: "Title 1",
350
- slug: "title-1",
779
+ slug: faker.lorem.slug(5),
351
780
  tags: ["Foo", "Bar"]
352
781
  });
353
- const [draft] = await adapter.createDraft({
782
+ expect2(createPostMutation.log).toStrictEqual([[post.ref, "create"]]);
783
+ const [draft, createDraftMutation] = await adapter.createDraft({
354
784
  postRef: post.ref
355
785
  });
786
+ expect2(createDraftMutation.log).toStrictEqual([[draft.ref, "create"]]);
356
787
  const changeSetAdapter = adapter.changeSet(draft.ref);
357
- const [{ block: blockParagraph1 }] = await changeSetAdapter.createBlockParagraph({
788
+ const [
789
+ { block: blockParagraph1, updatedParent: updatedPost },
790
+ createBlockParagraphMutation
791
+ ] = await changeSetAdapter.createBlockParagraph({
358
792
  parentRef: post.ref
359
793
  });
360
- const [{ block: blockRow, updatedParent }] = await changeSetAdapter.createBlockRow({
794
+ expect2(updatedPost.children.blocks).toStrictEqual([blockParagraph1.ref]);
795
+ expect2(updatedPost.children.blocks).toHaveLength(1);
796
+ expect2(createBlockParagraphMutation.log[1][2].children.blocks).toStrictEqual([]);
797
+ const readPost1 = await changeSetAdapter.readEntity(post.ref);
798
+ expect2(readPost1.children.blocks).toHaveLength(1);
799
+ const [{ block: blockRow, updatedParent: updatedPost2 }, mutation] = await changeSetAdapter.createBlockRow({
361
800
  parentRef: post.ref
362
801
  });
363
- const [{ block: blockParagraph2 }] = await changeSetAdapter.createBlockParagraph({
802
+ expect2(updatedPost2.children.blocks).toHaveLength(2);
803
+ const readPost2 = await changeSetAdapter.readEntity(post.ref);
804
+ expect2(readPost2.children.blocks).toHaveLength(2);
805
+ const [{ block: blockParagraph2, updatedParent: updatedBlockRow }] = await changeSetAdapter.createBlockParagraph({
364
806
  parentRef: blockRow.ref
365
807
  });
808
+ const readPost3 = await changeSetAdapter.readEntity(post.ref);
809
+ expect2(readPost3.children.blocks).toHaveLength(2);
366
810
  return {
367
811
  postRef: post.ref,
368
812
  draftRef: draft.ref,
369
813
  changeSetAdapter,
370
814
  blockParagraph1,
371
815
  blockParagraph2,
372
- blockRow,
373
- post: updatedParent
816
+ blockRow: updatedBlockRow,
817
+ draft,
818
+ post: readPost3
374
819
  };
375
820
  };
376
- var testAdapterImplementation = (adapterConstructor, engineArgsAdapter1 = {}, engineArgsAdapter2 = {}) => {
377
- return async () => {
378
- const adapter1 = adapterConstructor({ operations, entities, ...engineArgsAdapter1 });
379
- const adapter2 = adapterConstructor({ operations, entities, ...engineArgsAdapter2 });
380
- describe("Post CRUD", async () => {
381
- let postRef;
382
- let post;
383
- let createPostMutation;
384
- beforeAll(async () => {
385
- const createPostRes = await adapter1.createPost({
386
- title: "Title 1",
387
- slug: "title-1",
388
- tags: ["Foo", "Bar"]
389
- });
390
- post = createPostRes[0];
391
- postRef = createPostRes[0].ref;
392
- createPostMutation = createPostRes[1];
393
- });
394
- test("create (createEntity function)", async () => {
395
- expect(post).toMatchZodSchema(PostSchema);
396
- expect(post.data.title).toBe("Title 1");
397
- expect(post.data.tags).toStrictEqual(["Foo", "Bar"]);
398
- });
399
- test("read (readEntity function)", async () => {
400
- const readPostRes = await adapter1.readPost(postRef);
401
- expect(readPostRes.data.title).toStrictEqual("Title 1");
402
- expect(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
403
- expect(readPostRes).toMatchZodSchema(PostSchema);
404
- });
405
- test("update (updateEntity function)", async () => {
406
- const [post2] = await adapter1.updatePost({
407
- ref: postRef,
408
- title: "Title 2",
409
- tags: ["Foo"]
410
- });
411
- expect(post2.data.tags).toStrictEqual(["Foo"]);
412
- expect(post2.data.title).toBe("Title 2");
413
- expect(post2).toMatchZodSchema(PostSchema);
414
- });
415
- test("updateTitle (patchEntity function + debounce)", async () => {
416
- const updatePostTitleRes1 = await adapter1.updatePostTitle({
417
- ref: postRef,
418
- title: "Title 3"
419
- });
420
- expect(updatePostTitleRes1[0]).toMatchZodSchema(PostSchema);
421
- const updatePostTitleRes2 = await adapter1.updatePostTitle({
422
- ref: postRef,
423
- title: "Title 4"
424
- });
425
- expect(updatePostTitleRes2[0]).toMatchZodSchema(PostSchema);
426
- expect(updatePostTitleRes2[1].ref).toBe(updatePostTitleRes1[1].ref);
427
- expect(updatePostTitleRes2[1].timestamp >= updatePostTitleRes1[1].timestamp).toBeTrue();
428
- });
429
- test("delete (deleteEntity function)", async () => {
430
- const [count, mutation] = await adapter1.deletePost(postRef);
431
- expect(count).toBe(1);
432
- expect(mutation.log).toStrictEqual([[postRef, "delete", null]]);
433
- });
434
- test("sync mutation", async () => {
435
- const res = await adapter2.syncOptimisticMutation(createPostMutation);
436
- expect(res[0]).toStrictEqual(post);
437
- expect(res[1]).toStrictEqual(createPostMutation);
438
- expect(() => adapter2.syncOptimisticMutation(createPostMutation)).toThrowError(BadRequestError);
439
- });
440
- });
441
- describe("changeSet", async () => {
442
- let postRef, draftRef, changeSetAdapter, blockParagraph1, post, blockRow, blockParagraph2;
443
- beforeAll(async () => {
444
- ({
445
- postRef,
446
- draftRef,
447
- changeSetAdapter,
448
- blockParagraph1,
449
- post,
450
- blockRow,
451
- blockParagraph2
452
- } = await prepareChangeSetTest(adapter1));
453
- });
454
- test("create (createEntity function w/changeSetRef)", async () => {
455
- expect(blockParagraph1).toMatchZodSchema(BlockParagraphSchema);
456
- expect(post).toMatchZodSchema(PostSchema);
457
- });
458
- test("read (readEntity function w/changeSetRef)", async () => {
459
- const read = await changeSetAdapter.readEntity(blockParagraph1.ref);
460
- expect(read).toMatchZodSchema(BlockParagraphSchema);
461
- });
462
- test("update (patchEntity function w/changeSetRef)", async () => {
463
- const [updatedBlock] = await changeSetAdapter.updateBlockParagraph({
464
- ref: blockParagraph1.ref,
465
- content: "Hello, world!"
466
- });
467
- expect(updatedBlock).toMatchZodSchema(BlockParagraphSchema);
468
- });
469
- test("delete (with cascade delete)", async () => {
470
- const [count, mutation] = await changeSetAdapter.deletePost(postRef);
471
- expect(count).toBe(4);
472
- expect(mutation.log).toStrictEqual([
473
- [blockParagraph1.ref, "delete", draftRef],
474
- [blockRow.ref, "delete", draftRef],
475
- [blockParagraph2.ref, "delete", draftRef],
476
- [postRef, "delete", draftRef]
477
- ]);
478
- await expect(() => changeSetAdapter.readEntity(blockParagraph1.ref)).toThrow(NotFoundError2);
479
- await expect(() => changeSetAdapter.updateBlockParagraph({
480
- ref: blockParagraph1.ref,
481
- content: "Foo"
482
- })).toThrow(NotFoundError2);
483
- });
484
- test("pageMutations", async () => {
485
- const res = await changeSetAdapter.pageMutations({
486
- changeSetRef: draftRef
487
- });
488
- expect(res.length).toBeGreaterThan(0);
489
- expect(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
490
- });
491
- test("pageMutations2", async () => {
492
- const res = await changeSetAdapter.pageMutations({
493
- changeSetRef: draftRef
494
- });
495
- expect(res.length).toBeGreaterThan(0);
496
- expect(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
497
- });
821
+ var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
822
+ let createAdapter = async ({
823
+ optimistic = false,
824
+ session = { identityRef: "User/42" },
825
+ engineArgs
826
+ } = {}) => {
827
+ return adapterConstructor({
828
+ operations,
829
+ entities,
830
+ session,
831
+ snowflake,
832
+ optimistic,
833
+ ...engineArgs ?? await generateArgs()
498
834
  });
499
835
  };
836
+ let adapter1, adapter2;
837
+ beforeAll(async () => {
838
+ adapter1 = await createAdapter();
839
+ adapter2 = await createAdapter();
840
+ });
841
+ describe("Post CRUD", () => {
842
+ let postRef;
843
+ let post;
844
+ let createPostMutation;
845
+ beforeAll(async () => {
846
+ const createPostRes = await adapter1.createPost({
847
+ title: "Title 1",
848
+ slug: faker.lorem.slug(5),
849
+ tags: ["Foo", "Bar"]
850
+ });
851
+ post = createPostRes[0];
852
+ postRef = createPostRes[0].ref;
853
+ createPostMutation = createPostRes[1];
854
+ });
855
+ test("create (createEntity function)", async () => {
856
+ expect2(post).toMatchZodSchema(PostEntity.schema);
857
+ expect2(post.data.title).toBe("Title 1");
858
+ expect2(post.data.tags).toStrictEqual(["Foo", "Bar"]);
859
+ expect2(createPostMutation).toMatchZodSchema(CreatePostMutationSchema);
860
+ });
861
+ test("read (readEntity function)", async () => {
862
+ const readPostRes = await adapter1.readPost(postRef);
863
+ expect2(readPostRes.data.title).toStrictEqual("Title 1");
864
+ expect2(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
865
+ expect2(readPostRes).toMatchZodSchema(PostEntity.schema);
866
+ });
867
+ test("read by unique", async () => {
868
+ const readPostRes = await adapter1.readPostBySlug(post.data.slug);
869
+ expect2(readPostRes.data.title).toStrictEqual("Title 1");
870
+ expect2(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
871
+ expect2(readPostRes.data.slug).toStrictEqual(post.data.slug);
872
+ });
873
+ test("create with same slug", async () => {
874
+ expect2(() => adapter1.createPost({
875
+ title: "Title 2",
876
+ slug: post.data.slug,
877
+ tags: ["Foo", "Bar"]
878
+ })).toThrow(ConflictError);
879
+ });
880
+ test("update unique slug", async () => {
881
+ const slug1 = faker.lorem.slug(5);
882
+ const slug2 = faker.lorem.slug(5);
883
+ const [post2] = await adapter1.createPost({
884
+ title: "Title 1",
885
+ slug: slug1
886
+ });
887
+ const readPostRes1 = await adapter1.readPostBySlug(slug1);
888
+ expect2(readPostRes1.data.slug).toStrictEqual(slug1);
889
+ const [updateRes] = await adapter1.updatePostSlug({
890
+ ref: post2.ref,
891
+ slug: slug2
892
+ });
893
+ expect2(updateRes.data.slug).toStrictEqual(slug2);
894
+ expect2(() => adapter1.readPostBySlug(slug1)).toThrow(NotFoundError3);
895
+ const readPostRes2 = await adapter1.readPostBySlug(slug2);
896
+ expect2(readPostRes2.data.slug).toStrictEqual(slug2);
897
+ });
898
+ test("update and delete post by slug", async () => {
899
+ const slug1 = faker.lorem.slug(5);
900
+ const slug2 = faker.lorem.slug(5);
901
+ const [post2] = await adapter1.createPost({
902
+ title: "Title 1",
903
+ slug: slug1
904
+ });
905
+ const [res] = await adapter1.crudBySlug({
906
+ slug: slug1,
907
+ newSlug: slug2
908
+ });
909
+ expect2(res).toStrictEqual([null, null]);
910
+ });
911
+ test("update index entries", async () => {
912
+ const [post2] = await adapter1.createPost({
913
+ title: "Title 1",
914
+ tags: ["foo"]
915
+ });
916
+ const pageTagFoo1 = await adapter1.pagePostsByTag("foo");
917
+ expect2(pageTagFoo1.length).toBe(1);
918
+ expect2(pageTagFoo1[0].ref).toBe(post2.ref);
919
+ const [updatedRes] = await adapter1.updatePostTags({
920
+ ref: post2.ref,
921
+ tags: ["bar"]
922
+ });
923
+ const pageTagFoo2 = await adapter1.pagePostsByTag("foo");
924
+ expect2(pageTagFoo2.length).toBe(0);
925
+ const pageTagBar1 = await adapter1.pagePostsByTag("bar");
926
+ expect2(pageTagBar1.length).toBe(1);
927
+ await adapter1.deletePost(post2.ref);
928
+ const pageTagBar2 = await adapter1.pagePostsByTag("bar");
929
+ expect2(pageTagBar2.length).toBe(0);
930
+ });
931
+ test("read not found (readEntity function)", async () => {
932
+ expect2(() => adapter1.readPost("Post/999")).toThrow(NotFoundError3);
933
+ });
934
+ test.todo("update (updateEntity function)", async () => {
935
+ const [post2] = await adapter1.updatePost({
936
+ ref: postRef,
937
+ title: "Title 2",
938
+ tags: ["Foo"]
939
+ });
940
+ expect2(post2.data.tags).toStrictEqual(["Foo"]);
941
+ expect2(post2.data.title).toBe("Title 2");
942
+ expect2(post2).toMatchZodSchema(PostEntity.schema);
943
+ });
944
+ test("updateTitle (patchEntity function + debounce)", async () => {
945
+ const [update1, mutation1] = await adapter1.updatePostTitle({
946
+ ref: postRef,
947
+ title: "Title 3"
948
+ });
949
+ expect2(update1).toMatchZodSchema(PostEntity.schema);
950
+ expect2(mutation1).toMatchZodSchema(UpdatePostTitleMutationSchema);
951
+ const [update2, mutation2] = await adapter1.updatePostTitle({
952
+ ref: postRef,
953
+ title: "Title 4"
954
+ });
955
+ expect2(update2).toMatchZodSchema(PostEntity.schema);
956
+ expect2(mutation2).toMatchZodSchema(UpdatePostTitleMutationSchema);
957
+ expect2(mutation1.ref).toBe(mutation2.ref);
958
+ expect2(mutation2.timestamp >= mutation1.timestamp).toBeTrue();
959
+ });
960
+ test("updatePostDescription without changeSetAdapter fails with BadRequestError", async () => {
961
+ expect2(() => adapter1.updatePostDescription({
962
+ ref: postRef,
963
+ description: "Description 1"
964
+ })).toThrow(BadRequestError);
965
+ });
966
+ test("delete (deleteEntity function)", async () => {
967
+ const currentPost = await adapter1.readPost(postRef);
968
+ expect2(currentPost.ref).toBe(postRef);
969
+ const [count, mutation] = await adapter1.deletePost(postRef);
970
+ expect2(count).toBe(1);
971
+ expect2(mutation.log).toStrictEqual([
972
+ [postRef, "delete", currentPost]
973
+ ]);
974
+ expect2(() => adapter1.readPost(postRef)).toThrow(NotFoundError3);
975
+ });
976
+ test("sync mutation", async () => {
977
+ const {
978
+ persistedAt: ignore,
979
+ ...createPostMutationWithoutPersistedAt
980
+ } = createPostMutation;
981
+ const [{ persistedAt, ...mutation }] = await adapter2.persistOptimisticMutations([createPostMutation]);
982
+ expect2(mutation).toStrictEqual(createPostMutationWithoutPersistedAt);
983
+ });
984
+ test("sync mutation with debounce > 0", async () => {
985
+ const [post2, createPostMutation2] = await adapter1.createPost({
986
+ title: "Foo"
987
+ });
988
+ const [{ persistedAt, ...mutation }] = await adapter2.persistOptimisticMutations([createPostMutation2]);
989
+ const {
990
+ persistedAt: ignore,
991
+ ...createPostMutationWithoutPersistedAt
992
+ } = createPostMutation2;
993
+ expect2(mutation).toStrictEqual(createPostMutationWithoutPersistedAt);
994
+ const res = await adapter1.updatePostTitle({
995
+ ref: post2.ref,
996
+ title: "A"
997
+ });
998
+ const [, debounceMutation] = await adapter1.updatePostTitle({
999
+ ref: post2.ref,
1000
+ title: "A"
1001
+ });
1002
+ expect2(debounceMutation.debounceCount).toBe(1);
1003
+ const [debounceMutationPersist] = await adapter2.persistOptimisticMutations([debounceMutation]);
1004
+ expect2(debounceMutationPersist.debounceCount).toBe(1);
1005
+ expect2(debounceMutationPersist.persistedAt).toBeDefined();
1006
+ });
1007
+ test("create, patch and delete the same item within the same transaction", async () => {
1008
+ const [post1] = await adapter1.createPost({ title: "Post 1" });
1009
+ const [post2] = await adapter1.createPost({ title: "Post 1" });
1010
+ const [currentPost, mutation] = await adapter1.testTransactionalEdits({
1011
+ name: "Test"
1012
+ });
1013
+ expect2(mutation.log).toHaveLength(0);
1014
+ const [, mutation2] = await adapter1.testTransactionalEdits({
1015
+ post1ref: post1.ref
1016
+ });
1017
+ expect2(mutation2.log).toHaveLength(1);
1018
+ expect2(mutation2.log[0][1]).toBe("delete");
1019
+ expect2(() => adapter1.testTransactionalEdits({
1020
+ post2ref: post2.ref
1021
+ })).toThrow(BadRequestError);
1022
+ });
1023
+ });
1024
+ describe("OrgSettings singleton", () => {
1025
+ let adapter;
1026
+ beforeAll(async () => {
1027
+ adapter = await createAdapter();
1028
+ });
1029
+ test("create returns bare-name ref", async () => {
1030
+ const [orgSettings] = await adapter.createOrgSettings({
1031
+ name: "Acme",
1032
+ theme: "dark",
1033
+ primaryAdmin: "User/42"
1034
+ });
1035
+ expect2(orgSettings.ref).toBe("OrgSettings");
1036
+ expect2(orgSettings.entity).toBe("OrgSettings");
1037
+ expect2(orgSettings.data.name).toBe("Acme");
1038
+ expect2(orgSettings.parents.primaryAdmin).toBe("User/42");
1039
+ expect2(orgSettings.children.featuredPosts).toStrictEqual([]);
1040
+ });
1041
+ test("read by bare-name ref", async () => {
1042
+ const orgSettings = await adapter.readOrgSettings();
1043
+ expect2(orgSettings.ref).toBe("OrgSettings");
1044
+ expect2(orgSettings.data.name).toBe("Acme");
1045
+ });
1046
+ test("second create throws ConflictError", async () => {
1047
+ expect2(() => adapter.createOrgSettings({ name: "Other" })).toThrow(ConflictError);
1048
+ });
1049
+ test("patch + debounce collapses mutations", async () => {
1050
+ const [, mutation1] = await adapter.updateOrgSettingsName({
1051
+ name: "Acme Co"
1052
+ });
1053
+ const [updated, mutation2] = await adapter.updateOrgSettingsName({
1054
+ name: "Acme Inc"
1055
+ });
1056
+ expect2(updated.data.name).toBe("Acme Inc");
1057
+ expect2(mutation1.ref).toBe(mutation2.ref);
1058
+ expect2(mutation2.debounceCount).toBeGreaterThanOrEqual(1);
1059
+ });
1060
+ test("debounce does not collapse across identities", async () => {
1061
+ const sharedEngineArgs = await generateArgs();
1062
+ const adapterA = await createAdapter({
1063
+ session: { identityRef: "User/A" },
1064
+ engineArgs: sharedEngineArgs
1065
+ });
1066
+ const adapterB = await createAdapter({
1067
+ session: { identityRef: "User/B" },
1068
+ engineArgs: sharedEngineArgs
1069
+ });
1070
+ await adapterA.createOrgSettings({ name: "Acme" });
1071
+ const [, mutationA] = await adapterA.updateOrgSettingsName({
1072
+ name: "From A"
1073
+ });
1074
+ const [, mutationB] = await adapterB.updateOrgSettingsName({
1075
+ name: "From B"
1076
+ });
1077
+ expect2(mutationA.ref).not.toBe(mutationB.ref);
1078
+ expect2(mutationA.identityRef).toBe("User/A");
1079
+ expect2(mutationB.identityRef).toBe("User/B");
1080
+ await adapterA.deleteOrgSettings();
1081
+ });
1082
+ test("delete removes the singleton", async () => {
1083
+ const [count] = await adapter.deleteOrgSettings();
1084
+ expect2(count).toBe(1);
1085
+ expect2(() => adapter.readOrgSettings()).toThrow(NotFoundError3);
1086
+ });
1087
+ test("recreate after delete works", async () => {
1088
+ const [orgSettings] = await adapter.createOrgSettings({
1089
+ name: "NewOrg"
1090
+ });
1091
+ expect2(orgSettings.ref).toBe("OrgSettings");
1092
+ expect2(orgSettings.data.name).toBe("NewOrg");
1093
+ });
1094
+ test("constructor rejects singleton + uniqueDataKeys", () => {
1095
+ expect2(() => new Entity9("Bad", {
1096
+ singleton: true,
1097
+ data: z51.object({ name: z51.string() }),
1098
+ uniqueDataKeys: ["name"]
1099
+ })).toThrow(/singleton/);
1100
+ });
1101
+ test("createRef throws on unregistered entity", async () => {
1102
+ expect2(() => adapter.createUnknownRef()).toThrow(BadRequestError);
1103
+ });
1104
+ });
1105
+ describe("paging", () => {
1106
+ let adapter;
1107
+ let post1ref;
1108
+ beforeAll(async () => {
1109
+ adapter = await createAdapter();
1110
+ const [post1] = await adapter.createPost({ title: "Post 1" });
1111
+ post1ref = post1.ref;
1112
+ const [user] = await adapter.createUser({ email: "foo@bar.com" });
1113
+ const [draft1] = await adapter.createDraft({
1114
+ postRef: post1.ref
1115
+ });
1116
+ const [post2] = await adapter.createPost({ title: "Post 2" });
1117
+ const [draft2] = await adapter.createDraft({
1118
+ postRef: post2.ref
1119
+ });
1120
+ const draft1adapter = adapter.changeSet(draft1.ref);
1121
+ await draft1adapter.createBlockImage({
1122
+ parentRef: post1.ref,
1123
+ url: "https://example.com/image.png"
1124
+ });
1125
+ await draft1adapter.createBlockParagraph({
1126
+ parentRef: post1.ref
1127
+ });
1128
+ await adapter.applyDraft(draft1.ref);
1129
+ const draft2adapter = adapter.changeSet(draft2.ref);
1130
+ await draft2adapter.createBlockImage({
1131
+ parentRef: post2.ref,
1132
+ url: "https://example.com/image.png"
1133
+ });
1134
+ await draft2adapter.createBlockParagraph({
1135
+ parentRef: post2.ref
1136
+ });
1137
+ await adapter.applyDraft(draft2.ref);
1138
+ });
1139
+ test("limited to given collection", async () => {
1140
+ const res = await adapter.pagePosts();
1141
+ expect2(res).toHaveLength(2);
1142
+ });
1143
+ test("limit", async () => {
1144
+ const res = await adapter.pagePosts({ size: 1 });
1145
+ expect2(res).toHaveLength(1);
1146
+ });
1147
+ test("pageSplat", async () => {
1148
+ const res = await adapter.pageSplat({});
1149
+ expect2(res).toHaveLength(11);
1150
+ });
1151
+ test("pageEmptyEntitiesArray", async () => {
1152
+ const res = await adapter.pageEmptyEntitiesArray({});
1153
+ expect2(res).toHaveLength(0);
1154
+ });
1155
+ test("pageBlocks", async () => {
1156
+ const res = await adapter.pageBlocks({});
1157
+ expect2(res).toHaveLength(4);
1158
+ });
1159
+ test("pageBlocks with parent ref", async () => {
1160
+ const res = await adapter.pageBlocks({ parentRef: post1ref });
1161
+ expect2(res).toHaveLength(2);
1162
+ expect2(res[0].parents.parent).toBe(post1ref);
1163
+ expect2(res[1].parents.parent).toBe(post1ref);
1164
+ });
1165
+ });
1166
+ describe("changeSet", () => {
1167
+ let postRef, draftRef, changeSetAdapter, blockParagraph1, post, blockRow, blockParagraph2, draft;
1168
+ beforeAll(async () => {
1169
+ ({
1170
+ postRef,
1171
+ draftRef,
1172
+ changeSetAdapter,
1173
+ blockParagraph1,
1174
+ post,
1175
+ blockRow,
1176
+ blockParagraph2,
1177
+ draft
1178
+ } = await prepareChangeSetTest(adapter1, adapter2));
1179
+ });
1180
+ test("create (createEntity function w/changeSetRef)", async () => {
1181
+ expect2(blockParagraph1).toMatchZodSchema(BlockParagraph.schema);
1182
+ expect2(post).toMatchZodSchema(PostEntity.schema);
1183
+ });
1184
+ test("read (readEntity function w/changeSetRef)", async () => {
1185
+ const read = await changeSetAdapter.readEntity(blockParagraph1.ref);
1186
+ expect2(read).toMatchZodSchema(BlockParagraph.schema);
1187
+ });
1188
+ test("update (patchEntity function w/changeSetRef)", async () => {
1189
+ const [updatedBlock] = await changeSetAdapter.updateBlockParagraph({
1190
+ ref: blockParagraph1.ref,
1191
+ content: "Hello, world!"
1192
+ });
1193
+ expect2(updatedBlock).toMatchZodSchema(BlockParagraph.schema);
1194
+ });
1195
+ test("move (batchReadEntities function)", async () => {
1196
+ const res = await changeSetAdapter.moveBlocks({
1197
+ refs: [blockParagraph1.ref],
1198
+ targetPosition: 1
1199
+ });
1200
+ });
1201
+ test("delete (with cascade delete)", async () => {
1202
+ const postUpdated = await changeSetAdapter.readEntity(postRef);
1203
+ const blockParagraph1Update = await changeSetAdapter.readEntity(blockParagraph1.ref);
1204
+ const blockRowUpdated = await changeSetAdapter.readEntity(blockRow.ref);
1205
+ const [count, mutation] = await changeSetAdapter.deletePost(postRef);
1206
+ expect2(count).toBe(4);
1207
+ expect2(mutation.log).toStrictEqual([
1208
+ [blockParagraph1.ref, "delete", blockParagraph1Update],
1209
+ [blockParagraph2.ref, "delete", blockParagraph2],
1210
+ [blockRow.ref, "delete", blockRowUpdated],
1211
+ [postRef, "delete", postUpdated]
1212
+ ]);
1213
+ await expect2(() => changeSetAdapter.readEntity(blockParagraph1.ref)).toThrow(NotFoundError3);
1214
+ await expect2(() => changeSetAdapter.updateBlockParagraph({
1215
+ ref: blockParagraph1.ref,
1216
+ content: "Foo"
1217
+ })).toThrow(NotFoundError3);
1218
+ });
1219
+ test("pageMutations", async () => {
1220
+ const res = await changeSetAdapter.pageMutations({
1221
+ changeSetRef: draftRef
1222
+ });
1223
+ expect2(res.length).toBeGreaterThan(0);
1224
+ expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
1225
+ });
1226
+ test("pageMutations run again", async () => {
1227
+ const res = await changeSetAdapter.pageMutations({
1228
+ changeSetRef: draftRef
1229
+ });
1230
+ expect2(res.length).toBeGreaterThan(0);
1231
+ expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
1232
+ });
1233
+ test("invalid changeSetRef throws error", async () => {
1234
+ const changeSetAdapter2 = adapter1.changeSet("Draft/123");
1235
+ expect2(() => changeSetAdapter2.createPost({ title: "Title 1" })).toThrow(BadRequestError);
1236
+ });
1237
+ test("duplicateDraft (txn.duplicateChangeSetMutations) produces an independent copy with remapped refs", async () => {
1238
+ const [post2] = await adapter1.createPost({
1239
+ title: "Title 1",
1240
+ slug: faker.lorem.slug(5)
1241
+ });
1242
+ const [sourceDraft] = await adapter1.createDraft({
1243
+ postRef: post2.ref
1244
+ });
1245
+ const sourceCs = adapter1.changeSet(sourceDraft.ref);
1246
+ const [{ block: row }] = await sourceCs.createBlockRow({
1247
+ parentRef: post2.ref
1248
+ });
1249
+ const [{ block: para }] = await sourceCs.createBlockParagraph({
1250
+ parentRef: row.ref,
1251
+ content: "Hello"
1252
+ });
1253
+ const [{ draftRef: newDraftRef, mutations, refMap }] = await adapter1.duplicateDraft({
1254
+ sourceRef: sourceDraft.ref,
1255
+ postRef: post2.ref
1256
+ });
1257
+ expect2(mutations).toHaveLength(2);
1258
+ const newRow = refMap.get(row.ref);
1259
+ const newPara = refMap.get(para.ref);
1260
+ expect2(newRow).toBeDefined();
1261
+ expect2(newPara).toBeDefined();
1262
+ expect2(newRow).not.toBe(row.ref);
1263
+ expect2(newPara).not.toBe(para.ref);
1264
+ expect2([...refMap.values()]).not.toContain(row.ref);
1265
+ expect2([...refMap.values()]).not.toContain(para.ref);
1266
+ const targetCs = adapter1.changeSet(newDraftRef);
1267
+ expect2((await targetCs.readEntity(newRow)).ref).toBe(newRow);
1268
+ expect2((await targetCs.readEntity(newPara)).parents.parent).toBe(newRow);
1269
+ expect2((await sourceCs.readEntity(para.ref)).parents.parent).toBe(row.ref);
1270
+ });
1271
+ test("duplicateDraft when a source op reads the changeSet root (one-transaction, pending target root)", async () => {
1272
+ const [post2] = await adapter1.createPost({
1273
+ title: "Title 1",
1274
+ slug: faker.lorem.slug(5)
1275
+ });
1276
+ const [sourceDraft] = await adapter1.createDraft({
1277
+ postRef: post2.ref
1278
+ });
1279
+ await adapter1.changeSet(sourceDraft.ref).createBlockRowReadingRoot({ parentRef: post2.ref });
1280
+ const [{ draftRef: newDraftRef, mutations, refMap }] = await adapter1.duplicateDraft({
1281
+ sourceRef: sourceDraft.ref,
1282
+ postRef: post2.ref
1283
+ });
1284
+ expect2(mutations).toHaveLength(1);
1285
+ expect2(mutations[0].operation.name).toBe("createBlockRowReadingRoot");
1286
+ const newRow = [...refMap.values()][0];
1287
+ expect2(newRow).toBeDefined();
1288
+ const targetCs = adapter1.changeSet(newDraftRef);
1289
+ expect2((await targetCs.readEntity(newRow)).ref).toBe(newRow);
1290
+ });
1291
+ test("deleteBlocks (patch running 2 times removing on array element every time)", async () => {
1292
+ const [post2, createPostMutation] = await adapter1.createPost({
1293
+ title: "Title 1",
1294
+ slug: faker.lorem.slug(5),
1295
+ tags: ["Foo", "Bar"]
1296
+ });
1297
+ const [draft2, createDraftMutation] = await adapter1.createDraft({
1298
+ postRef: post2.ref
1299
+ });
1300
+ const changeSetAdapter2 = adapter1.changeSet(draft2.ref);
1301
+ const [{ block: blockParagraph12 }, createBlockParagraph1Mutation] = await changeSetAdapter2.createBlockParagraph({
1302
+ parentRef: post2.ref
1303
+ });
1304
+ const [{ block: blockParagraph22 }, createBlockParagraph2Mutation] = await changeSetAdapter2.createBlockParagraph({
1305
+ parentRef: post2.ref
1306
+ });
1307
+ const readPost2 = await changeSetAdapter2.readEntity(post2.ref);
1308
+ expect2(readPost2.children.blocks).toEqual([
1309
+ blockParagraph12.ref,
1310
+ blockParagraph22.ref
1311
+ ]);
1312
+ const [, deleteMutation] = await changeSetAdapter2.deleteBlocks([
1313
+ blockParagraph12.ref,
1314
+ blockParagraph22.ref
1315
+ ]);
1316
+ expect2(deleteMutation.log[0][2].children.blocks).toEqual([
1317
+ blockParagraph12.ref,
1318
+ blockParagraph22.ref
1319
+ ]);
1320
+ expect2(deleteMutation.log[0][2].updated.mutationRef).toBe(createBlockParagraph2Mutation.ref);
1321
+ const readPost22 = await changeSetAdapter2.readEntity(post2.ref);
1322
+ expect2(readPost22.updated.mutationRef).toEqual(deleteMutation.ref);
1323
+ });
1324
+ test("applyDraft", async () => {
1325
+ const { draftRef: draftRef2, post: post2, changeSetAdapter: changeSetAdapter2 } = await prepareChangeSetTest(adapter1);
1326
+ const [version, mutation] = await adapter1.applyDraft(draftRef2);
1327
+ expect2(() => changeSetAdapter2.createBlockImage({
1328
+ parentRef: post2.ref,
1329
+ url: "https://example.com/image.png"
1330
+ })).toThrowError(new RegExp(`changeSetRef .*${draftRef2}.* has already been applied`));
1331
+ });
1332
+ test("debounce does not collapse across changeSets (applied draft)", async () => {
1333
+ const [post2] = await adapter1.createPost({
1334
+ title: "Debounce repro",
1335
+ slug: faker.lorem.slug(5),
1336
+ tags: []
1337
+ });
1338
+ const [draft1] = await adapter1.createDraft({ postRef: post2.ref });
1339
+ const draft1adapter = adapter1.changeSet(draft1.ref);
1340
+ const [, mutation1] = await draft1adapter.updatePostDescription({
1341
+ ref: post2.ref,
1342
+ description: "From draft 1"
1343
+ });
1344
+ expect2(mutation1.changeSetRef).toBe(draft1.ref);
1345
+ await adapter1.applyDraft(draft1.ref);
1346
+ const [draft2] = await adapter1.createDraft({ postRef: post2.ref });
1347
+ const draft2adapter = adapter1.changeSet(draft2.ref);
1348
+ const [, mutation2] = await draft2adapter.updatePostDescription({
1349
+ ref: post2.ref,
1350
+ description: "From draft 2"
1351
+ });
1352
+ expect2(mutation2.ref).not.toBe(mutation1.ref);
1353
+ expect2(mutation2.changeSetRef).toBe(draft2.ref);
1354
+ });
1355
+ test("deleteDraft", async () => {
1356
+ const { draftRef: draftRef2 } = await prepareChangeSetTest(adapter1);
1357
+ const mutationsBefore = await adapter1.pageMutations({
1358
+ changeSetRef: draftRef2
1359
+ });
1360
+ const [, mutation] = await adapter1.deleteDraft(draftRef2);
1361
+ expect2(mutation.log).toHaveLength(mutationsBefore.length + 1);
1362
+ const mutationsAfter = await adapter1.pageMutations({
1363
+ changeSetRef: draftRef2
1364
+ });
1365
+ expect2(mutationsAfter).toHaveLength(0);
1366
+ });
1367
+ test("init adapter2", async () => {
1368
+ const adapterA = await createAdapter({ optimistic: true });
1369
+ const adapterB = await createAdapter({ optimistic: true });
1370
+ const { draftRef: draftRef2 } = await prepareChangeSetTest(adapterA, adapterB);
1371
+ const mutations = await adapterA.pageMutations({
1372
+ changeSetRef: draftRef2
1373
+ });
1374
+ const allMutationsAdapter1 = await adapterA.pageMutations({});
1375
+ const allMutationsAdapter2 = await adapterB.pageMutations({});
1376
+ expect2(allMutationsAdapter1).not.toBeEmpty();
1377
+ expect2(allMutationsAdapter2).toBeEmpty();
1378
+ const res = await adapterB.loadMutations(allMutationsAdapter1);
1379
+ const allMutationsAdapter2after = await adapterB.pageMutations({});
1380
+ expect2(allMutationsAdapter2after.length).toBe(allMutationsAdapter1.length);
1381
+ const res2 = await adapterB.loadMutations(allMutationsAdapter1);
1382
+ });
1383
+ test("persisted at", async () => {
1384
+ const adapterA = await createAdapter({ optimistic: false });
1385
+ const adapterB = await createAdapter({ optimistic: true });
1386
+ const [, mutationNonOptimistic] = await adapterA.createPost({
1387
+ title: "Foo"
1388
+ });
1389
+ expect2(mutationNonOptimistic.persistedAt).toBeDefined();
1390
+ expect2(mutationNonOptimistic.persistedAt).toBe(mutationNonOptimistic.timestamp);
1391
+ const [, mutationOptimistic] = await adapterB.createPost({
1392
+ title: "Foo"
1393
+ });
1394
+ expect2(mutationOptimistic.persistedAt).toBeNull();
1395
+ const [mutationOptimisticPersisted] = await adapterA.persistOptimisticMutations([mutationOptimistic]);
1396
+ expect2(mutationOptimisticPersisted.persistedAt).toBeString();
1397
+ });
1398
+ test("persistOptimisticMutations", async () => {
1399
+ const persistedAdapter = await createAdapter({ optimistic: false });
1400
+ const optimisticAdapter = await createAdapter({ optimistic: true });
1401
+ expect2(persistedAdapter.persistOptimisticMutations).toBeDefined();
1402
+ expect2(optimisticAdapter.loadMutations).toBeDefined();
1403
+ const [post2, createPostMutation] = await optimisticAdapter.createPost({
1404
+ title: "Foo",
1405
+ slug: faker.lorem.slug(5),
1406
+ tags: []
1407
+ });
1408
+ const [persistCratePostMutation] = await persistedAdapter.persistOptimisticMutations([
1409
+ createPostMutation
1410
+ ]);
1411
+ expect2(persistCratePostMutation.persistedAt >= createPostMutation.timestamp).toBeTrue();
1412
+ const readMutation2 = await persistedAdapter.readMutation(persistCratePostMutation.ref);
1413
+ expect2(readMutation2).toStrictEqual(persistCratePostMutation);
1414
+ const [draft2, { persistedAt: ignore, ...createDraftMutation }] = await optimisticAdapter.createDraft({
1415
+ postRef: post2.ref
1416
+ });
1417
+ const [{ persistedAt, ...persistedCreateDraftMutation }] = await persistedAdapter.persistOptimisticMutations([
1418
+ createDraftMutation
1419
+ ]);
1420
+ expect2(persistedCreateDraftMutation).toStrictEqual(createDraftMutation);
1421
+ const changeSetAdapter2 = optimisticAdapter.changeSet(draft2.ref);
1422
+ const [res] = await changeSetAdapter2.createBlockParagraph({
1423
+ parentRef: post2.ref
1424
+ });
1425
+ });
1426
+ });
500
1427
  };
501
1428
  // src/inMemoryAdapter.ts
502
1429
  import { createInMemoryAdapter } from "@roc-db/in-memory";
503
1430
  var inMemoryAdapter = createInMemoryAdapter({
504
1431
  operations,
505
- entities
1432
+ entities,
1433
+ session: {
1434
+ identityRef: "User/42"
1435
+ }
506
1436
  });
507
1437
  export {
508
1438
  testAdapterImplementation,