jazz-tools 0.15.16 → 0.16.0

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 (199) hide show
  1. package/.svelte-kit/__package__/jazz.class.svelte.d.ts +2 -2
  2. package/.svelte-kit/__package__/jazz.class.svelte.d.ts.map +1 -1
  3. package/.svelte-kit/__package__/jazz.class.svelte.js +5 -5
  4. package/.svelte-kit/__package__/jazz.svelte.d.ts +2 -2
  5. package/.svelte-kit/__package__/jazz.svelte.d.ts.map +1 -1
  6. package/.turbo/turbo-build.log +46 -46
  7. package/CHANGELOG.md +25 -0
  8. package/dist/browser/index.d.ts +2 -2
  9. package/dist/browser/index.d.ts.map +1 -1
  10. package/dist/browser/index.js.map +1 -1
  11. package/dist/browser-media-images/index.d.ts +3 -1
  12. package/dist/browser-media-images/index.d.ts.map +1 -1
  13. package/dist/browser-media-images/index.js.map +1 -1
  14. package/dist/{chunk-OSVAAVWQ.js → chunk-MLCNE3TL.js} +594 -598
  15. package/dist/chunk-MLCNE3TL.js.map +1 -0
  16. package/dist/index.js +8 -10
  17. package/dist/index.js.map +1 -1
  18. package/dist/react/hooks.d.ts +2 -2
  19. package/dist/react/hooks.d.ts.map +1 -1
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/react-core/hooks.d.ts +2 -2
  22. package/dist/react-core/hooks.d.ts.map +1 -1
  23. package/dist/react-core/index.js +3 -3
  24. package/dist/react-core/index.js.map +1 -1
  25. package/dist/react-native-core/hooks.d.ts +2 -2
  26. package/dist/react-native-core/hooks.d.ts.map +1 -1
  27. package/dist/react-native-core/index.js.map +1 -1
  28. package/dist/svelte/jazz.class.svelte.d.ts +2 -2
  29. package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
  30. package/dist/svelte/jazz.class.svelte.js +5 -5
  31. package/dist/svelte/jazz.svelte.d.ts +2 -2
  32. package/dist/svelte/jazz.svelte.d.ts.map +1 -1
  33. package/dist/testing.js +3 -3
  34. package/dist/testing.js.map +1 -1
  35. package/dist/tools/coValues/CoValueBase.d.ts +3 -13
  36. package/dist/tools/coValues/CoValueBase.d.ts.map +1 -1
  37. package/dist/tools/coValues/account.d.ts +2 -2
  38. package/dist/tools/coValues/account.d.ts.map +1 -1
  39. package/dist/tools/coValues/coFeed.d.ts.map +1 -1
  40. package/dist/tools/coValues/coList.d.ts.map +1 -1
  41. package/dist/tools/coValues/coMap.d.ts +5 -18
  42. package/dist/tools/coValues/coMap.d.ts.map +1 -1
  43. package/dist/tools/coValues/deepLoading.d.ts +4 -1
  44. package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
  45. package/dist/tools/coValues/extensions/imageDef.d.ts +4 -7
  46. package/dist/tools/coValues/extensions/imageDef.d.ts.map +1 -1
  47. package/dist/tools/coValues/inbox.d.ts +2 -2
  48. package/dist/tools/coValues/inbox.d.ts.map +1 -1
  49. package/dist/tools/coValues/interfaces.d.ts +2 -17
  50. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  51. package/dist/tools/coValues/request.d.ts +2 -2
  52. package/dist/tools/coValues/request.d.ts.map +1 -1
  53. package/dist/tools/coValues/schemaUnion.d.ts +5 -1
  54. package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
  55. package/dist/tools/exports.d.ts +3 -3
  56. package/dist/tools/exports.d.ts.map +1 -1
  57. package/dist/tools/implementation/createContext.d.ts +4 -4
  58. package/dist/tools/implementation/createContext.d.ts.map +1 -1
  59. package/dist/tools/implementation/invites.d.ts +2 -2
  60. package/dist/tools/implementation/invites.d.ts.map +1 -1
  61. package/dist/tools/implementation/schemaUtils.d.ts +8 -0
  62. package/dist/tools/implementation/schemaUtils.d.ts.map +1 -0
  63. package/dist/tools/implementation/zodSchema/coExport.d.ts +11 -1
  64. package/dist/tools/implementation/zodSchema/coExport.d.ts.map +1 -1
  65. package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts +22 -0
  66. package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts.map +1 -0
  67. package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +10 -0
  68. package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -0
  69. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +11 -11
  70. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  71. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +34 -24
  72. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
  73. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +16 -14
  74. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
  75. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +23 -17
  76. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
  77. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +24 -16
  78. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
  79. package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts +20 -9
  80. package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts.map +1 -1
  81. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +18 -12
  82. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
  83. package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts +18 -0
  84. package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts.map +1 -0
  85. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +14 -9
  86. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
  87. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +14 -9
  88. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
  89. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +14 -9
  90. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
  91. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +15 -13
  92. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
  93. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +12 -15
  94. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +1 -1
  95. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts +17 -20
  96. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts.map +1 -1
  97. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts +17 -20
  98. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts.map +1 -1
  99. package/dist/tools/implementation/zodSchema/unionUtils.d.ts +3 -5
  100. package/dist/tools/implementation/zodSchema/unionUtils.d.ts.map +1 -1
  101. package/dist/tools/implementation/zodSchema/zodCo.d.ts +10 -8
  102. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  103. package/dist/tools/implementation/zodSchema/zodReExport.d.ts +4 -8
  104. package/dist/tools/implementation/zodSchema/zodReExport.d.ts.map +1 -1
  105. package/dist/tools/implementation/zodSchema/zodSchema.d.ts +21 -30
  106. package/dist/tools/implementation/zodSchema/zodSchema.d.ts.map +1 -1
  107. package/dist/tools/internal.d.ts +3 -2
  108. package/dist/tools/internal.d.ts.map +1 -1
  109. package/dist/tools/lib/utilityTypes.d.ts +10 -0
  110. package/dist/tools/lib/utilityTypes.d.ts.map +1 -0
  111. package/dist/tools/subscribe/utils.d.ts.map +1 -1
  112. package/dist/tools/testing.d.ts +2 -2
  113. package/dist/tools/testing.d.ts.map +1 -1
  114. package/dist/worker/index.d.ts.map +1 -1
  115. package/dist/worker/index.js +2 -2
  116. package/dist/worker/index.js.map +1 -1
  117. package/package.json +5 -5
  118. package/src/browser/index.ts +2 -4
  119. package/src/browser-media-images/index.ts +1 -1
  120. package/src/react/hooks.tsx +2 -2
  121. package/src/react-core/hooks.ts +6 -6
  122. package/src/react-core/tests/useAccount.test.ts +2 -2
  123. package/src/react-core/tests/useCoState.test.ts +3 -2
  124. package/src/react-native-core/hooks.tsx +2 -2
  125. package/src/svelte/jazz.class.svelte.ts +10 -7
  126. package/src/svelte/jazz.svelte.ts +2 -2
  127. package/src/tools/coValues/CoValueBase.ts +8 -20
  128. package/src/tools/coValues/account.ts +18 -14
  129. package/src/tools/coValues/coFeed.ts +0 -4
  130. package/src/tools/coValues/coList.ts +7 -9
  131. package/src/tools/coValues/coMap.ts +1 -6
  132. package/src/tools/coValues/coPlainText.ts +4 -4
  133. package/src/tools/coValues/deepLoading.ts +4 -1
  134. package/src/tools/coValues/extensions/imageDef.ts +3 -3
  135. package/src/tools/coValues/inbox.ts +4 -4
  136. package/src/tools/coValues/interfaces.ts +4 -71
  137. package/src/tools/coValues/request.ts +15 -13
  138. package/src/tools/coValues/schemaUnion.ts +8 -4
  139. package/src/tools/exports.ts +3 -14
  140. package/src/tools/implementation/createContext.ts +9 -9
  141. package/src/tools/implementation/invites.ts +2 -2
  142. package/src/tools/implementation/schemaUtils.ts +18 -0
  143. package/src/tools/implementation/zodSchema/coExport.ts +14 -0
  144. package/src/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.ts +156 -0
  145. package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +133 -0
  146. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +36 -17
  147. package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +101 -52
  148. package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +54 -50
  149. package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +54 -46
  150. package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +187 -137
  151. package/src/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.ts +29 -27
  152. package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +28 -18
  153. package/src/tools/implementation/zodSchema/schemaTypes/CoValueSchema.ts +18 -0
  154. package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +45 -36
  155. package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +47 -35
  156. package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +43 -30
  157. package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +28 -23
  158. package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.ts +28 -25
  159. package/src/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.ts +86 -78
  160. package/src/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.ts +91 -82
  161. package/src/tools/implementation/zodSchema/unionUtils.ts +47 -51
  162. package/src/tools/implementation/zodSchema/zodCo.ts +42 -75
  163. package/src/tools/implementation/zodSchema/zodReExport.ts +44 -24
  164. package/src/tools/implementation/zodSchema/zodSchema.ts +64 -102
  165. package/src/tools/internal.ts +3 -2
  166. package/src/tools/lib/utilityTypes.ts +7 -0
  167. package/src/tools/subscribe/utils.ts +4 -2
  168. package/src/tools/testing.ts +4 -4
  169. package/src/tools/tests/ContextManager.test.ts +8 -9
  170. package/src/tools/tests/account.test.ts +65 -3
  171. package/src/tools/tests/coDiscriminatedUnion.test-d.ts +38 -0
  172. package/src/tools/tests/coDiscriminatedUnion.test.ts +219 -1
  173. package/src/tools/tests/coFeed.test-d.ts +4 -3
  174. package/src/tools/tests/coList.test-d.ts +32 -3
  175. package/src/tools/tests/coList.test.ts +20 -2
  176. package/src/tools/tests/coMap.record.test-d.ts +31 -3
  177. package/src/tools/tests/coMap.record.test.ts +9 -9
  178. package/src/tools/tests/coMap.test-d.ts +8 -8
  179. package/src/tools/tests/coMap.test.ts +19 -5
  180. package/src/tools/tests/coOptional.test.ts +63 -1
  181. package/src/tools/tests/createContext.test.ts +7 -9
  182. package/src/tools/tests/deepLoading.test.ts +4 -10
  183. package/src/tools/tests/exportImport.test.ts +2 -2
  184. package/src/tools/tests/groupsAndAccounts.test.ts +5 -4
  185. package/src/tools/tests/inbox.test.ts +3 -2
  186. package/src/tools/tests/load.test.ts +3 -29
  187. package/src/tools/tests/schemaUnion.test.ts +2 -2
  188. package/src/tools/tests/subscribe.test.ts +22 -114
  189. package/src/tools/tests/testing.test.ts +6 -6
  190. package/src/tools/tests/zod.test-d.ts +27 -0
  191. package/src/tools/tests/zod.test.ts +50 -45
  192. package/src/worker/index.ts +0 -1
  193. package/dist/chunk-OSVAAVWQ.js.map +0 -1
  194. package/dist/tools/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.d.ts +0 -12
  195. package/dist/tools/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.d.ts.map +0 -1
  196. package/dist/tools/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.d.ts +0 -9
  197. package/dist/tools/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.d.ts.map +0 -1
  198. package/src/tools/implementation/zodSchema/runtimeConverters/zodFieldToCoFieldDef.ts +0 -172
  199. package/src/tools/implementation/zodSchema/runtimeConverters/zodSchemaToCoSchema.ts +0 -218
