jazz-tools 0.18.29 → 0.18.30

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 (107) hide show
  1. package/.svelte-kit/__package__/media/image.svelte +7 -4
  2. package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
  3. package/.svelte-kit/__package__/media/image.types.d.ts +1 -0
  4. package/.svelte-kit/__package__/media/image.types.d.ts.map +1 -1
  5. package/.svelte-kit/__package__/tests/media/image.svelte.test.js +63 -0
  6. package/.turbo/turbo-build.log +62 -62
  7. package/CHANGELOG.md +17 -0
  8. package/dist/better-auth/auth/client.d.ts +1 -1
  9. package/dist/better-auth/auth/server.d.ts +1 -1
  10. package/dist/better-auth/auth/server.d.ts.map +1 -1
  11. package/dist/better-auth/auth/server.js.map +1 -1
  12. package/dist/better-auth/database-adapter/index.d.ts +3 -3
  13. package/dist/better-auth/database-adapter/index.d.ts.map +1 -1
  14. package/dist/better-auth/database-adapter/index.js +6 -2
  15. package/dist/better-auth/database-adapter/index.js.map +1 -1
  16. package/dist/better-auth/database-adapter/utils.d.ts.map +1 -1
  17. package/dist/browser/index.d.ts +2 -1
  18. package/dist/browser/index.d.ts.map +1 -1
  19. package/dist/browser/index.js.map +1 -1
  20. package/dist/{chunk-F55R554M.js → chunk-6BIYT3KH.js} +51 -30
  21. package/dist/chunk-6BIYT3KH.js.map +1 -0
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/inspector/{custom-element-35MDW4SW.js → custom-element-RQTLPAPJ.js} +584 -298
  25. package/dist/inspector/custom-element-RQTLPAPJ.js.map +1 -0
  26. package/dist/inspector/index.js +570 -338
  27. package/dist/inspector/index.js.map +1 -1
  28. package/dist/inspector/register-custom-element.js +1 -1
  29. package/dist/inspector/ui/index.d.ts +6 -0
  30. package/dist/inspector/ui/index.d.ts.map +1 -0
  31. package/dist/inspector/viewer/group-view.d.ts +3 -2
  32. package/dist/inspector/viewer/group-view.d.ts.map +1 -1
  33. package/dist/inspector/viewer/page.d.ts.map +1 -1
  34. package/dist/react/index.js +2 -2
  35. package/dist/react/index.js.map +1 -1
  36. package/dist/react/media/image.d.ts +8 -0
  37. package/dist/react/media/image.d.ts.map +1 -1
  38. package/dist/react-native-core/index.js +3 -3
  39. package/dist/react-native-core/index.js.map +1 -1
  40. package/dist/react-native-core/media/image.d.ts +15 -0
  41. package/dist/react-native-core/media/image.d.ts.map +1 -1
  42. package/dist/svelte/media/image.svelte +7 -4
  43. package/dist/svelte/media/image.svelte.d.ts.map +1 -1
  44. package/dist/svelte/media/image.types.d.ts +1 -0
  45. package/dist/svelte/media/image.types.d.ts.map +1 -1
  46. package/dist/svelte/tests/media/image.svelte.test.js +63 -0
  47. package/dist/testing.js +8 -1
  48. package/dist/testing.js.map +1 -1
  49. package/dist/tools/coValues/account.d.ts +1 -0
  50. package/dist/tools/coValues/account.d.ts.map +1 -1
  51. package/dist/tools/coValues/group.d.ts +3 -3
  52. package/dist/tools/coValues/group.d.ts.map +1 -1
  53. package/dist/tools/implementation/invites.d.ts +2 -2
  54. package/dist/tools/implementation/invites.d.ts.map +1 -1
  55. package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +1 -1
  56. package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
  57. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  58. package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts +3 -1
  59. package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts.map +1 -1
  60. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  61. package/dist/tools/implementation/zodSchema/zodReExport.d.ts +1 -1
  62. package/dist/tools/implementation/zodSchema/zodReExport.d.ts.map +1 -1
  63. package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
  64. package/dist/tools/subscribe/SubscriptionScope.d.ts +0 -2
  65. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  66. package/dist/tools/testing.d.ts +1 -0
  67. package/dist/tools/testing.d.ts.map +1 -1
  68. package/dist/tools/tests/CoValueCoreSubscription.test.d.ts.map +1 -0
  69. package/package.json +4 -4
  70. package/src/better-auth/auth/server.ts +7 -2
  71. package/src/better-auth/auth/tests/server.test.ts +39 -17
  72. package/src/better-auth/database-adapter/index.ts +8 -5
  73. package/src/better-auth/database-adapter/utils.ts +4 -0
  74. package/src/browser/index.ts +2 -1
  75. package/src/inspector/ui/index.ts +5 -0
  76. package/src/inspector/viewer/group-view.tsx +304 -20
  77. package/src/inspector/viewer/new-app.tsx +4 -4
  78. package/src/inspector/viewer/page.tsx +16 -2
  79. package/src/react/media/image.tsx +11 -2
  80. package/src/react/tests/media/image.test.tsx +94 -0
  81. package/src/react-native-core/media/image.tsx +11 -3
  82. package/src/svelte/media/image.svelte +7 -4
  83. package/src/svelte/media/image.types.ts +1 -0
  84. package/src/svelte/tests/media/image.svelte.test.ts +85 -0
  85. package/src/tools/coValues/account.ts +30 -5
  86. package/src/tools/coValues/group.ts +13 -12
  87. package/src/tools/coValues/inbox.ts +5 -5
  88. package/src/tools/implementation/invites.ts +3 -8
  89. package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +5 -1
  90. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +2 -0
  91. package/src/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.ts +63 -50
  92. package/src/tools/implementation/zodSchema/zodReExport.ts +2 -2
  93. package/src/tools/subscribe/CoValueCoreSubscription.ts +17 -0
  94. package/src/tools/subscribe/SubscriptionScope.ts +1 -27
  95. package/src/tools/testing.ts +7 -0
  96. package/src/tools/{subscribe → tests}/CoValueCoreSubscription.test.ts +233 -3
  97. package/src/tools/tests/coFeed.branch.test.ts +14 -5
  98. package/src/tools/tests/coMap.test.ts +139 -42
  99. package/src/tools/tests/coOptional.test.ts +9 -1
  100. package/src/tools/tests/groupsAndAccounts.test.ts +156 -1
  101. package/src/tools/tests/load.test.ts +198 -1
  102. package/src/tools/tests/zod.test-d.ts +0 -2
  103. package/src/tools/tests/zod.test.ts +43 -40
  104. package/dist/chunk-F55R554M.js.map +0 -1
  105. package/dist/inspector/custom-element-35MDW4SW.js.map +0 -1
  106. package/dist/tools/subscribe/CoValueCoreSubscription.test.d.ts.map +0 -1
  107. /package/dist/tools/{subscribe → tests}/CoValueCoreSubscription.test.d.ts +0 -0
