jazz-tools 0.13.31 → 0.14.1

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 (166) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +22 -3
  3. package/dist/auth/DemoAuth.d.ts.map +1 -1
  4. package/dist/auth/PassphraseAuth.d.ts +1 -3
  5. package/dist/auth/PassphraseAuth.d.ts.map +1 -1
  6. package/dist/{chunk-IJU4XPFS.js → chunk-WLOZKDOH.js} +3536 -3291
  7. package/dist/chunk-WLOZKDOH.js.map +1 -0
  8. package/dist/coValues/CoValueBase.d.ts +22 -0
  9. package/dist/coValues/CoValueBase.d.ts.map +1 -0
  10. package/dist/coValues/account.d.ts +12 -12
  11. package/dist/coValues/account.d.ts.map +1 -1
  12. package/dist/coValues/coFeed.d.ts +24 -25
  13. package/dist/coValues/coFeed.d.ts.map +1 -1
  14. package/dist/coValues/coList.d.ts +10 -13
  15. package/dist/coValues/coList.d.ts.map +1 -1
  16. package/dist/coValues/coMap.d.ts +32 -35
  17. package/dist/coValues/coMap.d.ts.map +1 -1
  18. package/dist/coValues/coPlainText.d.ts.map +1 -1
  19. package/dist/coValues/deepLoading.d.ts +17 -21
  20. package/dist/coValues/deepLoading.d.ts.map +1 -1
  21. package/dist/coValues/extensions/imageDef.d.ts +12 -11
  22. package/dist/coValues/extensions/imageDef.d.ts.map +1 -1
  23. package/dist/coValues/group.d.ts +5 -9
  24. package/dist/coValues/group.d.ts.map +1 -1
  25. package/dist/coValues/inbox.d.ts +2 -3
  26. package/dist/coValues/inbox.d.ts.map +1 -1
  27. package/dist/coValues/interfaces.d.ts +8 -34
  28. package/dist/coValues/interfaces.d.ts.map +1 -1
  29. package/dist/coValues/profile.d.ts +4 -14
  30. package/dist/coValues/profile.d.ts.map +1 -1
  31. package/dist/coValues/registeredSchemas.d.ts +1 -3
  32. package/dist/coValues/registeredSchemas.d.ts.map +1 -1
  33. package/dist/coValues/schemaUnion.d.ts +6 -6
  34. package/dist/exports.d.ts +12 -16
  35. package/dist/exports.d.ts.map +1 -1
  36. package/dist/implementation/ContextManager.d.ts +1 -1
  37. package/dist/implementation/ContextManager.d.ts.map +1 -1
  38. package/dist/implementation/activeAccountContext.d.ts +1 -1
  39. package/dist/implementation/activeAccountContext.d.ts.map +1 -1
  40. package/dist/implementation/createContext.d.ts +10 -10
  41. package/dist/implementation/createContext.d.ts.map +1 -1
  42. package/dist/implementation/invites.d.ts +6 -6
  43. package/dist/implementation/invites.d.ts.map +1 -1
  44. package/dist/implementation/refs.d.ts +2 -2
  45. package/dist/implementation/refs.d.ts.map +1 -1
  46. package/dist/implementation/schema.d.ts +21 -28
  47. package/dist/implementation/schema.d.ts.map +1 -1
  48. package/dist/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.d.ts +9 -0
  49. package/dist/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.d.ts.map +1 -0
  50. package/dist/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.d.ts +28 -0
  51. package/dist/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.d.ts.map +1 -0
  52. package/dist/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +65 -0
  53. package/dist/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -0
  54. package/dist/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +28 -0
  55. package/dist/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -0
  56. package/dist/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +24 -0
  57. package/dist/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -0
  58. package/dist/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +41 -0
  59. package/dist/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -0
  60. package/dist/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +35 -0
  61. package/dist/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -0
  62. package/dist/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +9 -0
  63. package/dist/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -0
  64. package/dist/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +20 -0
  65. package/dist/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -0
  66. package/dist/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +18 -0
  67. package/dist/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -0
  68. package/dist/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +24 -0
  69. package/dist/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -0
  70. package/dist/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +21 -0
  71. package/dist/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +1 -0
  72. package/dist/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts +29 -0
  73. package/dist/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts.map +1 -0
  74. package/dist/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts +29 -0
  75. package/dist/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts.map +1 -0
  76. package/dist/implementation/zodSchema/unionUtils.d.ts +6 -0
  77. package/dist/implementation/zodSchema/unionUtils.d.ts.map +1 -0
  78. package/dist/implementation/zodSchema/zodCo.d.ts +35 -0
  79. package/dist/implementation/zodSchema/zodCo.d.ts.map +1 -0
  80. package/dist/implementation/zodSchema/zodSchema.d.ts +38 -0
  81. package/dist/implementation/zodSchema/zodSchema.d.ts.map +1 -0
  82. package/dist/index.js +295 -10
  83. package/dist/index.js.map +1 -1
  84. package/dist/internal.d.ts +34 -0
  85. package/dist/internal.d.ts.map +1 -1
  86. package/dist/subscribe/SubscriptionScope.d.ts +1 -2
  87. package/dist/subscribe/SubscriptionScope.d.ts.map +1 -1
  88. package/dist/subscribe/utils.d.ts +2 -2
  89. package/dist/subscribe/utils.d.ts.map +1 -1
  90. package/dist/testing.d.ts +10 -8
  91. package/dist/testing.d.ts.map +1 -1
  92. package/dist/testing.js +1 -1
  93. package/dist/testing.js.map +1 -1
  94. package/dist/tests/utils.d.ts +6 -2
  95. package/dist/tests/utils.d.ts.map +1 -1
  96. package/dist/types.d.ts +1 -7
  97. package/dist/types.d.ts.map +1 -1
  98. package/package.json +3 -2
  99. package/src/auth/DemoAuth.ts +1 -2
  100. package/src/auth/PassphraseAuth.ts +1 -1
  101. package/src/coValues/CoValueBase.ts +88 -0
  102. package/src/coValues/account.ts +53 -43
  103. package/src/coValues/coFeed.ts +65 -83
  104. package/src/coValues/coList.ts +28 -21
  105. package/src/coValues/coMap.ts +54 -38
  106. package/src/coValues/coPlainText.ts +4 -1
  107. package/src/coValues/deepLoading.ts +35 -43
  108. package/src/coValues/extensions/imageDef.ts +21 -19
  109. package/src/coValues/group.ts +37 -38
  110. package/src/coValues/inbox.ts +24 -11
  111. package/src/coValues/interfaces.ts +29 -93
  112. package/src/coValues/profile.ts +12 -13
  113. package/src/coValues/registeredSchemas.ts +1 -3
  114. package/src/coValues/schemaUnion.ts +6 -6
  115. package/src/exports.ts +47 -25
  116. package/src/implementation/activeAccountContext.ts +1 -1
  117. package/src/implementation/createContext.ts +39 -24
  118. package/src/implementation/invites.ts +15 -12
  119. package/src/implementation/refs.ts +6 -4
  120. package/src/implementation/schema.ts +22 -34
  121. package/src/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.ts +101 -0
  122. package/src/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.ts +191 -0
  123. package/src/implementation/zodSchema/schemaTypes/AccountSchema.ts +102 -0
  124. package/src/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +70 -0
  125. package/src/implementation/zodSchema/schemaTypes/CoListSchema.ts +59 -0
  126. package/src/implementation/zodSchema/schemaTypes/CoMapSchema.ts +126 -0
  127. package/src/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +98 -0
  128. package/src/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +9 -0
  129. package/src/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +27 -0
  130. package/src/implementation/zodSchema/schemaTypes/RichTextSchema.ts +25 -0
  131. package/src/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +61 -0
  132. package/src/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.ts +77 -0
  133. package/src/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.ts +90 -0
  134. package/src/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.ts +103 -0
  135. package/src/implementation/zodSchema/unionUtils.ts +139 -0
  136. package/src/implementation/zodSchema/zodCo.ts +409 -0
  137. package/src/implementation/zodSchema/zodSchema.ts +116 -0
  138. package/src/internal.ts +38 -0
  139. package/src/subscribe/SubscriptionScope.ts +3 -1
  140. package/src/subscribe/utils.ts +7 -2
  141. package/src/testing.ts +14 -16
  142. package/src/tests/ContextManager.test.ts +73 -47
  143. package/src/tests/DemoAuth.test.ts +1 -1
  144. package/src/tests/account.test.ts +6 -9
  145. package/src/tests/coFeed.test.ts +102 -63
  146. package/src/tests/coList.test.ts +82 -95
  147. package/src/tests/coMap.record.test.ts +53 -87
  148. package/src/tests/coMap.test.ts +297 -312
  149. package/src/tests/coPlainText.test.ts +19 -39
  150. package/src/tests/createContext.test.ts +33 -15
  151. package/src/tests/deepLoading.test.ts +196 -179
  152. package/src/tests/groupsAndAccounts.test.ts +81 -72
  153. package/src/tests/imageDef.test.ts +22 -13
  154. package/src/tests/inbox.test.ts +36 -29
  155. package/src/tests/load.test.ts +10 -10
  156. package/src/tests/patterns/requestToJoin.test.ts +31 -31
  157. package/src/tests/schema.test.ts +37 -38
  158. package/src/tests/schemaUnion.test.ts +54 -64
  159. package/src/tests/subscribe.test.ts +118 -116
  160. package/src/tests/testing.test.ts +33 -33
  161. package/src/tests/utils.ts +3 -2
  162. package/src/types.ts +1 -8
  163. package/dist/chunk-IJU4XPFS.js.map +0 -1
  164. package/dist/tests/deepLoading.test-d.d.ts +0 -2
  165. package/dist/tests/deepLoading.test-d.d.ts.map +0 -1
  166. package/src/tests/deepLoading.test-d.ts +0 -393