@@ -1,5 +1,5 @@
1
1
  import { assert, beforeEach, expect, test } from "vitest";
2
- import { Account, CoListSchema, Group, co, z } from "../exports.js";
2
+ import { Account, Group, co, z } from "../exports.js";
3
3
  import {
4
4
  createJazzTestAccount,
5
5
  linkAccounts,
@@ -147,10 +147,10 @@ test("should support recursive props on co.profile", async () => {
147
147
  username: z.optional(z.string()),
148
148
  display_name: z.optional(z.string()),
149
149
  anonymous: z.boolean(),
150
- get following(): CoListSchema<typeof User> {
150
+ get following(): co.List<typeof User> {
151
151
  return co.list(User);
152
152
  },
153
- get followers(): CoListSchema<typeof User> {
153
+ get followers(): co.List<typeof User> {
154
154
  return co.list(User);
155
155
  },
156
156
  });
@@ -194,3 +194,65 @@ test("should support recursive props on co.profile", async () => {
194
194
  expect(account.profile.following.length).toBe(0);
195
195
  expect(account.profile.followers.length).toBe(0);
196
196
  });
197
+
198
+ test("root and profile should be trusting by default", async () => {
199
+ const AccountSchema = co
200
+ .account({
201
+ profile: co.profile(),
202
+ root: co.map({
203
+ name: z.string(),
204
+ }),
205
+ })
206
+ .withMigration((me, creationProps) => {
207
+ const group = Group.create({ owner: me }).makePublic();
208
+
209
+ if (me.profile === undefined) {
210
+ me.profile = co.profile().create(
211
+ {
212
+ name: creationProps?.name ?? "Anonymous",
213
+ },
214
+ group,
215
+ );
216
+ }
217
+
218
+ if (me.root === undefined) {
219
+ me.root = co
220
+ .map({
221
+ name: z.string(),
222
+ })
223
+ .create(
224
+ {
225
+ name: creationProps?.name ?? "Anonymous",
226
+ },
227
+ group,
228
+ );
229
+ }
230
+ });
231
+
232
+ const bob = await createJazzTestAccount({
233
+ AccountSchema,
234
+ creationProps: {
235
+ name: "Bob",
236
+ },
237
+ });
238
+
239
+ const alice = await createJazzTestAccount({
240
+ AccountSchema,
241
+ creationProps: {
242
+ name: "Alice",
243
+ },
244
+ });
245
+
246
+ const bobAccountLoadedFromAlice = await AccountSchema.load(bob.id, {
247
+ loadAs: alice,
248
+ resolve: {
249
+ profile: true,
250
+ root: true,
251
+ },
252
+ });
253
+
254
+ assert(bobAccountLoadedFromAlice);
255
+
256
+ expect(bobAccountLoadedFromAlice.profile.name).toBe("Bob");
257
+ expect(bobAccountLoadedFromAlice.root.name).toBe("Bob");
258
+ });
@@ -44,6 +44,44 @@ describe("co.discriminatedUnion", () => {
44
44
  matches(person);
45
45
  });
46
46
 
47
+ test("recursive co.discriminatedUnion", () => {
48
+ const Dog = co.map({
49
+ type: z.literal("dog"),
50
+ get friend() {
51
+ return co.optional(Pet);
52
+ },
53
+ });
54
+ const Cat = co.map({
55
+ type: z.literal("cat"),
56
+ get friend() {
57
+ return co.optional(Pet);
58
+ },
59
+ });
60
+
61
+ const Pet = co.discriminatedUnion("type", [Dog, Cat]);
62
+
63
+ const pallino = Cat.create({
64
+ type: "cat",
65
+ friend: Dog.create({
66
+ type: "dog",
67
+ }),
68
+ });
69
+
70
+ pallino.friend = Cat.create({
71
+ type: "cat",
72
+ });
73
+
74
+ type ExpectedType = {
75
+ friend: Loaded<typeof Dog> | Loaded<typeof Cat> | undefined;
76
+ };
77
+
78
+ function matches(value: ExpectedType) {
79
+ return value;
80
+ }
81
+
82
+ matches(pallino);
83
+ });
84
+
47
85
  test("cannot use co.discriminatedUnion with zod schemas as values", () => {
48
86
  const Person = co.map({
49
87
  pet: co.discriminatedUnion("type", [
@@ -1,5 +1,5 @@
1
1
  import { beforeEach, describe, expect, test, vi } from "vitest";
2
- import { Loaded, co, z } from "../exports.js";
2
+ import { CoPlainText, Loaded, co, z } from "../exports.js";
3
3
  import { createJazzTestAccount, setupJazzTestSync } from "../testing.js";
4
4
  import { waitFor } from "./utils.js";
5
5
 
@@ -39,6 +39,224 @@ describe("co.discriminatedUnion", () => {
39
39
  expect(person.pet.type).toEqual("cat");
40
40
  });
41
41
 
42
+ test("use nested co.discriminatedUnions", () => {
43
+ const BaseError = { status: z.literal("failed"), message: z.string() };
44
+ const BadRequestError = co.map({ ...BaseError, code: z.literal(400) });
45
+ const UnauthorizedError = co.map({ ...BaseError, code: z.literal(401) });
46
+ const InternalServerError = co.map({ ...BaseError, code: z.literal(500) });
47
+ const Errors = co.discriminatedUnion("code", [
48
+ BadRequestError,
49
+ UnauthorizedError,
50
+ InternalServerError,
51
+ ]);
52
+
53
+ const Success = co.map({ status: z.literal("success"), data: z.string() });
54
+ const Response = co.map({
55
+ result: co.discriminatedUnion("status", [Success, Errors]),
56
+ });
57
+
58
+ const response = Response.create({
59
+ result: Success.create({
60
+ status: "success",
61
+ data: "Hello, world!",
62
+ }),
63
+ });
64
+
65
+ expect(response.result.status).toEqual("success");
66
+ if (response.result.status === "success") {
67
+ expect(response.result.data).toEqual("Hello, world!");
68
+ }
69
+
70
+ response.result = BadRequestError.create({
71
+ status: "failed",
72
+ message: "Bad request",
73
+ code: 400,
74
+ });
75
+
76
+ expect(response.result.status).toEqual("failed");
77
+ if (response.result.status === "failed") {
78
+ expect(response.result.code).toEqual(400);
79
+ if (response.result.code === 400) {
80
+ expect(response.result.message).toEqual("Bad request");
81
+ }
82
+ }
83
+ });
84
+
85
+ test("use deeply nested co.discriminatedUnions", () => {
86
+ const BaseError = { status: z.literal("failed"), message: z.string() };
87
+ const BadRequestError = co.map({ ...BaseError, code: z.literal(400) });
88
+ const UnauthorizedError = co.map({ ...BaseError, code: z.literal(401) });
89
+ const Errors = co.discriminatedUnion("code", [
90
+ BadRequestError,
91
+ co.discriminatedUnion("code", [
92
+ co.discriminatedUnion("code", [
93
+ co.discriminatedUnion("code", [UnauthorizedError]),
94
+ ]),
95
+ ]),
96
+ ]);
97
+
98
+ const Response = co.map({
99
+ error: Errors,
100
+ });
101
+
102
+ const response = Response.create({
103
+ error: BadRequestError.create({
104
+ status: "failed",
105
+ message: "Bad request",
106
+ code: 400,
107
+ }),
108
+ });
109
+
110
+ expect(response.error.status).toEqual("failed");
111
+ if (response.error.status === "failed") {
112
+ expect(response.error.code).toEqual(400);
113
+ if (response.error.code === 400) {
114
+ expect(response.error.message).toEqual("Bad request");
115
+ }
116
+ }
117
+
118
+ response.error = UnauthorizedError.create({
119
+ status: "failed",
120
+ message: "Unauthorized",
121
+ code: 401,
122
+ });
123
+
124
+ expect(response.error.status).toEqual("failed");
125
+ if (response.error.status === "failed") {
126
+ expect(response.error.code).toEqual(401);
127
+ if (response.error.code === 401) {
128
+ expect(response.error.message).toEqual("Unauthorized");
129
+ }
130
+ }
131
+ });
132
+
133
+ test("co.discriminatedUnion works when nested inside a co.list", () => {
134
+ const Dog = co.map({
135
+ type: z.literal("dog"),
136
+ });
137
+ const Cat = co.map({
138
+ type: z.literal("cat"),
139
+ });
140
+ const Pet = co.discriminatedUnion("type", [Dog, Cat]);
141
+
142
+ const Pets = co.list(Pet);
143
+
144
+ const Person = co.map({
145
+ pets: Pets,
146
+ });
147
+
148
+ const pets = Pets.create([
149
+ Dog.create({
150
+ type: "dog",
151
+ }),
152
+ Cat.create({
153
+ type: "cat",
154
+ }),
155
+ ]);
156
+ const person = Person.create({
157
+ pets,
158
+ });
159
+
160
+ expect(person.pets[0]?.type).toEqual("dog");
161
+ expect(person.pets[1]?.type).toEqual("cat");
162
+ });
163
+
164
+ test("co.discriminatedUnion works when used in a recursive reference", () => {
165
+ const NoteItem = co.map({
166
+ type: z.literal("note"),
167
+ internal: z.boolean(),
168
+ content: co.plainText(),
169
+ });
170
+
171
+ const AttachmentItem = co.map({
172
+ type: z.literal("attachment"),
173
+ internal: z.boolean(),
174
+ content: co.fileStream(),
175
+ });
176
+
177
+ const ReferenceItem = co.map({
178
+ type: z.literal("reference"),
179
+ internal: z.boolean(),
180
+ content: z.string(),
181
+
182
+ get child(): co.DiscriminatedUnion<
183
+ [typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]
184
+ > {
185
+ return ProjectContextItem;
186
+ },
187
+ });
188
+
189
+ const ProjectContextItem = co.discriminatedUnion("type", [
190
+ NoteItem,
191
+ AttachmentItem,
192
+ ReferenceItem,
193
+ ]);
194
+
195
+ const referenceItem = ReferenceItem.create({
196
+ type: "reference",
197
+ internal: false,
198
+ content: "Hello",
199
+ child: NoteItem.create({
200
+ type: "note",
201
+ internal: false,
202
+ content: CoPlainText.create("Hello"),
203
+ }),
204
+ });
205
+
206
+ expect(referenceItem.child.type).toEqual("note");
207
+ });
208
+
209
+ test("co.discriminatedUnion works when used inside another schema in a recursive reference", () => {
210
+ const NoteItem = co.map({
211
+ type: z.literal("note"),
212
+ internal: z.boolean(),
213
+ content: co.plainText(),
214
+ });
215
+
216
+ const AttachmentItem = co.map({
217
+ type: z.literal("attachment"),
218
+ internal: z.boolean(),
219
+ content: co.fileStream(),
220
+ });
221
+
222
+ const ReferenceItem = co.map({
223
+ type: z.literal("reference"),
224
+ internal: z.boolean(),
225
+ content: z.string(),
226
+
227
+ get children(): co.List<
228
+ co.DiscriminatedUnion<
229
+ [typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]
230
+ >
231
+ > {
232
+ return ProjectContextItems;
233
+ },
234
+ });
235
+
236
+ const ProjectContextItem = co.discriminatedUnion("type", [
237
+ NoteItem,
238
+ AttachmentItem,
239
+ ReferenceItem,
240
+ ]);
241
+
242
+ const ProjectContextItems = co.list(ProjectContextItem);
243
+
244
+ const referenceItem = ReferenceItem.create({
245
+ type: "reference",
246
+ internal: false,
247
+ content: "Hello",
248
+ children: ProjectContextItems.create([
249
+ NoteItem.create({
250
+ type: "note",
251
+ internal: false,
252
+ content: CoPlainText.create("Hello"),
253
+ }),
254
+ ]),
255
+ });
256
+
257
+ expect(referenceItem.children[0]?.type).toEqual("note");
258
+ });
259
+
42
260
  test("load CoValue instances using the DiscriminatedUnion schema", async () => {
43
261
  const Dog = co.map({
44
262
  type: z.literal("dog"),
@@ -70,9 +70,10 @@ describe("CoFeed", () => {
70
70
  });
71
71
 
72
72
  test("CoFeed create with partially loaded, reference and optional", () => {
73
+ const Breed = co.map({ type: z.literal("labrador"), value: z.string() });
73
74
  const Dog = co.map({
74
75
  name: z.string(),
75
- breed: co.map({ type: z.literal("labrador"), value: z.string() }),
76
+ breed: Breed,
76
77
  });
77
78
  type Dog = co.loaded<typeof Dog>;
78
79
 
@@ -80,11 +81,11 @@ describe("CoFeed", () => {
80
81
 
81
82
  const dog = Dog.create({
82
83
  name: "Rex",
83
- breed: Dog.def.shape.breed.create({
84
+ breed: Breed.create({
84
85
  type: "labrador",
85
86
  value: "Labrador",
86
87
  }),
87
- }) as Dog;
88
+ });
88
89
 
89
90
  const feed = DogFeed.create([dog, undefined]);
90
91
 
@@ -74,9 +74,10 @@ describe("CoList", () => {
74
74
  });
75
75
 
76
76
  test("CoList create with partially loaded, reference and optional", () => {
77
+ const Breed = co.map({ type: z.literal("labrador"), value: z.string() });
77
78
  const Dog = co.map({
78
79
  name: z.string(),
79
- breed: co.map({ type: z.literal("labrador"), value: z.string() }),
80
+ breed: Breed,
80
81
  });
81
82
  type Dog = co.loaded<typeof Dog>;
82
83
 
@@ -84,11 +85,11 @@ describe("CoList", () => {
84
85
 
85
86
  const dog = Dog.create({
86
87
  name: "Rex",
87
- breed: Dog.def.shape.breed.create({
88
+ breed: Breed.create({
88
89
  type: "labrador",
89
90
  value: "Labrador",
90
91
  }),
91
- }) as Dog;
92
+ });
92
93
 
93
94
  const list = DogList.create([dog, undefined]);
94
95
 
@@ -101,6 +102,34 @@ describe("CoList", () => {
101
102
  matches(list);
102
103
  });
103
104
 
105
+ test("CoList with recursive reference", () => {
106
+ const Dog = co.map({
107
+ name: z.string(),
108
+ breed: z.string(),
109
+ get friends() {
110
+ return DogList.optional();
111
+ },
112
+ });
113
+
114
+ const DogList = co.list(Dog);
115
+
116
+ const rex = Dog.create({
117
+ name: "Rex",
118
+ breed: "Labrador",
119
+ friends: DogList.create([]),
120
+ });
121
+
122
+ const list = DogList.create([rex]);
123
+
124
+ type ExpectedType = Loaded<typeof Dog>[];
125
+
126
+ function matches(value: ExpectedType) {
127
+ return value;
128
+ }
129
+
130
+ matches(list);
131
+ });
132
+
104
133
  test("CoList with nested lists", () => {
105
134
  const NestedList = co.list(co.list(z.string()));
106
135
 
@@ -1,7 +1,11 @@
1
1
  import { WasmCrypto } from "cojson/crypto/WasmCrypto";
2
2
  import { beforeEach, describe, expect, test, vi } from "vitest";
3
3
  import { Account, Group, subscribeToCoValue, z } from "../index.js";
4
- import { Loaded, anySchemaToCoSchema, co } from "../internal.js";
4
+ import {
5
+ Loaded,
6
+ co,
7
+ coValueClassFromCoValueClassOrSchema,
8
+ } from "../internal.js";
5
9
  import { createJazzTestAccount, setupJazzTestSync } from "../testing.js";
6
10
  import { waitFor } from "./utils.js";
7
11
 
@@ -580,7 +584,7 @@ describe("CoList subscription", async () => {
580
584
  const spy = vi.fn((list) => updates.push(list));
581
585
 
582
586
  subscribeToCoValue(
583
- anySchemaToCoSchema(TestList),
587
+ coValueClassFromCoValueClassOrSchema(TestList),
584
588
  list.id,
585
589
  {
586
590
  syncResolution: true,
@@ -806,3 +810,17 @@ describe("CoList subscription", async () => {
806
810
  expect(spy).toHaveBeenCalledTimes(2);
807
811
  });
808
812
  });
813
+
814
+ describe("co.list schema", () => {
815
+ test("can access the inner schema of a co.list", () => {
816
+ const Keywords = co.list(co.plainText());
817
+
818
+ const keywords = Keywords.create([
819
+ Keywords.element.create("hello"),
820
+ Keywords.element.create("world"),
821
+ ]);
822
+
823
+ expect(keywords[0]?.toString()).toEqual("hello");
824
+ expect(keywords[1]?.toString()).toEqual("world");
825
+ });
826
+ });
@@ -81,9 +81,10 @@ describe("CoMap.Record", () => {
81
81
  });
82
82
 
83
83
  test("Record create with partially loaded, reference and optional", () => {
84
+ const Breed = co.map({ type: z.literal("labrador"), value: z.string() });
84
85
  const Dog = co.map({
85
86
  name: z.string(),
86
- breed: co.map({ type: z.literal("labrador"), value: z.string() }),
87
+ breed: Breed,
87
88
  });
88
89
  type Dog = co.loaded<typeof Dog>;
89
90
 
@@ -91,11 +92,11 @@ describe("CoMap.Record", () => {
91
92
 
92
93
  const dog = Dog.create({
93
94
  name: "Rex",
94
- breed: Dog.def.shape.breed.create({
95
+ breed: Breed.create({
95
96
  type: "labrador",
96
97
  value: "Labrador",
97
98
  }),
98
- }) as Dog;
99
+ });
99
100
 
100
101
  const record = DogRecord.create({
101
102
  pet1: dog,
@@ -112,6 +113,33 @@ describe("CoMap.Record", () => {
112
113
 
113
114
  matches(record);
114
115
  });
116
+
117
+ test("Record with recursive reference", () => {
118
+ const Dog = co.map({
119
+ name: z.string(),
120
+ get owner() {
121
+ return Person.optional();
122
+ },
123
+ });
124
+
125
+ const Person = co.record(z.string(), Dog);
126
+
127
+ const person = Person.create({
128
+ pet1: Dog.create({ name: "Rex" }),
129
+ });
130
+
131
+ person.pet1!.owner = person;
132
+
133
+ type ExpectedType = {
134
+ [key: string]: Loaded<typeof Dog> | undefined;
135
+ };
136
+
137
+ function matches(value: ExpectedType) {
138
+ return value;
139
+ }
140
+
141
+ matches(person);
142
+ });
115
143
  });
116
144
 
117
145
  describe("Record resolution", () => {
@@ -236,9 +236,6 @@ describe("CoMap.Record", async () => {
236
236
  pet1: Dog.create({ name: "Rex", breed: "Labrador" }),
237
237
  });
238
238
 
239
- type V = (typeof Person)["_zod"]["def"]["valueType"];
240
- type T = InstanceOrPrimitiveOfSchema<typeof Person>;
241
-
242
239
  const updates: Loaded<typeof Person, { $each: true }>[] = [];
243
240
  const spy = vi.fn((person) => updates.push(person));
244
241
 
@@ -301,7 +298,7 @@ describe("CoMap.Record", async () => {
301
298
  });
302
299
 
303
300
  // Covers https://github.com/garden-co/jazz/issues/2385
304
- test("create a Record with a discriminated union containing a co.map that uses withHelpers", () => {
301
+ test("create a Record with a discriminated union containing a co.image", () => {
305
302
  const Base = co.map({
306
303
  type: z.literal("base"),
307
304
  name: z.string(),
@@ -309,8 +306,8 @@ describe("CoMap.Record", async () => {
309
306
 
310
307
  const IssueRepro = co.map({
311
308
  type: z.literal("repro"),
312
- catchall: co.map({}).withHelpers((self) => self),
313
309
  name: z.string(),
310
+ image: co.image(),
314
311
  });
315
312
 
316
313
  const PersonRecord = co.record(
@@ -320,8 +317,10 @@ describe("CoMap.Record", async () => {
320
317
 
321
318
  const person = IssueRepro.create({
322
319
  type: "repro",
323
- catchall: IssueRepro.def.shape.catchall.create({}),
324
320
  name: "John",
321
+ image: co.image().create({
322
+ originalSize: [1920, 1080],
323
+ }),
325
324
  });
326
325
 
327
326
  const record = PersonRecord.create({
@@ -329,7 +328,7 @@ describe("CoMap.Record", async () => {
329
328
  });
330
329
 
331
330
  if (record.john?.type === "repro") {
332
- expect(record.john.catchall).toEqual({});
331
+ expect(record.john.image.originalSize).toEqual([1920, 1080]);
333
332
  expect(record.john.name).toEqual("John");
334
333
  expect(record.john.type).toEqual("repro");
335
334
  }
@@ -342,9 +341,10 @@ describe("CoMap.Record", async () => {
342
341
  name: z.string(),
343
342
  });
344
343
 
344
+ const Catchall = co.map({}).catchall(z.string());
345
345
  const IssueRepro = co.map({
346
346
  type: z.literal("repro"),
347
- catchall: co.map({}).catchall(z.string()),
347
+ catchall: Catchall,
348
348
  name: z.string(),
349
349
  });
350
350
 
@@ -355,7 +355,7 @@ describe("CoMap.Record", async () => {
355
355
 
356
356
  const person = IssueRepro.create({
357
357
  type: "repro",
358
- catchall: IssueRepro.def.shape.catchall.create({}),
358
+ catchall: Catchall.create({}),
359
359
  name: "John",
360
360
  });
361
361
 
@@ -1,7 +1,7 @@
1
1
  import { assert, describe, expectTypeOf, test } from "vitest";
2
2
  import { Group, co, z } from "../exports.js";
3
3
  import { Account } from "../index.js";
4
- import { CoListSchema, Loaded } from "../internal.js";
4
+ import { Loaded } from "../internal.js";
5
5
 
6
6
  describe("CoMap", async () => {
7
7
  describe("init", () => {
@@ -117,9 +117,10 @@ describe("CoMap", async () => {
117
117
  });
118
118
 
119
119
  test("CoMap create with partially loaded, reference and optional", () => {
120
+ const Breed = co.map({ type: z.literal("labrador"), value: z.string() });
120
121
  const Dog = co.map({
121
122
  name: z.string(),
122
- breed: co.map({ type: z.literal("labrador"), value: z.string() }),
123
+ breed: Breed,
123
124
  });
124
125
  type Dog = co.loaded<typeof Dog>;
125
126
 
@@ -131,7 +132,7 @@ describe("CoMap", async () => {
131
132
 
132
133
  const dog = Dog.create({
133
134
  name: "Rex",
134
- breed: Dog.def.shape.breed.create({
135
+ breed: Breed.create({
135
136
  type: "labrador",
136
137
  value: "Labrador",
137
138
  }),
@@ -158,8 +159,8 @@ describe("CoMap", async () => {
158
159
 
159
160
  test("Comap with recursive optional reference", () => {
160
161
  const Recursive = co.map({
161
- get child(): z.ZodOptional<typeof Recursive> {
162
- return co.optional(Recursive);
162
+ get child() {
163
+ return Recursive.optional();
163
164
  },
164
165
  });
165
166
 
@@ -183,8 +184,7 @@ describe("CoMap", async () => {
183
184
  const Person = co.map({
184
185
  name: z.string(),
185
186
  age: z.number(),
186
- // TODO: would be nice if this didn't need a type annotation
187
- get friend(): z.ZodOptional<typeof Person> {
187
+ get friend() {
188
188
  return co.optional(Person);
189
189
  },
190
190
  });
@@ -243,7 +243,7 @@ describe("CoMap", async () => {
243
243
  test("update a reference on a loaded value", () => {
244
244
  const Dog = co.map({
245
245
  name: z.string(),
246
- get siblings(): CoListSchema<typeof Dog> {
246
+ get siblings() {
247
247
  return co.list(Dog);
248
248
  },
249
249
  });