@@ -104,6 +104,91 @@ describe("Image", async () => {
104
104
  expect(img!.src).toBe(placeholderDataUrl);
105
105
  });
106
106
 
107
+ it("should not override actual placeholders", async () => {
108
+ const placeholderDataUrl =
109
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";
110
+ const customPlaceholder =
111
+ "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXItaWNvbiBsdWNpZGUtdXNlciI+PHBhdGggZD0iTTE5IDIxdi0yYTQgNCAwIDAgMC00LTRIOWE0IDQgMCAwIDAtNCA0djIiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjciIHI9IjQiLz48L3N2Zz4=";
112
+
113
+ const original = FileStream.create({ owner: account });
114
+ original.start({ mimeType: "image/jpeg" });
115
+ // Don't end original, so it has no chunks
116
+
117
+ const im = ImageDefinition.create(
118
+ {
119
+ original,
120
+ originalSize: [100, 100],
121
+ progressive: false,
122
+ placeholderDataURL: placeholderDataUrl,
123
+ },
124
+ {
125
+ owner: account,
126
+ },
127
+ );
128
+
129
+ const { container } = renderWithAccount({
130
+ imageId: im.$jazz.id,
131
+ alt: "test",
132
+ placeholder: customPlaceholder
133
+ });
134
+
135
+ const img = container.querySelector("img");
136
+ expect(img).toBeDefined();
137
+ expect(img!.src).toBe(placeholderDataUrl);
138
+ });
139
+
140
+ it("should show custom placeholder while loading and replace with loaded image", async () => {
141
+ const createObjectURLSpy = vi
142
+ .spyOn(URL, "createObjectURL")
143
+ .mockImplementation((blob) => {
144
+ if (!(blob instanceof Blob)) {
145
+ throw new Error("Blob expected");
146
+ }
147
+ return `blob:test-${blob.size}`;
148
+ });
149
+
150
+ const customPlaceholder =
151
+ "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXItaWNvbiBsdWNpZGUtdXNlciI+PHBhdGggZD0iTTE5IDIxdi0yYTQgNCAwIDAgMC00LTRIOWE0IDQgMCAwIDAtNCA0djIiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjciIHI9IjQiLz48L3N2Zz4=";
152
+
153
+ // Create an image with no chunks initially (loading state)
154
+ const original = FileStream.create({ owner: account });
155
+ original.start({ mimeType: "image/jpeg" });
156
+ // Don't end original, so it has no chunks
157
+
158
+ const im = ImageDefinition.create(
159
+ {
160
+ original,
161
+ originalSize: [100, 100],
162
+ progressive: false,
163
+ },
164
+ {
165
+ owner: account,
166
+ },
167
+ );
168
+
169
+ const { container } = renderWithAccount({
170
+ imageId: im.$jazz.id,
171
+ alt: "test-loading-custom-placeholder",
172
+ placeholder: customPlaceholder
173
+ });
174
+ // Initially should show custom placeholder
175
+ let img = container.querySelector("img");
176
+ expect(img).toBeDefined();
177
+ expect(img!.src).toBe(customPlaceholder);
178
+
179
+ // Now add the actual image data
180
+ const imageData = await createDummyFileStream(100, account);
181
+ im.$jazz.set("100x100", imageData);
182
+
183
+ // Wait for the image to load and replace the placeholder
184
+ await waitFor(() => {
185
+ img = container.querySelector("img");
186
+ expect(img!.src).toBe("blob:test-100");
187
+ });
188
+
189
+ expect(createObjectURLSpy).toHaveBeenCalledTimes(1);
190
+ });
191
+
107
192
  it("should render the original image once loaded", async () => {
108
193
  const createObjectURLSpy = vi
109
194
  .spyOn(URL, "createObjectURL")
@@ -12,6 +12,7 @@ import {
12
12
  RawCoValue,
13
13
  SessionID,
14
14
  cojsonInternals,
15
+ isAccountRole,
15
16
  } from "cojson";
16
17
  import {
17
18
  AnonymousJazzAgent,
@@ -166,29 +167,52 @@ export class Account extends CoValueBase implements CoValue {
166
167
  }
167
168
  const role = valueOwner.getRoleOf(this.$jazz.id);
168
169
 
170
+ return isAccountRole(role);
171
+ }
172
+
173
+ canWrite(value: CoValue): boolean {
174
+ const valueOwner = value.$jazz.owner;
175
+ if (!valueOwner) {
176
+ if (value[TypeSym] === "Group") {
177
+ const roleInGroup = (value as Group).getRoleOf(this.$jazz.id);
178
+ return (
179
+ roleInGroup === "admin" ||
180
+ roleInGroup === "manager" ||
181
+ roleInGroup === "writer"
182
+ );
183
+ }
184
+ if (value[TypeSym] === "Account") {
185
+ return value.$jazz.id === this.$jazz.id;
186
+ }
187
+ return false;
188
+ }
189
+ const role = valueOwner.getRoleOf(this.$jazz.id);
190
+
169
191
  return (
170
192
  role === "admin" ||
193
+ role === "manager" ||
171
194
  role === "writer" ||
172
- role === "reader" ||
173
195
  role === "writeOnly"
174
196
  );
175
197
  }
176
198
 
177
- canWrite(value: CoValue): boolean {
199
+ canManage(value: CoValue): boolean {
178
200
  const valueOwner = value.$jazz.owner;
179
201
  if (!valueOwner) {
180
202
  if (value[TypeSym] === "Group") {
181
203
  const roleInGroup = (value as Group).getRoleOf(this.$jazz.id);
182
- return roleInGroup === "admin" || roleInGroup === "writer";
204
+ return roleInGroup === "manager" || roleInGroup === "admin";
183
205
  }
184
206
  if (value[TypeSym] === "Account") {
185
207
  return value.$jazz.id === this.$jazz.id;
186
208
  }
187
209
  return false;
188
210
  }
189
- const role = valueOwner.getRoleOf(this.$jazz.id);
190
211
 
191
- return role === "admin" || role === "writer" || role === "writeOnly";
212
+ return (
213
+ valueOwner.getRoleOf(this.$jazz.id) === "admin" ||
214
+ valueOwner.getRoleOf(this.$jazz.id) === "manager"
215
+ );
192
216
  }
193
217
 
194
218
  canAdmin(value: CoValue): boolean {
@@ -203,6 +227,7 @@ export class Account extends CoValueBase implements CoValue {
203
227
  }
204
228
  return false;
205
229
  }
230
+
206
231
  return valueOwner.getRoleOf(this.$jazz.id) === "admin";
207
232
  }
208
233
 
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  RawAccount,
3
+ isAccountRole,
3
4
  type AccountRole,
4
5
  type AgentID,
5
6
  type Everyone,
@@ -10,7 +11,6 @@ import {
10
11
  } from "cojson";
11
12
  import {
12
13
  AnonymousJazzAgent,
13
- BranchDefinition,
14
14
  CoValue,
15
15
  CoValueClass,
16
16
  ID,
@@ -108,13 +108,16 @@ export class Group extends CoValueBase implements CoValue {
108
108
  */
109
109
  addMember(
110
110
  member: Group,
111
- role?: "reader" | "writer" | "admin" | "inherit",
111
+ role?: "reader" | "writer" | "admin" | "manager" | "inherit",
112
+ ): void;
113
+ addMember(
114
+ member: Group | Account,
115
+ role: "reader" | "writer" | "admin" | "manager",
112
116
  ): void;
113
- addMember(member: Group | Account, role: "reader" | "writer" | "admin"): void;
114
117
  addMember(
115
118
  member: Group | Everyone | Account,
116
119
  role?: AccountRole | "inherit",
117
- ) {
120
+ ): void {
118
121
  if (isGroupValue(member)) {
119
122
  if (role === "writeOnly")
120
123
  throw new Error("Cannot add group as member with write-only role");
@@ -158,12 +161,7 @@ export class Group extends CoValueBase implements CoValue {
158
161
 
159
162
  const role = this.$jazz.raw.roleOf(accountID);
160
163
 
161
- if (
162
- role === "admin" ||
163
- role === "writer" ||
164
- role === "reader" ||
165
- role === "writeOnly"
166
- ) {
164
+ if (isAccountRole(role)) {
167
165
  const ref = new Ref<Account>(
168
166
  accountID,
169
167
  this.$jazz.loadedAs,
@@ -249,9 +247,12 @@ export class Group extends CoValueBase implements CoValue {
249
247
  */
250
248
  extend(
251
249
  parent: Group,
252
- roleMapping?: "reader" | "writer" | "admin" | "inherit",
250
+ roleMapping?: "reader" | "writer" | "admin" | "manager" | "inherit",
253
251
  ): this {
254
- this.$jazz.raw.extend(parent.$jazz.raw, roleMapping);
252
+ this.$jazz.raw.extend(
253
+ parent.$jazz.raw,
254
+ roleMapping as "reader" | "writer" | "admin" | "manager" | "inherit",
255
+ );
255
256
  return this;
256
257
  }
257
258
 
@@ -431,12 +431,12 @@ export class InboxSender<I extends CoValue, O extends CoValue | undefined> {
431
431
  throw new Error("Failed to load the inbox owner profile");
432
432
  }
433
433
 
434
+ const inboxOwnerRole = inboxOwnerProfileRaw.group.roleOf(
435
+ currentAccount.$jazz.raw.id,
436
+ );
437
+
434
438
  if (
435
- inboxOwnerProfileRaw.group.roleOf(currentAccount.$jazz.raw.id) !==
436
- "reader" &&
437
- inboxOwnerProfileRaw.group.roleOf(currentAccount.$jazz.raw.id) !==
438
- "writer" &&
439
- inboxOwnerProfileRaw.group.roleOf(currentAccount.$jazz.raw.id) !== "admin"
439
+ !["reader", "writer", "admin", "manager"].includes(inboxOwnerRole ?? "")
440
440
  ) {
441
441
  throw new Error(
442
442
  "Insufficient permissions to access the inbox, make sure its user profile is publicly readable.",
@@ -1,16 +1,11 @@
1
- import { type InviteSecret, cojsonInternals } from "cojson";
1
+ import { AccountRole, type InviteSecret, cojsonInternals } from "cojson";
2
2
  import { Account } from "../coValues/account.js";
3
- import type {
4
- CoValue,
5
- CoValueClass,
6
- CoValueClassOrSchema,
7
- ID,
8
- } from "../internal.js";
3
+ import type { CoValue, CoValueClassOrSchema } from "../internal.js";
9
4
 
10
5
  /** @category Invite Links */
11
6
  export function createInviteLink<C extends CoValue>(
12
7
  value: C,
13
- role: "reader" | "writer" | "admin" | "writeOnly",
8
+ role: AccountRole,
14
9
  baseURL: string,
15
10
  valueHint?: string,
16
11
  ): string {
@@ -26,7 +26,9 @@ export type SchemaField =
26
26
  | z.core.$ZodNullable<z.core.$ZodType>
27
27
  | z.core.$ZodUnion<z.core.$ZodType[]>
28
28
  | z.core.$ZodDiscriminatedUnion<z.core.$ZodType[]>
29
+ | z.core.$ZodIntersection<z.core.$ZodType, z.core.$ZodType>
29
30
  | z.core.$ZodObject<z.core.$ZodLooseShape>
31
+ | z.core.$ZodRecord<z.core.$ZodRecordKey, z.core.$ZodType>
30
32
  | z.core.$ZodArray<z.core.$ZodType>
31
33
  | z.core.$ZodTuple<z.core.$ZodType[]>
32
34
  | z.core.$ZodReadonly<z.core.$ZodType>
@@ -146,8 +148,10 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
146
148
  );
147
149
  } else if (
148
150
  zodSchemaDef.type === "object" ||
151
+ zodSchemaDef.type === "record" ||
149
152
  zodSchemaDef.type === "array" ||
150
- zodSchemaDef.type === "tuple"
153
+ zodSchemaDef.type === "tuple" ||
154
+ zodSchemaDef.type === "intersection"
151
155
  ) {
152
156
  return coField.json();
153
157
  } else if (zodSchemaDef.type === "union") {
@@ -2,6 +2,7 @@ import {
2
2
  Account,
3
3
  AccountCreationProps,
4
4
  BranchDefinition,
5
+ coOptionalDefiner,
5
6
  Group,
6
7
  RefsToResolveStrict,
7
8
  Simplify,
@@ -149,6 +150,7 @@ export function enrichAccountSchema<Shape extends BaseAccountShape>(
149
150
  getCoValueClass: () => {
150
151
  return coValueClass;
151
152
  },
153
+ optional: () => coOptionalDefiner(enrichedSchema),
152
154
  }) as unknown as AccountSchema<Shape>;
153
155
  return enrichedSchema;
154
156
  }
@@ -25,59 +25,72 @@ export type TypeOfZodSchema<S extends z.core.$ZodType> =
25
25
  infer Members extends readonly z.core.$ZodType[]
26
26
  >
27
27
  ? TypeOfZodSchema<Members[number]>
28
- : S extends z.core.$ZodObject<infer Shape>
29
- ? /**
30
- * Cannot use {@link PartialOnUndefined} because evaluating TypeOfZodSchema<Shape[key]>
31
- * to know if the value can be undefined does not work with recursive types.
32
- */
33
- {
34
- -readonly [key in keyof Shape as Shape[key] extends OptionalInSchema
35
- ? never
36
- : key]: TypeOfZodSchema<Shape[key]>;
37
- } & {
38
- -readonly [key in keyof Shape as Shape[key] extends OptionalInSchema
39
- ? key
40
- : never]?: TypeOfZodSchema<Shape[key]>;
41
- }
42
- : S extends z.core.$ZodArray<infer Item extends z.core.$ZodType>
43
- ? TypeOfZodSchema<Item>[]
44
- : S extends z.core.$ZodTuple<
45
- infer Items extends readonly z.core.$ZodType[]
28
+ : S extends z.core.$ZodIntersection<
29
+ infer Left extends z.core.$ZodType,
30
+ infer Right extends z.core.$ZodType
31
+ >
32
+ ? TypeOfZodSchema<Left> & TypeOfZodSchema<Right>
33
+ : S extends z.core.$ZodObject<infer Shape>
34
+ ? /**
35
+ * Cannot use {@link PartialOnUndefined} because evaluating TypeOfZodSchema<Shape[key]>
36
+ * to know if the value can be undefined does not work with recursive types.
37
+ */
38
+ {
39
+ -readonly [key in keyof Shape as Shape[key] extends OptionalInSchema
40
+ ? never
41
+ : key]: TypeOfZodSchema<Shape[key]>;
42
+ } & {
43
+ -readonly [key in keyof Shape as Shape[key] extends OptionalInSchema
44
+ ? key
45
+ : never]?: TypeOfZodSchema<Shape[key]>;
46
+ }
47
+ : S extends z.core.$ZodRecord<
48
+ infer Key,
49
+ infer Value extends z.core.$ZodType
46
50
  >
47
51
  ? {
48
- [key in keyof Items]: TypeOfZodSchema<Items[key]>;
52
+ [key in z.output<Key>]: TypeOfZodSchema<Value>;
49
53
  }
50
- : S extends z.core.$ZodString
51
- ? string
52
- : S extends z.core.$ZodNumber
53
- ? number
54
- : S extends z.core.$ZodBoolean
55
- ? boolean
56
- : S extends z.core.$ZodLiteral<infer Literal>
57
- ? Literal
58
- : S extends z.core.$ZodDate
59
- ? Date
60
- : S extends z.core.$ZodEnum<infer Enum>
61
- ? Enum[keyof Enum]
62
- : S extends z.core.$ZodTemplateLiteral<
63
- infer pattern
64
- >
65
- ? pattern
66
- : S extends z.core.$ZodReadonly<
67
- infer Inner extends z.core.$ZodType
68
- >
69
- ? TypeOfZodSchema<Inner>
70
- : S extends z.core.$ZodDefault<
71
- infer Default extends z.core.$ZodType
54
+ : S extends z.core.$ZodArray<infer Item extends z.core.$ZodType>
55
+ ? TypeOfZodSchema<Item>[]
56
+ : S extends z.core.$ZodTuple<
57
+ infer Items extends readonly z.core.$ZodType[]
58
+ >
59
+ ? {
60
+ [key in keyof Items]: TypeOfZodSchema<Items[key]>;
61
+ }
62
+ : S extends z.core.$ZodString
63
+ ? string
64
+ : S extends z.core.$ZodNumber
65
+ ? number
66
+ : S extends z.core.$ZodBoolean
67
+ ? boolean
68
+ : S extends z.core.$ZodLiteral<infer Literal>
69
+ ? Literal
70
+ : S extends z.core.$ZodDate
71
+ ? Date
72
+ : S extends z.core.$ZodEnum<infer Enum>
73
+ ? Enum[keyof Enum]
74
+ : S extends z.core.$ZodTemplateLiteral<
75
+ infer pattern
72
76
  >
73
- ? TypeOfZodSchema<Default>
74
- : S extends z.core.$ZodCodec<
75
- any,
76
- infer Out extends z.core.$ZodType
77
+ ? pattern
78
+ : S extends z.core.$ZodReadonly<
79
+ infer Inner extends z.core.$ZodType
77
80
  >
78
- ? Out["_zod"]["output"]
79
- : S extends z.core.$ZodCatch<
80
- infer Catch extends z.core.$ZodType
81
+ ? TypeOfZodSchema<Inner>
82
+ : S extends z.core.$ZodDefault<
83
+ infer Default extends z.core.$ZodType
81
84
  >
82
- ? TypeOfZodSchema<Catch>
83
- : never;
85
+ ? TypeOfZodSchema<Default>
86
+ : S extends z.core.$ZodCodec<
87
+ any,
88
+ infer Out extends z.core.$ZodType
89
+ >
90
+ ? Out["_zod"]["output"]
91
+ : S extends z.core.$ZodCatch<
92
+ infer Catch extends
93
+ z.core.$ZodType
94
+ >
95
+ ? TypeOfZodSchema<Catch>
96
+ : never;
@@ -32,8 +32,8 @@ export {
32
32
  int32,
33
33
  union,
34
34
  discriminatedUnion,
35
- // record,
36
- // intersection,
35
+ record,
36
+ intersection,
37
37
  int,
38
38
  codec,
39
39
  optional,
@@ -220,6 +220,9 @@ export class CoValueCoreSubscription {
220
220
 
221
221
  emit(value: RawCoValue | "unavailable"): void {
222
222
  if (this.unsubscribed) return;
223
+ if (!isReadyForEmit(value)) {
224
+ return;
225
+ }
223
226
 
224
227
  this.listener(value);
225
228
  }
@@ -234,3 +237,17 @@ export class CoValueCoreSubscription {
234
237
  this._unsubscribe();
235
238
  }
236
239
  }
240
+
241
+ /**
242
+ * This is true if the value is unavailable, or if the value is a binary coValue or a completely downloaded coValue.
243
+ */
244
+ function isReadyForEmit(value: RawCoValue | "unavailable") {
245
+ if (value === "unavailable") {
246
+ return true;
247
+ }
248
+
249
+ return (
250
+ value.core.verified?.header.meta?.type === "binary" ||
251
+ value.core.isCompletelyDownloaded()
252
+ );
253
+ }
@@ -79,11 +79,7 @@ export class SubscriptionScope<D extends CoValue> {
79
79
  // - Run the migration only once
80
80
  // - Skip all the updates until the migration is done
81
81
  // - Trigger handleUpdate only with the final value
82
- if (
83
- !this.migrated &&
84
- value !== "unavailable" &&
85
- !value.core.verified.isStreaming()
86
- ) {
82
+ if (!this.migrated && value !== "unavailable") {
87
83
  if (this.migrating) {
88
84
  return;
89
85
  }
@@ -272,10 +268,6 @@ export class SubscriptionScope<D extends CoValue> {
272
268
  // If the value is in error, we send the update regardless of the children statuses
273
269
  if (this.value.type !== "loaded") return true;
274
270
 
275
- if (this.isStreaming() && !this.isFileStream()) {
276
- return false;
277
- }
278
-
279
271
  return this.pendingLoadedChildren.size === 0;
280
272
  }
281
273
 
@@ -304,24 +296,6 @@ export class SubscriptionScope<D extends CoValue> {
304
296
  return undefined;
305
297
  }
306
298
 
307
- isStreaming() {
308
- if (this.value.type !== "loaded") {
309
- return false;
310
- }
311
-
312
- return this.value.value.$jazz.raw.core.verified.isStreaming();
313
- }
314
-
315
- isFileStream() {
316
- if (this.value.type !== "loaded") {
317
- return false;
318
- }
319
-
320
- return (
321
- this.value.value.$jazz.raw.core.verified.header.meta?.type === "binary"
322
- );
323
- }
324
-
325
299
  triggerUpdate() {
326
300
  if (!this.shouldSendUpdates()) return;
327
301
  if (!this.dirty) return;
@@ -385,3 +385,10 @@ export async function setupJazzTestSync({
385
385
 
386
386
  return account;
387
387
  }
388
+
389
+ export function disableJazzTestSync() {
390
+ if (syncServer.current) {
391
+ syncServer.current.gracefulShutdown();
392
+ }
393
+ syncServer.current = null;
394
+ }