@@ -1,7 +1,7 @@
1
1
  import { WasmCrypto } from "cojson/crypto/WasmCrypto";
2
2
  import { assert, beforeEach, describe, expect, test } from "vitest";
3
- import { Account, CoMap, Group, Profile, co } from "../exports.js";
4
- import { Ref } from "../internal.js";
3
+ import { Account, CoMap, Group, Profile, coField, z } from "../exports.js";
4
+ import { Loaded, Ref, co, zodSchemaToCoSchema } from "../internal.js";
5
5
  import { createJazzTestAccount, setupJazzTestSync } from "../testing.js";
6
6
  import { setupTwoNodes, waitFor } from "./utils.js";
7
7
 
@@ -17,31 +17,37 @@ beforeEach(async () => {
17
17
 
18
18
  describe("Custom accounts and groups", async () => {
19
19
  test("Custom account and group", async () => {
20
- class CustomProfile extends Profile {
21
- name = co.string;
22
- color = co.string;
23
- }
24
-
25
- class CustomAccount extends Account {
26
- profile = co.ref(CustomProfile);
27
- root = co.ref(CoMap);
28
-
29
- migrate(this: CustomAccount, creationProps?: { name: string }) {
30
- if (creationProps) {
31
- const profileGroup = Group.create({ owner: this });
32
- profileGroup.addMember("everyone", "reader");
33
- this.profile = CustomProfile.create(
34
- { name: creationProps.name, color: "blue" },
35
- profileGroup,
36
- );
37
- }
38
- }
39
- }
20
+ const CustomProfile = co.profile({
21
+ name: z.string(),
22
+ color: z.string(),
23
+ });
24
+
25
+ const CustomAccount = co
26
+ .account({
27
+ profile: CustomProfile,
28
+ root: co.map({}),
29
+ })
30
+ .withMigration(
31
+ (
32
+ account: Loaded<typeof CustomAccount>,
33
+ creationProps?: { name: string },
34
+ ) => {
35
+ if (creationProps) {
36
+ console.log("In migration!");
37
+ const profileGroup = Group.create({ owner: account });
38
+ profileGroup.addMember("everyone", "reader");
39
+ account.profile = CustomProfile.create(
40
+ { name: creationProps.name, color: "blue" },
41
+ profileGroup,
42
+ );
43
+ }
44
+ },
45
+ );
40
46
 
41
47
  const me = await createJazzTestAccount({
42
48
  creationProps: { name: "Hermes Puggington" },
43
49
  isCurrentActiveAccount: true,
44
- AccountSchema: CustomAccount,
50
+ AccountSchema: zodSchemaToCoSchema(CustomAccount),
45
51
  });
46
52
 
47
53
  expect(me.profile).toBeDefined();
@@ -54,41 +60,44 @@ describe("Custom accounts and groups", async () => {
54
60
  expect(group.members).toMatchObject([{ id: me.id, role: "admin" }]);
55
61
 
56
62
  const meAsMember = group.members.find((member) => member.id === me.id);
57
- expect((meAsMember?.account as CustomAccount).profile?.name).toBe(
58
- "Hermes Puggington",
59
- );
60
- expect((meAsMember?.account as CustomAccount).profile?.color).toBe("blue");
63
+ assert(meAsMember?.account);
64
+ expect((meAsMember?.account).profile?.name).toBe("Hermes Puggington");
61
65
  });
62
66
 
63
67
  test("Should throw when creating a profile with an account as owner", async () => {
64
- class CustomAccount extends Account {
65
- migrate(this: CustomAccount, creationProps?: { name: string }) {
66
- if (creationProps) {
67
- this.profile = Profile.create(
68
- { name: creationProps.name },
69
- // @ts-expect-error - only groups can own profiles, but we want to also perform a runtime check
70
- this,
71
- );
72
- }
73
- }
74
- }
68
+ const CustomAccount = co
69
+ .account()
70
+ .withMigration(
71
+ (
72
+ account: Loaded<typeof CustomAccount>,
73
+ creationProps?: { name: string },
74
+ ) => {
75
+ if (creationProps) {
76
+ account.profile = co.profile().create(
77
+ { name: creationProps.name },
78
+ // @ts-expect-error - only groups can own profiles, but we want to also perform a runtime check
79
+ account,
80
+ );
81
+ }
82
+ },
83
+ );
75
84
 
76
85
  await expect(() =>
77
86
  CustomAccount.create({
78
87
  creationProps: { name: "Hermes Puggington" },
79
88
  crypto: Crypto,
80
89
  }),
81
- ).rejects.toThrowError("Profiles should be owned by a group");
90
+ ).rejects.toThrowError("Profile must be owned by a Group");
82
91
  });
83
92
  });
84
93
 
85
94
  describe("Group inheritance", () => {
86
- class TestMap extends CoMap {
87
- title = co.string;
88
- }
95
+ const TestMap = co.map({
96
+ title: z.string(),
97
+ });
89
98
 
90
99
  test("Group inheritance", async () => {
91
- const me = await Account.create({
100
+ const me = await co.account().create({
92
101
  creationProps: { name: "Hermes Puggington" },
93
102
  crypto: Crypto,
94
103
  });
@@ -98,7 +107,7 @@ describe("Group inheritance", () => {
98
107
 
99
108
  group.extend(parentGroup);
100
109
 
101
- const reader = await Account.createAs(me, {
110
+ const reader = await co.account().createAs(me, {
102
111
  creationProps: { name: "Reader" },
103
112
  });
104
113
 
@@ -122,7 +131,7 @@ describe("Group inheritance", () => {
122
131
  });
123
132
 
124
133
  test("Group inheritance with grand-children", async () => {
125
- const me = await Account.create({
134
+ const me = await co.account().create({
126
135
  creationProps: { name: "Hermes Puggington" },
127
136
  crypto: Crypto,
128
137
  });
@@ -134,7 +143,7 @@ describe("Group inheritance", () => {
134
143
  group.extend(parentGroup);
135
144
  parentGroup.extend(grandParentGroup);
136
145
 
137
- const reader = await Account.createAs(me, {
146
+ const reader = await co.account().createAs(me, {
138
147
  creationProps: { name: "Reader" },
139
148
  });
140
149
 
@@ -163,7 +172,7 @@ describe("Group inheritance", () => {
163
172
  });
164
173
 
165
174
  test("Group.getParentGroups should return the parent groups", async () => {
166
- const me = await Account.create({
175
+ const me = await co.account().create({
167
176
  creationProps: { name: "Test Owner" },
168
177
  crypto: Crypto,
169
178
  });
@@ -188,7 +197,7 @@ describe("Group inheritance", () => {
188
197
  });
189
198
 
190
199
  test("Account.getParentGroups should return an empty array", async () => {
191
- const account = await Account.create({
200
+ const account = await co.account().create({
192
201
  creationProps: { name: "Test Account" },
193
202
  crypto: Crypto,
194
203
  });
@@ -313,7 +322,7 @@ describe("Group.getRoleOf with 'me' parameter", () => {
313
322
  await account.waitForAllCoValuesSync();
314
323
  const group = Group.create({ owner: account });
315
324
 
316
- group.addMember(Account.getMe(), "writer");
325
+ group.addMember(co.account().getMe(), "writer");
317
326
 
318
327
  expect(group.getRoleOf("me")).toBe("writer");
319
328
  });
@@ -323,7 +332,7 @@ describe("Group.getRoleOf with 'me' parameter", () => {
323
332
  await account.waitForAllCoValuesSync();
324
333
  const group = Group.create({ owner: account });
325
334
 
326
- group.addMember(Account.getMe(), "reader");
335
+ group.addMember(co.account().getMe(), "reader");
327
336
 
328
337
  expect(group.getRoleOf("me")).toBe("reader");
329
338
  });
@@ -343,7 +352,7 @@ describe("Account permissions", () => {
343
352
  });
344
353
 
345
354
  test("getRoleOf returns admin only for self and me", async () => {
346
- const account = await Account.create({
355
+ const account = await co.account().create({
347
356
  creationProps: { name: "Test Account" },
348
357
  crypto: Crypto,
349
358
  });
@@ -353,10 +362,10 @@ describe("Account permissions", () => {
353
362
 
354
363
  // The GlobalMe is not this account
355
364
  expect(account.getRoleOf("me")).toBe(undefined);
356
- expect(Account.getMe().getRoleOf("me")).toBe("admin");
365
+ expect(co.account().getMe().getRoleOf("me")).toBe("admin");
357
366
 
358
367
  // Other accounts should have no role
359
- const otherAccount = await Account.create({
368
+ const otherAccount = await co.account().create({
360
369
  creationProps: { name: "Other Account" },
361
370
  crypto: Crypto,
362
371
  });
@@ -367,7 +376,7 @@ describe("Account permissions", () => {
367
376
  });
368
377
 
369
378
  test("members array only contains self as admin", async () => {
370
- const account = await Account.create({
379
+ const account = await co.account().create({
371
380
  creationProps: { name: "Test Account" },
372
381
  crypto: Crypto,
373
382
  });
@@ -381,7 +390,7 @@ describe("Account permissions", () => {
381
390
  describe("Account permissions", () => {
382
391
  test("canRead permissions for different roles", async () => {
383
392
  // Create test accounts
384
- const admin = await Account.create({
393
+ const admin = await co.account().create({
385
394
  creationProps: { name: "Admin" },
386
395
  crypto: Crypto,
387
396
  });
@@ -389,13 +398,13 @@ describe("Account permissions", () => {
389
398
  const group = Group.create({ owner: admin });
390
399
  const testObject = CoMap.create({}, { owner: group });
391
400
 
392
- const writer = await Account.createAs(admin, {
401
+ const writer = await co.account().createAs(admin, {
393
402
  creationProps: { name: "Writer" },
394
403
  });
395
- const reader = await Account.createAs(admin, {
404
+ const reader = await co.account().createAs(admin, {
396
405
  creationProps: { name: "Reader" },
397
406
  });
398
- const writeOnly = await Account.createAs(admin, {
407
+ const writeOnly = await co.account().createAs(admin, {
399
408
  creationProps: { name: "WriteOnly" },
400
409
  });
401
410
 
@@ -413,7 +422,7 @@ describe("Account permissions", () => {
413
422
 
414
423
  test("canWrite permissions for different roles", async () => {
415
424
  // Create test accounts
416
- const admin = await Account.create({
425
+ const admin = await co.account().create({
417
426
  creationProps: { name: "Admin" },
418
427
  crypto: Crypto,
419
428
  });
@@ -421,13 +430,13 @@ describe("Account permissions", () => {
421
430
  const group = Group.create({ owner: admin });
422
431
  const testObject = CoMap.create({}, { owner: group });
423
432
 
424
- const writer = await Account.createAs(admin, {
433
+ const writer = await co.account().createAs(admin, {
425
434
  creationProps: { name: "Writer" },
426
435
  });
427
- const reader = await Account.createAs(admin, {
436
+ const reader = await co.account().createAs(admin, {
428
437
  creationProps: { name: "Reader" },
429
438
  });
430
- const writeOnly = await Account.createAs(admin, {
439
+ const writeOnly = await co.account().createAs(admin, {
431
440
  creationProps: { name: "WriteOnly" },
432
441
  });
433
442
 
@@ -445,7 +454,7 @@ describe("Account permissions", () => {
445
454
 
446
455
  test("canAdmin permissions for different roles", async () => {
447
456
  // Create test accounts
448
- const admin = await Account.create({
457
+ const admin = await co.account().create({
449
458
  creationProps: { name: "Admin" },
450
459
  crypto: Crypto,
451
460
  });
@@ -453,13 +462,13 @@ describe("Account permissions", () => {
453
462
  const group = Group.create({ owner: admin });
454
463
  const testObject = CoMap.create({}, { owner: group });
455
464
 
456
- const writer = await Account.createAs(admin, {
465
+ const writer = await co.account().createAs(admin, {
457
466
  creationProps: { name: "Writer" },
458
467
  });
459
- const reader = await Account.createAs(admin, {
468
+ const reader = await co.account().createAs(admin, {
460
469
  creationProps: { name: "Reader" },
461
470
  });
462
- const writeOnly = await Account.createAs(admin, {
471
+ const writeOnly = await co.account().createAs(admin, {
463
472
  creationProps: { name: "WriteOnly" },
464
473
  });
465
474
 
@@ -476,7 +485,7 @@ describe("Account permissions", () => {
476
485
  });
477
486
 
478
487
  test("permissions for non-members", async () => {
479
- const admin = await Account.create({
488
+ const admin = await co.account().create({
480
489
  creationProps: { name: "Admin" },
481
490
  crypto: Crypto,
482
491
  });
@@ -484,7 +493,7 @@ describe("Account permissions", () => {
484
493
  const group = Group.create({ owner: admin });
485
494
  const testObject = CoMap.create({}, { owner: group });
486
495
 
487
- const nonMember = await Account.createAs(admin, {
496
+ const nonMember = await co.account().createAs(admin, {
488
497
  creationProps: { name: "NonMember" },
489
498
  });
490
499
 
@@ -508,7 +517,7 @@ describe("Group.members", () => {
508
517
  expect(childGroup.members).toEqual([
509
518
  expect.objectContaining({
510
519
  account: expect.objectContaining({
511
- id: Account.getMe().id,
520
+ id: co.account().getMe().id,
512
521
  }),
513
522
  role: "admin",
514
523
  }),
@@ -536,7 +545,7 @@ describe("Group.members", () => {
536
545
  expect(childGroup.members).toEqual([
537
546
  expect.objectContaining({
538
547
  account: expect.objectContaining({
539
- id: Account.getMe().id,
548
+ id: co.account().getMe().id,
540
549
  }),
541
550
  role: "admin",
542
551
  }),
@@ -558,7 +567,7 @@ describe("Group.members", () => {
558
567
  expect(childGroup.members).toEqual([
559
568
  expect.objectContaining({
560
569
  account: expect.objectContaining({
561
- id: Account.getMe().id,
570
+ id: co.account().getMe().id,
562
571
  }),
563
572
  role: "admin",
564
573
  }),
@@ -579,7 +588,7 @@ describe("Group.members", () => {
579
588
  expect(childGroup.members).toEqual([
580
589
  expect.objectContaining({
581
590
  account: expect.objectContaining({
582
- id: Account.getMe().id,
591
+ id: co.account().getMe().id,
583
592
  }),
584
593
  role: "admin",
585
594
  }),
@@ -1,6 +1,6 @@
1
1
  import { WasmCrypto } from "cojson/crypto/WasmCrypto";
2
2
  import { describe, expect, test } from "vitest";
3
- import { Account, FileStream, ImageDefinition, co } from "../exports.js";
3
+ import { Account, FileStream, ImageDefinition } from "../exports.js";
4
4
 
5
5
  const Crypto = await WasmCrypto.create();
6
6
 
@@ -31,7 +31,7 @@ describe("ImageDefinition", async () => {
31
31
  { owner: me },
32
32
  );
33
33
 
34
- const result = imageDef.highestResAvailable();
34
+ const result = ImageDefinition.highestResAvailable(imageDef);
35
35
  expect(result).toBeUndefined();
36
36
  });
37
37
 
@@ -50,7 +50,7 @@ describe("ImageDefinition", async () => {
50
50
 
51
51
  imageDef["1920x1080"] = stream;
52
52
 
53
- const result = imageDef.highestResAvailable();
53
+ const result = ImageDefinition.highestResAvailable(imageDef);
54
54
  expect(result).toBeDefined();
55
55
  expect(result?.res).toBe("1920x1080");
56
56
  expect(result?.stream).toStrictEqual(stream);
@@ -77,7 +77,7 @@ describe("ImageDefinition", async () => {
77
77
  imageDef["1920x1080"] = stream1;
78
78
  imageDef["1280x720"] = stream2;
79
79
 
80
- const result = imageDef.highestResAvailable();
80
+ const result = ImageDefinition.highestResAvailable(imageDef);
81
81
  expect(result).toBeDefined();
82
82
  expect(result?.res).toBe("1920x1080");
83
83
  expect(result?.stream).toStrictEqual(stream1);
@@ -104,7 +104,9 @@ describe("ImageDefinition", async () => {
104
104
  imageDef["1920x1080"] = stream1;
105
105
  imageDef["1280x720"] = stream2;
106
106
 
107
- const result = imageDef.highestResAvailable({ maxWidth: 1500 });
107
+ const result = ImageDefinition.highestResAvailable(imageDef, {
108
+ maxWidth: 1500,
109
+ });
108
110
  expect(result).toBeDefined();
109
111
  expect(result?.res).toBe("1280x720");
110
112
  expect(result?.stream).toStrictEqual(stream2);
@@ -130,7 +132,7 @@ describe("ImageDefinition", async () => {
130
132
  imageDef["1920x1080"] = stream1;
131
133
  imageDef["1280x720"] = stream2;
132
134
 
133
- const result = imageDef.highestResAvailable();
135
+ const result = ImageDefinition.highestResAvailable(imageDef);
134
136
  expect(result).toBeDefined();
135
137
  expect(result?.res).toBe("1920x1080");
136
138
  expect(result?.stream).toStrictEqual(stream1);
@@ -162,7 +164,7 @@ describe("ImageDefinition", async () => {
162
164
  imageDef["1280x720"] = stream2;
163
165
  imageDef["1024x576"] = stream3;
164
166
 
165
- const result = imageDef.highestResAvailable();
167
+ const result = ImageDefinition.highestResAvailable(imageDef);
166
168
  expect(result).toBeDefined();
167
169
  expect(result?.res).toBe("1920x1080");
168
170
  expect(result?.stream).toStrictEqual(stream1);
@@ -181,10 +183,9 @@ describe("ImageDefinition", async () => {
181
183
  stream.push(new Uint8Array([1, 2, 3]));
182
184
  stream.end();
183
185
 
184
- // @ts-expect-error - Testing invalid key
185
186
  imageDef["invalid-key"] = stream;
186
187
 
187
- const result = imageDef.highestResAvailable();
188
+ const result = ImageDefinition.highestResAvailable(imageDef);
188
189
  expect(result).toBeUndefined();
189
190
  });
190
191
 
@@ -216,19 +217,25 @@ describe("ImageDefinition", async () => {
216
217
  imageDef["800x450"] = stream3;
217
218
 
218
219
  // Should return 1280x720 as it's the smallest resolution >= 1000px
219
- const result1 = imageDef.highestResAvailable({ targetWidth: 1000 });
220
+ const result1 = ImageDefinition.highestResAvailable(imageDef, {
221
+ targetWidth: 1000,
222
+ });
220
223
  expect(result1).toBeDefined();
221
224
  expect(result1?.res).toBe("1280x720");
222
225
  expect(result1?.stream).toStrictEqual(stream2);
223
226
 
224
227
  // Should return 800x450 as it's the smallest resolution >= 700px
225
- const result2 = imageDef.highestResAvailable({ targetWidth: 700 });
228
+ const result2 = ImageDefinition.highestResAvailable(imageDef, {
229
+ targetWidth: 700,
230
+ });
226
231
  expect(result2).toBeDefined();
227
232
  expect(result2?.res).toBe("800x450");
228
233
  expect(result2?.stream).toStrictEqual(stream3);
229
234
 
230
235
  // Should return 1920x1080 as it's the smallest resolution >= 1500px
231
- const result3 = imageDef.highestResAvailable({ targetWidth: 1500 });
236
+ const result3 = ImageDefinition.highestResAvailable(imageDef, {
237
+ targetWidth: 1500,
238
+ });
232
239
  expect(result3).toBeDefined();
233
240
  expect(result3?.res).toBe("1920x1080");
234
241
  expect(result3?.stream).toStrictEqual(stream1);
@@ -261,7 +268,9 @@ describe("ImageDefinition", async () => {
261
268
  imageDef["800x450"] = stream3;
262
269
 
263
270
  // Should skip 1280x720 as it's incomplete and return 1920x1080
264
- const result = imageDef.highestResAvailable({ targetWidth: 1000 });
271
+ const result = ImageDefinition.highestResAvailable(imageDef, {
272
+ targetWidth: 1000,
273
+ });
265
274
  expect(result).toBeDefined();
266
275
  expect(result?.res).toBe("800x450");
267
276
  expect(result?.stream).toStrictEqual(stream1);
@@ -1,31 +1,32 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
- import { Account } from "../coValues/account";
3
- import { CoMap } from "../coValues/coMap";
4
- import { Group } from "../coValues/group";
5
- import { Inbox, InboxSender } from "../coValues/inbox";
6
- import { Profile } from "../exports";
7
- import { co } from "../internal";
2
+ import {
3
+ Account,
4
+ CoMap,
5
+ Group,
6
+ Inbox,
7
+ InboxSender,
8
+ Profile,
9
+ z,
10
+ } from "../exports";
11
+ import { Loaded, co, coField, zodSchemaToCoSchema } from "../internal";
8
12
  import { setupTwoNodes, waitFor } from "./utils";
9
13
 
10
- class Message extends CoMap {
11
- text = co.string;
12
- }
14
+ const Message = co.map({
15
+ text: z.string(),
16
+ });
13
17
 
14
18
  describe("Inbox", () => {
15
19
  describe("Private profile", () => {
16
20
  it("Should throw if the inbox owner profile is private", async () => {
17
- class WorkerAccount extends Account {
18
- migrate() {
19
- this.profile = Profile.create(
20
- { name: "Worker" },
21
- Group.create({ owner: this }),
22
- );
23
- }
24
- }
21
+ const WorkerAccount = co.account().withMigration((account) => {
22
+ account.profile = co
23
+ .profile()
24
+ .create({ name: "Worker" }, Group.create({ owner: account }));
25
+ });
25
26
 
26
27
  const { clientAccount: sender, serverAccount: receiver } =
27
28
  await setupTwoNodes({
28
- ServerAccountSchema: WorkerAccount,
29
+ ServerAccountSchema: zodSchemaToCoSchema(WorkerAccount),
29
30
  });
30
31
 
31
32
  await expect(() => InboxSender.load(receiver.id, sender)).rejects.toThrow(
@@ -53,7 +54,7 @@ describe("Inbox", () => {
53
54
  inboxSender.sendMessage(message);
54
55
 
55
56
  // Track received messages
56
- const receivedMessages: Message[] = [];
57
+ const receivedMessages: Loaded<typeof Message>[] = [];
57
58
  let senderAccountID: unknown = undefined;
58
59
 
59
60
  // Subscribe to inbox messages
@@ -79,7 +80,7 @@ describe("Inbox", () => {
79
80
  const { clientAccount: sender, serverAccount: receiver } =
80
81
  await setupTwoNodes();
81
82
 
82
- class EmptyMessage extends CoMap {}
83
+ const EmptyMessage = co.map({});
83
84
 
84
85
  const receiverInbox = await Inbox.load(receiver);
85
86
 
@@ -96,7 +97,7 @@ describe("Inbox", () => {
96
97
  inboxSender.sendMessage(message);
97
98
 
98
99
  // Track received messages
99
- const receivedMessages: EmptyMessage[] = [];
100
+ const receivedMessages: Loaded<typeof EmptyMessage>[] = [];
100
101
  let senderAccountID: unknown = undefined;
101
102
 
102
103
  // Subscribe to inbox messages
@@ -140,10 +141,10 @@ describe("Inbox", () => {
140
141
  });
141
142
 
142
143
  // Setup inbox sender
143
- const inboxSender = await InboxSender.load<Message, Message>(
144
- receiver.id,
145
- sender,
146
- );
144
+ const inboxSender = await InboxSender.load<
145
+ Loaded<typeof Message>,
146
+ Loaded<typeof Message>
147
+ >(receiver.id, sender);
147
148
  const resultId = await inboxSender.sendMessage(message);
148
149
 
149
150
  const result = await Message.load(resultId, { loadAs: receiver });
@@ -169,7 +170,10 @@ describe("Inbox", () => {
169
170
  const unsubscribe = receiverInbox.subscribe(Message, async (message) => {});
170
171
 
171
172
  // Setup inbox sender
172
- const inboxSender = await InboxSender.load<Message>(receiver.id, sender);
173
+ const inboxSender = await InboxSender.load<Loaded<typeof Message>>(
174
+ receiver.id,
175
+ sender,
176
+ );
173
177
  const result = await inboxSender.sendMessage(message);
174
178
 
175
179
  expect(result).toBeUndefined();
@@ -198,7 +202,10 @@ describe("Inbox", () => {
198
202
  });
199
203
 
200
204
  // Setup inbox sender
201
- const inboxSender = await InboxSender.load<Message>(receiver.id, sender);
205
+ const inboxSender = await InboxSender.load<Loaded<typeof Message>>(
206
+ receiver.id,
207
+ sender,
208
+ );
202
209
 
203
210
  await expect(inboxSender.sendMessage(message)).rejects.toThrow(
204
211
  "Error: Failed",
@@ -233,7 +240,7 @@ describe("Inbox", () => {
233
240
  inboxSender.sendMessage(message);
234
241
 
235
242
  // Track received messages
236
- const receivedMessages: Message[] = [];
243
+ const receivedMessages: Loaded<typeof Message>[] = [];
237
244
 
238
245
  // Subscribe to inbox messages
239
246
  const unsubscribe = receiverInbox.subscribe(Message, async (message) => {
@@ -273,7 +280,7 @@ describe("Inbox", () => {
273
280
  inboxSender.sendMessage(message);
274
281
 
275
282
  // Track received messages
276
- const receivedMessages: Message[] = [];
283
+ const receivedMessages: Loaded<typeof Message>[] = [];
277
284
 
278
285
  // Subscribe to inbox messages
279
286
  const unsubscribe = receiverInbox.subscribe(Message, async (message) => {
@@ -1,6 +1,6 @@
1
1
  import { cojsonInternals } from "cojson";
2
2
  import { beforeEach, expect, test } from "vitest";
3
- import { Account, CoMap, Group, co } from "../exports.js";
3
+ import { Account, Group, co, z } from "../exports.js";
4
4
  import {
5
5
  createJazzTestAccount,
6
6
  getPeerConnectedToTestSyncServer,
@@ -15,9 +15,9 @@ beforeEach(async () => {
15
15
  });
16
16
 
17
17
  test("load a value", async () => {
18
- class Person extends CoMap {
19
- name = co.string;
20
- }
18
+ const Person = co.map({
19
+ name: z.string(),
20
+ });
21
21
 
22
22
  const group = Group.create();
23
23
  const map = Person.create({ name: "John" }, group);
@@ -31,9 +31,9 @@ test("load a value", async () => {
31
31
  });
32
32
 
33
33
  test("retry an unavailable a value", async () => {
34
- class Person extends CoMap {
35
- name = co.string;
36
- }
34
+ const Person = co.map({
35
+ name: z.string(),
36
+ });
37
37
 
38
38
  const currentAccount = Account.getMe();
39
39
 
@@ -74,9 +74,9 @@ test("retry an unavailable a value", async () => {
74
74
  });
75
75
 
76
76
  test("returns null if the value is unavailable after retries", async () => {
77
- class Person extends CoMap {
78
- name = co.string;
79
- }
77
+ const Person = co.map({
78
+ name: z.string(),
79
+ });
80
80
 
81
81
  const currentAccount = Account.getMe();
82
82