jazz-tools 0.18.38 → 0.19.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 (304) hide show
  1. package/.svelte-kit/__package__/jazz.class.svelte.d.ts +8 -8
  2. package/.svelte-kit/__package__/jazz.class.svelte.d.ts.map +1 -1
  3. package/.svelte-kit/__package__/jazz.class.svelte.js +39 -14
  4. package/.svelte-kit/__package__/media/image.svelte +6 -5
  5. package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
  6. package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.d.ts +2 -0
  7. package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.d.ts.map +1 -0
  8. package/.svelte-kit/__package__/tests/AccountCoState.svelte.test-d.js +19 -0
  9. package/.svelte-kit/__package__/tests/CoState.svelte.test-d.d.ts +2 -0
  10. package/.svelte-kit/__package__/tests/CoState.svelte.test-d.d.ts.map +1 -0
  11. package/.svelte-kit/__package__/tests/CoState.svelte.test-d.js +16 -0
  12. package/.svelte-kit/__package__/tests/CoState.svelte.test.d.ts +2 -0
  13. package/.svelte-kit/__package__/tests/CoState.svelte.test.d.ts.map +1 -0
  14. package/.svelte-kit/__package__/tests/CoState.svelte.test.js +42 -0
  15. package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte +23 -0
  16. package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte.d.ts +12 -0
  17. package/.svelte-kit/__package__/tests/TestCoStateWrapper.svelte.d.ts.map +1 -0
  18. package/.turbo/turbo-build.log +62 -62
  19. package/CHANGELOG.md +32 -0
  20. package/dist/better-auth/database-adapter/index.js +14 -11
  21. package/dist/better-auth/database-adapter/index.js.map +1 -1
  22. package/dist/better-auth/database-adapter/repository/generic.d.ts +1 -1
  23. package/dist/better-auth/database-adapter/repository/generic.d.ts.map +1 -1
  24. package/dist/better-auth/database-adapter/repository/user.d.ts.map +1 -1
  25. package/dist/{chunk-OSQ7S47Q.js → chunk-NCNM6UDZ.js} +563 -252
  26. package/dist/chunk-NCNM6UDZ.js.map +1 -0
  27. package/dist/index.js +14 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/media/{chunk-K6GCHLQU.js → chunk-3LKBM3G3.js} +23 -15
  30. package/dist/media/chunk-3LKBM3G3.js.map +1 -0
  31. package/dist/media/create-image/browser.d.ts +2 -2
  32. package/dist/media/create-image/react-native.d.ts +2 -2
  33. package/dist/media/create-image/server.d.ts +2 -2
  34. package/dist/media/create-image-factory.d.ts +2 -2
  35. package/dist/media/index.browser.js +1 -1
  36. package/dist/media/index.js +1 -1
  37. package/dist/media/index.native.js +1 -1
  38. package/dist/media/index.server.js +1 -1
  39. package/dist/media/utils.d.ts.map +1 -1
  40. package/dist/react/hooks.d.ts +1 -1
  41. package/dist/react/hooks.d.ts.map +1 -1
  42. package/dist/react/index.d.ts +1 -1
  43. package/dist/react/index.d.ts.map +1 -1
  44. package/dist/react/index.js +31 -15
  45. package/dist/react/index.js.map +1 -1
  46. package/dist/react/media/image.d.ts.map +1 -1
  47. package/dist/react-core/hooks.d.ts +126 -224
  48. package/dist/react-core/hooks.d.ts.map +1 -1
  49. package/dist/react-core/index.js +65 -63
  50. package/dist/react-core/index.js.map +1 -1
  51. package/dist/react-core/subscription-provider.d.ts.map +1 -1
  52. package/dist/react-core/tests/createCoValueSubscriptionContext.test.d.ts +2 -0
  53. package/dist/react-core/tests/createCoValueSubscriptionContext.test.d.ts.map +1 -0
  54. package/dist/react-core/tests/useAccount.selector.test.d.ts +2 -0
  55. package/dist/react-core/tests/useAccount.selector.test.d.ts.map +1 -0
  56. package/dist/react-core/tests/useCoState.selector.test.d.ts +2 -0
  57. package/dist/react-core/tests/useCoState.selector.test.d.ts.map +1 -0
  58. package/dist/react-native-core/hooks.d.ts +1 -1
  59. package/dist/react-native-core/hooks.d.ts.map +1 -1
  60. package/dist/react-native-core/index.js +7 -5
  61. package/dist/react-native-core/index.js.map +1 -1
  62. package/dist/react-native-core/media/image.d.ts.map +1 -1
  63. package/dist/svelte/jazz.class.svelte.d.ts +8 -8
  64. package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
  65. package/dist/svelte/jazz.class.svelte.js +39 -14
  66. package/dist/svelte/media/image.svelte +6 -5
  67. package/dist/svelte/media/image.svelte.d.ts.map +1 -1
  68. package/dist/svelte/tests/AccountCoState.svelte.test-d.d.ts +2 -0
  69. package/dist/svelte/tests/AccountCoState.svelte.test-d.d.ts.map +1 -0
  70. package/dist/svelte/tests/AccountCoState.svelte.test-d.js +19 -0
  71. package/dist/svelte/tests/CoState.svelte.test-d.d.ts +2 -0
  72. package/dist/svelte/tests/CoState.svelte.test-d.d.ts.map +1 -0
  73. package/dist/svelte/tests/CoState.svelte.test-d.js +16 -0
  74. package/dist/svelte/tests/CoState.svelte.test.d.ts +2 -0
  75. package/dist/svelte/tests/CoState.svelte.test.d.ts.map +1 -0
  76. package/dist/svelte/tests/CoState.svelte.test.js +42 -0
  77. package/dist/svelte/tests/TestCoStateWrapper.svelte +23 -0
  78. package/dist/svelte/tests/TestCoStateWrapper.svelte.d.ts +12 -0
  79. package/dist/svelte/tests/TestCoStateWrapper.svelte.d.ts.map +1 -0
  80. package/dist/testing.js +3 -1
  81. package/dist/testing.js.map +1 -1
  82. package/dist/tools/coValues/CoValueBase.d.ts +4 -1
  83. package/dist/tools/coValues/CoValueBase.d.ts.map +1 -1
  84. package/dist/tools/coValues/account.d.ts +6 -6
  85. package/dist/tools/coValues/account.d.ts.map +1 -1
  86. package/dist/tools/coValues/coFeed.d.ts +5 -5
  87. package/dist/tools/coValues/coFeed.d.ts.map +1 -1
  88. package/dist/tools/coValues/coList.d.ts +9 -8
  89. package/dist/tools/coValues/coList.d.ts.map +1 -1
  90. package/dist/tools/coValues/coMap.d.ts +17 -17
  91. package/dist/tools/coValues/coMap.d.ts.map +1 -1
  92. package/dist/tools/coValues/coPlainText.d.ts +3 -3
  93. package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
  94. package/dist/tools/coValues/coVector.d.ts +3 -3
  95. package/dist/tools/coValues/coVector.d.ts.map +1 -1
  96. package/dist/tools/coValues/deepLoading.d.ts +71 -40
  97. package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
  98. package/dist/tools/coValues/extensions/imageDef.d.ts +1 -1
  99. package/dist/tools/coValues/extensions/imageDef.d.ts.map +1 -1
  100. package/dist/tools/coValues/group.d.ts +2 -2
  101. package/dist/tools/coValues/group.d.ts.map +1 -1
  102. package/dist/tools/coValues/inbox.d.ts.map +1 -1
  103. package/dist/tools/coValues/interfaces.d.ts +17 -9
  104. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  105. package/dist/tools/coValues/request.d.ts.map +1 -1
  106. package/dist/tools/coValues/schemaUnion.d.ts +6 -9
  107. package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
  108. package/dist/tools/exports.d.ts +3 -3
  109. package/dist/tools/exports.d.ts.map +1 -1
  110. package/dist/tools/implementation/refs.d.ts +3 -3
  111. package/dist/tools/implementation/refs.d.ts.map +1 -1
  112. package/dist/tools/implementation/schema.d.ts +2 -2
  113. package/dist/tools/implementation/schema.d.ts.map +1 -1
  114. package/dist/tools/implementation/schemaUtils.d.ts +8 -0
  115. package/dist/tools/implementation/schemaUtils.d.ts.map +1 -1
  116. package/dist/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.d.ts.map +1 -1
  117. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +33 -18
  118. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  119. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +19 -7
  120. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
  121. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +23 -12
  122. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
  123. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +29 -18
  124. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
  125. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +39 -22
  126. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
  127. package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts +1 -0
  128. package/dist/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.d.ts.map +1 -1
  129. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +30 -19
  130. package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
  131. package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts +5 -0
  132. package/dist/tools/implementation/zodSchema/schemaTypes/CoValueSchema.d.ts.map +1 -1
  133. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts +6 -5
  134. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts.map +1 -1
  135. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +3 -2
  136. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
  137. package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts +3 -2
  138. package/dist/tools/implementation/zodSchema/schemaTypes/GroupSchema.d.ts.map +1 -1
  139. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +3 -2
  140. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
  141. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +3 -2
  142. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
  143. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +3 -0
  144. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
  145. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts +22 -0
  146. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesMaybeLoaded.d.ts.map +1 -0
  147. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts +4 -0
  148. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.d.ts.map +1 -1
  149. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.d.ts +9 -0
  150. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.d.ts.map +1 -0
  151. package/dist/tools/implementation/zodSchema/unionUtils.d.ts.map +1 -1
  152. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  153. package/dist/tools/implementation/zodSchema/zodSchema.d.ts +7 -6
  154. package/dist/tools/implementation/zodSchema/zodSchema.d.ts.map +1 -1
  155. package/dist/tools/internal.d.ts +3 -3
  156. package/dist/tools/internal.d.ts.map +1 -1
  157. package/dist/tools/lib/utils.d.ts +14 -0
  158. package/dist/tools/lib/utils.d.ts.map +1 -0
  159. package/dist/tools/lib/utils.test.d.ts +2 -0
  160. package/dist/tools/lib/utils.test.d.ts.map +1 -0
  161. package/dist/tools/subscribe/CoValueCoreSubscription.d.ts +3 -2
  162. package/dist/tools/subscribe/CoValueCoreSubscription.d.ts.map +1 -1
  163. package/dist/tools/subscribe/JazzError.d.ts +4 -3
  164. package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
  165. package/dist/tools/subscribe/SubscriptionScope.d.ts +7 -5
  166. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  167. package/dist/tools/subscribe/index.d.ts.map +1 -1
  168. package/dist/tools/subscribe/types.d.ts +23 -3
  169. package/dist/tools/subscribe/types.d.ts.map +1 -1
  170. package/dist/tools/subscribe/utils.d.ts.map +1 -1
  171. package/dist/tools/testing.d.ts +3 -2
  172. package/dist/tools/testing.d.ts.map +1 -1
  173. package/dist/tools/tests/schema.resolved.test.d.ts +2 -0
  174. package/dist/tools/tests/schema.resolved.test.d.ts.map +1 -0
  175. package/dist/tools/tests/utils.d.ts +2 -1
  176. package/dist/tools/tests/utils.d.ts.map +1 -1
  177. package/package.json +4 -4
  178. package/src/better-auth/database-adapter/index.ts +2 -2
  179. package/src/better-auth/database-adapter/repository/account.ts +3 -3
  180. package/src/better-auth/database-adapter/repository/generic.ts +9 -6
  181. package/src/better-auth/database-adapter/repository/user.ts +6 -2
  182. package/src/better-auth/database-adapter/schema.ts +1 -1
  183. package/src/better-auth/database-adapter/tests/index.test.ts +3 -4
  184. package/src/inspector/tests/viewer/history-view.test.tsx +6 -2
  185. package/src/media/utils.test.ts +5 -0
  186. package/src/media/utils.ts +25 -16
  187. package/src/react/hooks.tsx +2 -2
  188. package/src/react/index.ts +2 -2
  189. package/src/react/media/image.tsx +10 -2
  190. package/src/react/tests/useAcceptInvite.test.ts +3 -1
  191. package/src/react-core/hooks.ts +226 -304
  192. package/src/react-core/subscription-provider.tsx +14 -7
  193. package/src/react-core/tests/createCoValueSubscriptionContext.test.tsx +233 -0
  194. package/src/react-core/tests/subscription.bench.tsx +32 -15
  195. package/src/react-core/tests/{useAccountWithSelector.test.ts → useAccount.selector.test.ts} +72 -24
  196. package/src/react-core/tests/useAccount.test.ts +92 -106
  197. package/src/react-core/tests/{useCoStateWithSelector.test.ts → useCoState.selector.test.ts} +23 -8
  198. package/src/react-core/tests/useCoState.test.ts +173 -49
  199. package/src/react-core/tests/useInboxSender.test.ts +3 -1
  200. package/src/react-core/tests/usePassPhraseAuth.test.ts +11 -82
  201. package/src/react-core/tests/useSubscriptionSelector.test.ts +48 -14
  202. package/src/react-native-core/hooks.tsx +2 -2
  203. package/src/react-native-core/media/image.tsx +3 -1
  204. package/src/svelte/jazz.class.svelte.ts +103 -27
  205. package/src/svelte/media/image.svelte +6 -5
  206. package/src/svelte/tests/AccountCoState.svelte.test-d.ts +23 -0
  207. package/src/svelte/tests/CoState.svelte.test-d.ts +20 -0
  208. package/src/svelte/tests/CoState.svelte.test.ts +57 -0
  209. package/src/svelte/tests/TestCoStateWrapper.svelte +23 -0
  210. package/src/tools/coValues/CoValueBase.ts +12 -0
  211. package/src/tools/coValues/account.ts +17 -12
  212. package/src/tools/coValues/coFeed.ts +38 -15
  213. package/src/tools/coValues/coList.ts +17 -12
  214. package/src/tools/coValues/coMap.ts +15 -14
  215. package/src/tools/coValues/coPlainText.ts +6 -3
  216. package/src/tools/coValues/coVector.ts +6 -5
  217. package/src/tools/coValues/deepLoading.ts +147 -86
  218. package/src/tools/coValues/group.ts +3 -2
  219. package/src/tools/coValues/inbox.ts +11 -10
  220. package/src/tools/coValues/interfaces.ts +52 -30
  221. package/src/tools/coValues/request.ts +8 -6
  222. package/src/tools/coValues/schemaUnion.ts +20 -14
  223. package/src/tools/exports.ts +11 -1
  224. package/src/tools/implementation/refs.ts +19 -13
  225. package/src/tools/implementation/schema.ts +5 -4
  226. package/src/tools/implementation/schemaUtils.ts +15 -0
  227. package/src/tools/implementation/zodSchema/runtimeConverters/coValueSchemaTransformation.ts +4 -4
  228. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +131 -95
  229. package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +86 -16
  230. package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +73 -22
  231. package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +86 -28
  232. package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +204 -148
  233. package/src/tools/implementation/zodSchema/schemaTypes/CoOptionalSchema.ts +1 -0
  234. package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +71 -27
  235. package/src/tools/implementation/zodSchema/schemaTypes/CoValueSchema.ts +7 -0
  236. package/src/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.ts +8 -6
  237. package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +4 -1
  238. package/src/tools/implementation/zodSchema/schemaTypes/GroupSchema.ts +4 -1
  239. package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +4 -1
  240. package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +4 -1
  241. package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +3 -0
  242. package/src/tools/implementation/zodSchema/typeConverters/{InstanceOfSchemaCoValuesNullable.ts → InstanceOfSchemaCoValuesMaybeLoaded.ts} +47 -39
  243. package/src/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchema.ts +4 -0
  244. package/src/tools/implementation/zodSchema/typeConverters/{InstanceOrPrimitiveOfSchemaCoValuesNullable.ts → InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.ts} +7 -3
  245. package/src/tools/implementation/zodSchema/unionUtils.ts +35 -4
  246. package/src/tools/implementation/zodSchema/zodSchema.ts +15 -7
  247. package/src/tools/internal.ts +3 -3
  248. package/src/tools/lib/utils.test.ts +56 -0
  249. package/src/tools/lib/utils.ts +32 -0
  250. package/src/tools/subscribe/CoValueCoreSubscription.ts +13 -8
  251. package/src/tools/subscribe/JazzError.ts +8 -2
  252. package/src/tools/subscribe/SubscriptionScope.ts +57 -57
  253. package/src/tools/subscribe/index.ts +12 -4
  254. package/src/tools/subscribe/types.ts +36 -2
  255. package/src/tools/subscribe/utils.ts +2 -1
  256. package/src/tools/testing.ts +5 -0
  257. package/src/tools/tests/CoValueCoreSubscription.test.ts +10 -4
  258. package/src/tools/tests/ContextManager.test.ts +12 -5
  259. package/src/tools/tests/account.test.ts +22 -12
  260. package/src/tools/tests/coDiscriminatedUnion.test.ts +354 -8
  261. package/src/tools/tests/coFeed.branch.test.ts +48 -32
  262. package/src/tools/tests/coFeed.test-d.ts +17 -10
  263. package/src/tools/tests/coFeed.test.ts +52 -30
  264. package/src/tools/tests/coList.branch.test.ts +21 -21
  265. package/src/tools/tests/coList.test-d.ts +39 -23
  266. package/src/tools/tests/coList.test.ts +51 -25
  267. package/src/tools/tests/coList.unique.test.ts +34 -29
  268. package/src/tools/tests/coMap.branch.test.ts +20 -21
  269. package/src/tools/tests/coMap.record.test-d.ts +28 -26
  270. package/src/tools/tests/coMap.record.test.ts +30 -20
  271. package/src/tools/tests/coMap.test-d.ts +31 -29
  272. package/src/tools/tests/coMap.test.ts +67 -40
  273. package/src/tools/tests/coMap.unique.test.ts +25 -24
  274. package/src/tools/tests/coVector.test.ts +29 -15
  275. package/src/tools/tests/createContext.test.ts +5 -3
  276. package/src/tools/tests/deepLoading.test.ts +369 -176
  277. package/src/tools/tests/exportImport.test.ts +16 -15
  278. package/src/tools/tests/groupsAndAccounts.test.ts +39 -16
  279. package/src/tools/tests/inbox.test.ts +3 -1
  280. package/src/tools/tests/load.test.ts +29 -23
  281. package/src/tools/tests/patterns/quest.test.ts +3 -2
  282. package/src/tools/tests/patterns/requestToJoin.test.ts +17 -17
  283. package/src/tools/tests/request.test.ts +12 -2
  284. package/src/tools/tests/schema.resolved.test.ts +792 -0
  285. package/src/tools/tests/schemaUnion.test.ts +7 -3
  286. package/src/tools/tests/subscribe.test.ts +39 -21
  287. package/src/tools/tests/testing.test.ts +3 -2
  288. package/src/tools/tests/utils.ts +15 -2
  289. package/dist/chunk-OSQ7S47Q.js.map +0 -1
  290. package/dist/media/chunk-K6GCHLQU.js.map +0 -1
  291. package/dist/react-core/tests/useAccountWithSelector.test.d.ts +0 -2
  292. package/dist/react-core/tests/useAccountWithSelector.test.d.ts.map +0 -1
  293. package/dist/react-core/tests/useCoStateWithSelector.test.d.ts +0 -2
  294. package/dist/react-core/tests/useCoStateWithSelector.test.d.ts.map +0 -1
  295. package/dist/tools/implementation/errors.d.ts +0 -2
  296. package/dist/tools/implementation/errors.d.ts.map +0 -1
  297. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +0 -19
  298. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +0 -1
  299. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts +0 -5
  300. package/dist/tools/implementation/zodSchema/typeConverters/InstanceOrPrimitiveOfSchemaCoValuesNullable.d.ts.map +0 -1
  301. package/dist/tools/lib/id.d.ts +0 -2
  302. package/dist/tools/lib/id.d.ts.map +0 -1
  303. package/src/tools/implementation/errors.ts +0 -1
  304. package/src/tools/lib/id.ts +0 -3
@@ -9,9 +9,19 @@ import {
9
9
  isControlledAccount,
10
10
  z,
11
11
  } from "../index.js";
12
- import { Account, Loaded, co, randomSessionProvider } from "../internal.js";
12
+ import {
13
+ Account,
14
+ CoList,
15
+ Loaded,
16
+ MaybeLoaded,
17
+ NotLoaded,
18
+ co,
19
+ randomSessionProvider,
20
+ CoValueLoadingState,
21
+ NotLoadedCoValueState,
22
+ } from "../internal.js";
13
23
  import { createJazzTestAccount, linkAccounts } from "../testing.js";
14
- import { waitFor } from "./utils.js";
24
+ import { assertLoaded, waitFor } from "./utils.js";
15
25
 
16
26
  const Crypto = await WasmCrypto.create();
17
27
  const { connectedPeers } = cojsonInternals;
@@ -83,11 +93,16 @@ describe("Deep loading with depth arg", async () => {
83
93
 
84
94
  test("load without resolve", async () => {
85
95
  const map1 = await TestMap.load(map.$jazz.id, { loadAs: meOnSecondPeer });
86
- expectTypeOf(map1).branded.toEqualTypeOf<Loaded<typeof TestMap> | null>();
87
96
 
88
- assert(map1, "map1 is null");
97
+ type ExpectedType = MaybeLoaded<Loaded<typeof TestMap>>;
98
+ function matches(value: ExpectedType) {
99
+ return value;
100
+ }
101
+ matches(map1);
102
+
103
+ assertLoaded(map1);
89
104
 
90
- expect(map1.list).toBe(null);
105
+ expect(map1.list.$jazz.loadingState).toBe(CoValueLoadingState.LOADING);
91
106
  });
92
107
 
93
108
  test("load with resolve { list: true }", async () => {
@@ -95,15 +110,18 @@ describe("Deep loading with depth arg", async () => {
95
110
  loadAs: meOnSecondPeer,
96
111
  resolve: { list: true },
97
112
  });
98
- expectTypeOf(map2).branded.toEqualTypeOf<
99
- | (Loaded<typeof TestMap> & {
100
- readonly list: Loaded<typeof TestList>;
101
- })
102
- | null
103
- >();
104
- assert(map2, "map2 is null");
105
- expect(map2.list).toBeTruthy();
106
- expect(map2.list[0]).toBe(null);
113
+ type ExpectedType = MaybeLoaded<
114
+ Loaded<typeof TestMap> & {
115
+ readonly list: Loaded<typeof TestList>;
116
+ }
117
+ >;
118
+ function matches(value: ExpectedType) {
119
+ return value;
120
+ }
121
+ matches(map2);
122
+ assertLoaded(map2);
123
+ assertLoaded(map2.list);
124
+ expect(map2.list[0]?.$jazz.loadingState).toBe(CoValueLoadingState.LOADING);
107
125
  });
108
126
 
109
127
  test("load with resolve { list: { $each: true } }", async () => {
@@ -111,16 +129,21 @@ describe("Deep loading with depth arg", async () => {
111
129
  loadAs: meOnSecondPeer,
112
130
  resolve: { list: { $each: true } },
113
131
  });
114
- expectTypeOf(map3).toEqualTypeOf<
115
- | (Loaded<typeof TestMap> & {
116
- readonly list: Loaded<typeof TestList> &
117
- ReadonlyArray<Loaded<typeof InnerMap>>;
118
- })
119
- | null
120
- >();
121
- assert(map3, "map3 is null");
122
- expect(map3.list[0]).toBeTruthy();
123
- expect(map3.list[0]?.stream).toBe(null);
132
+ type ExpectedType = MaybeLoaded<
133
+ Loaded<typeof TestMap> & {
134
+ readonly list: Loaded<typeof TestList> &
135
+ ReadonlyArray<Loaded<typeof InnerMap>>;
136
+ }
137
+ >;
138
+ function matches(value: ExpectedType) {
139
+ return value;
140
+ }
141
+ matches(map3);
142
+ assertLoaded(map3);
143
+ assert(map3.list[0]);
144
+ expect(map3.list[0].stream.$jazz.loadingState).toBe(
145
+ CoValueLoadingState.LOADING,
146
+ );
124
147
  });
125
148
 
126
149
  test("load with resolve { optionalRef: true }", async () => {
@@ -128,14 +151,16 @@ describe("Deep loading with depth arg", async () => {
128
151
  loadAs: meOnSecondPeer,
129
152
  resolve: { optionalRef: true } as const,
130
153
  });
131
- expectTypeOf(map3a).branded.toEqualTypeOf<
132
- | (Loaded<typeof TestMap> & {
133
- readonly optionalRef: Loaded<typeof InnermostMap> | undefined;
134
- })
135
- | null
136
- >();
137
- assert(map3a, "map3a is null");
138
- expect(map3a).toBeTruthy();
154
+ type ExpectedType = MaybeLoaded<
155
+ Loaded<typeof TestMap> & {
156
+ readonly optionalRef: Loaded<typeof InnermostMap> | undefined;
157
+ }
158
+ >;
159
+ function matches(value: ExpectedType) {
160
+ return value;
161
+ }
162
+ matches(map3a);
163
+ assertLoaded(map3a);
139
164
  });
140
165
 
141
166
  test("load with resolve { list: { $each: { stream: true } } }", async () => {
@@ -143,21 +168,26 @@ describe("Deep loading with depth arg", async () => {
143
168
  loadAs: meOnSecondPeer,
144
169
  resolve: { list: { $each: { stream: true } } },
145
170
  });
146
- expectTypeOf(map4).toEqualTypeOf<
147
- | (Loaded<typeof TestMap> & {
148
- readonly list: Loaded<typeof TestList> &
149
- ReadonlyArray<
150
- Loaded<typeof InnerMap> & {
151
- readonly stream: Loaded<typeof TestFeed>;
152
- }
153
- >;
154
- })
155
- | null
156
- >();
157
- assert(map4, "map4 is null");
171
+ type ExpectedType = MaybeLoaded<
172
+ Loaded<typeof TestMap> & {
173
+ readonly list: Loaded<typeof TestList> &
174
+ ReadonlyArray<
175
+ Loaded<typeof InnerMap> & {
176
+ readonly stream: Loaded<typeof TestFeed>;
177
+ }
178
+ >;
179
+ }
180
+ >;
181
+ function matches(value: ExpectedType) {
182
+ return value;
183
+ }
184
+ matches(map4);
185
+ assertLoaded(map4);
158
186
  expect(map4.list[0]?.stream).toBeTruthy();
159
187
  expect(map4.list[0]?.stream?.perAccount[me.$jazz.id]).toBeTruthy();
160
- expect(map4.list[0]?.stream?.byMe?.value).toBe(null);
188
+ expect(map4.list[0]?.stream?.byMe?.value.$jazz.loadingState).toBe(
189
+ CoValueLoadingState.LOADING,
190
+ );
161
191
  });
162
192
 
163
193
  test("load with resolve { list: { $each: { stream: { $each: true } } } }", async () => {
@@ -165,28 +195,31 @@ describe("Deep loading with depth arg", async () => {
165
195
  loadAs: meOnSecondPeer,
166
196
  resolve: { list: { $each: { stream: { $each: true } } } },
167
197
  });
168
- type ExpectedMap5 =
169
- | (Loaded<typeof TestMap> & {
170
- readonly list: Loaded<typeof TestList> &
171
- ReadonlyArray<
172
- Loaded<typeof InnerMap> & {
173
- readonly stream: Loaded<typeof TestFeed> & {
174
- byMe?: { value: Loaded<typeof InnermostMap> };
175
- inCurrentSession?: { value: Loaded<typeof InnermostMap> };
176
- perSession: {
177
- [sessionID: SessionID]: {
178
- value: Loaded<typeof InnermostMap>;
179
- };
198
+ type ExpectedMap5 = MaybeLoaded<
199
+ Loaded<typeof TestMap> & {
200
+ readonly list: Loaded<typeof TestList> &
201
+ ReadonlyArray<
202
+ Loaded<typeof InnerMap> & {
203
+ readonly stream: Loaded<typeof TestFeed> & {
204
+ byMe?: { value: Loaded<typeof InnermostMap> };
205
+ inCurrentSession?: { value: Loaded<typeof InnermostMap> };
206
+ perSession: {
207
+ [sessionID: SessionID]: {
208
+ value: Loaded<typeof InnermostMap>;
180
209
  };
181
- } & {
182
- [key: ID<Account>]: { value: Loaded<typeof InnermostMap> };
183
210
  };
184
- }
185
- >;
186
- })
187
- | null;
188
- expectTypeOf(map5).toEqualTypeOf<ExpectedMap5>();
189
- assert(map5, "map5 is null");
211
+ } & {
212
+ [key: ID<Account>]: { value: Loaded<typeof InnermostMap> };
213
+ };
214
+ }
215
+ >;
216
+ }
217
+ >;
218
+ function matches(value: ExpectedMap5) {
219
+ return value;
220
+ }
221
+ matches(map5);
222
+ assertLoaded(map5);
190
223
 
191
224
  expect(map5.list[0]?.stream?.perAccount[me.$jazz.id]?.value).toBeTruthy();
192
225
  expect(map5.list[0]?.stream?.byMe?.value).toBeTruthy();
@@ -311,71 +344,66 @@ test("Deep loading a record-like coMap", async () => {
311
344
  $each: { list: { $each: true } },
312
345
  },
313
346
  });
314
- expectTypeOf(recordLoaded).toEqualTypeOf<
315
- | (Loaded<typeof RecordLike> & {
347
+ expectTypeOf(recordLoaded).branded.toEqualTypeOf<
348
+ MaybeLoaded<
349
+ Loaded<typeof RecordLike> & {
316
350
  readonly [key: string]: Loaded<typeof TestMap> & {
317
351
  readonly list: Loaded<typeof TestList> &
318
352
  ReadonlyArray<Loaded<typeof InnerMap>>;
319
353
  };
320
- })
321
- | null
354
+ }
355
+ >
322
356
  >();
323
- assert(recordLoaded, "recordLoaded is null");
357
+ assertLoaded(recordLoaded);
324
358
  expect(recordLoaded.key1?.list).not.toBe(null);
325
359
  expect(recordLoaded.key1?.list).toBeTruthy();
326
360
  expect(recordLoaded.key2?.list).not.toBe(null);
327
361
  expect(recordLoaded.key2?.list).toBeTruthy();
328
362
  });
329
363
 
330
- test("The resolve type doesn't accept extra keys", async () => {
331
- expect.assertions(1);
332
-
364
+ test("The resolve type doesn't accept extra keys, but the load resolves anyway", async () => {
333
365
  const me = await CustomAccount.create({
334
366
  creationProps: { name: "Hermes Puggington" },
335
367
  crypto: Crypto,
336
368
  });
337
369
 
338
- try {
339
- const meLoaded = await me.$jazz.ensureLoaded({
340
- resolve: {
341
- // @ts-expect-error
342
- profile: { stream: true, extraKey: true },
343
- // @ts-expect-error
344
- root: { list: true, extraKey: true },
345
- },
346
- });
370
+ const meLoaded = await me.$jazz.ensureLoaded({
371
+ resolve: {
372
+ // @ts-expect-error
373
+ profile: { stream: true, extraKey: true },
374
+ // @ts-expect-error
375
+ root: { list: true, extraKey: true },
376
+ },
377
+ });
347
378
 
348
- await me.$jazz.ensureLoaded({
349
- resolve: {
350
- // @ts-expect-error
351
- root: { list: { $each: true, extraKey: true } },
352
- },
353
- });
379
+ await me.$jazz.ensureLoaded({
380
+ resolve: {
381
+ // @ts-expect-error
382
+ root: { list: { $each: true, extraKey: true } },
383
+ },
384
+ });
354
385
 
355
- await me.$jazz.ensureLoaded({
356
- resolve: {
357
- root: { list: true },
358
- // @ts-expect-error
359
- extraKey: true,
360
- },
361
- });
386
+ await me.$jazz.ensureLoaded({
387
+ resolve: {
388
+ root: { list: true },
389
+ // @ts-expect-error
390
+ extraKey: true,
391
+ },
392
+ });
362
393
 
363
- // using assignment to check type compatibility
364
- const _T:
365
- | (Loaded<typeof CustomAccount> & {
366
- profile: Loaded<typeof CustomProfile> & {
367
- stream: Loaded<typeof TestFeed>;
368
- extraKey: never;
369
- };
370
- root: Loaded<typeof TestMap> & {
371
- list: Loaded<typeof TestList>;
372
- extraKey: never;
373
- };
374
- })
375
- | null = meLoaded;
376
- } catch (e) {
377
- expect(e).toBeInstanceOf(Error);
378
- }
394
+ // using assignment to check type compatibility
395
+ const _T:
396
+ | (Loaded<typeof CustomAccount> & {
397
+ profile: Loaded<typeof CustomProfile> & {
398
+ stream: Loaded<typeof TestFeed>;
399
+ extraKey: never;
400
+ };
401
+ root: Loaded<typeof TestMap> & {
402
+ list: Loaded<typeof TestList>;
403
+ extraKey: never;
404
+ };
405
+ })
406
+ | null = meLoaded;
379
407
  });
380
408
 
381
409
  test("The resolve type accepts keys from optional fields", async () => {
@@ -401,7 +429,7 @@ test("The resolve type accepts keys from optional fields", async () => {
401
429
  expect(pets[0]?.owner?.name).toEqual("Rex");
402
430
  });
403
431
 
404
- test("The resolve type doesn't accept keys from discriminated unions", async () => {
432
+ test("The resolve type accepts keys from discriminated unions", async () => {
405
433
  const Person = co.map({
406
434
  name: z.string(),
407
435
  });
@@ -415,24 +443,25 @@ test("The resolve type doesn't accept keys from discriminated unions", async ()
415
443
  const Pet = co.discriminatedUnion("type", [Dog, Cat]);
416
444
  const Pets = co.list(Pet);
417
445
 
418
- const pets = await Pets.create([
446
+ const pets = Pets.create([
419
447
  Dog.create({ type: "dog", owner: Person.create({ name: "Rex" }) }),
448
+ Cat.create({ type: "cat" }),
420
449
  ]);
421
450
 
422
451
  await pets.$jazz.ensureLoaded({
423
- resolve: {
424
- $each: true,
425
- },
426
- });
427
-
428
- await pets.$jazz.ensureLoaded({
429
- // @ts-expect-error cannot resolve owner
430
452
  resolve: { $each: { owner: true } },
431
453
  });
432
454
 
433
455
  expect(pets).toBeTruthy();
434
- if (pets?.[0]?.type === "dog") {
435
- expect(pets[0].owner?.name).toEqual("Rex");
456
+
457
+ for (const pet of pets) {
458
+ if (pet.type === "dog") {
459
+ expect(pet.owner?.name).toEqual("Rex");
460
+ } else {
461
+ expect("owner" in pet).toEqual(false);
462
+ // @ts-expect-error - this should still not appear in the types
463
+ expect(pet.owner).toBeUndefined();
464
+ }
436
465
  }
437
466
  });
438
467
 
@@ -461,7 +490,9 @@ describe("Deep loading with unauthorized account", async () => {
461
490
 
462
491
  const mapOnAlice = await TestMap.load(map.$jazz.id, { loadAs: alice });
463
492
 
464
- expect(mapOnAlice).toBe(null);
493
+ expect(mapOnAlice.$jazz.loadingState).toBe(
494
+ CoValueLoadingState.UNAUTHORIZED,
495
+ );
465
496
 
466
497
  expect(errorSpy).toHaveBeenCalledWith(
467
498
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id}`,
@@ -483,7 +514,9 @@ describe("Deep loading with unauthorized account", async () => {
483
514
  loadAs: alice,
484
515
  });
485
516
 
486
- expect(mapWithListOnAlice).toBe(null);
517
+ expect(mapWithListOnAlice.$jazz.loadingState).toBe(
518
+ CoValueLoadingState.UNAUTHORIZED,
519
+ );
487
520
 
488
521
  expect(errorSpy).toHaveBeenCalledWith(
489
522
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id} on path list`,
@@ -517,7 +550,9 @@ describe("Deep loading with unauthorized account", async () => {
517
550
  loadAs: alice,
518
551
  });
519
552
 
520
- expect(mapOnAlice).toBe(null);
553
+ expect(mapOnAlice.$jazz.loadingState).toBe(
554
+ CoValueLoadingState.UNAUTHORIZED,
555
+ );
521
556
 
522
557
  expect(errorSpy).toHaveBeenCalledWith(
523
558
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id} on path list.0`,
@@ -541,11 +576,9 @@ describe("Deep loading with unauthorized account", async () => {
541
576
  loadAs: alice,
542
577
  resolve: { optionalRef: true } as const,
543
578
  });
544
- expect(mapOnAlice).toBe(null);
545
-
546
- expect(mapOnAlice?.optionalRef).toBe(undefined);
547
- expect(mapOnAlice?.optionalRef?.value).toBe(undefined);
548
-
579
+ expect(mapOnAlice.$jazz.loadingState).toBe(
580
+ CoValueLoadingState.UNAUTHORIZED,
581
+ );
549
582
  expect(errorSpy).toHaveBeenCalledWith(
550
583
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id} on path optionalRef`,
551
584
  );
@@ -567,16 +600,17 @@ describe("Deep loading with unauthorized account", async () => {
567
600
  resolve: { list: true } as const,
568
601
  });
569
602
 
570
- assert(mapOnAlice, "Alice isn't able to load the map");
603
+ assertLoaded(mapOnAlice);
571
604
 
572
- const result = await new Promise((resolve) => {
573
- const unsub = mapOnAlice.$jazz.subscribe((value) => {
574
- resolve(value.optionalRef);
575
- unsub();
605
+ const result: MaybeLoaded<Loaded<typeof InnermostMap>> | undefined =
606
+ await new Promise((resolve) => {
607
+ const unsub = mapOnAlice.$jazz.subscribe((value) => {
608
+ resolve(value.optionalRef);
609
+ unsub();
610
+ });
576
611
  });
577
- });
578
612
 
579
- expect(result).toBe(null);
613
+ expect(result?.$jazz.loadingState).toBe(CoValueLoadingState.UNAUTHORIZED);
580
614
  });
581
615
 
582
616
  test("unaccessible stream", async () => {
@@ -603,7 +637,9 @@ describe("Deep loading with unauthorized account", async () => {
603
637
  loadAs: alice,
604
638
  });
605
639
 
606
- expect(mapOnAlice).toBe(null);
640
+ expect(mapOnAlice.$jazz.loadingState).toBe(
641
+ CoValueLoadingState.UNAUTHORIZED,
642
+ );
607
643
 
608
644
  expect(errorSpy).toHaveBeenCalledWith(
609
645
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id} on path list.0.stream`,
@@ -639,7 +675,9 @@ describe("Deep loading with unauthorized account", async () => {
639
675
  loadAs: alice,
640
676
  });
641
677
 
642
- expect(mapOnAlice).toBe(null);
678
+ expect(mapOnAlice.$jazz.loadingState).toBe(
679
+ CoValueLoadingState.UNAUTHORIZED,
680
+ );
643
681
 
644
682
  expect(errorSpy).toHaveBeenCalledWith(
645
683
  `The current user (${alice.$jazz.id}) is not authorized to access this value from ${map.$jazz.id} on path list.0.stream.${value.$jazz.id}`,
@@ -691,14 +729,18 @@ describe("Deep loading with unauthorized account", async () => {
691
729
  );
692
730
 
693
731
  const friendsOnAlice = await Friends.load(map.$jazz.id, {
694
- resolve: { $each: { $onError: null } },
732
+ resolve: { $each: { $onError: "catch" } },
695
733
  loadAs: alice,
696
734
  });
697
735
 
698
- assert(friendsOnAlice, "friendsOnAlice is null");
736
+ assertLoaded(friendsOnAlice);
699
737
 
700
- expect(friendsOnAlice.jane).toBeNull();
701
- expect(friendsOnAlice.alice).not.toBeNull();
738
+ expect(friendsOnAlice.jane?.$jazz.loadingState).toBe(
739
+ CoValueLoadingState.UNAUTHORIZED,
740
+ );
741
+ assert(friendsOnAlice.alice);
742
+ assertLoaded(friendsOnAlice.alice);
743
+ expect(friendsOnAlice.alice.name).toBe("Alice");
702
744
  });
703
745
 
704
746
  test("unaccessible nested record element with $onError", async () => {
@@ -727,14 +769,18 @@ describe("Deep loading with unauthorized account", async () => {
727
769
  );
728
770
 
729
771
  const user = await User.load(map.$jazz.id, {
730
- resolve: { friends: { $each: { $onError: null } } },
772
+ resolve: { friends: { $each: { $onError: "catch" } } },
731
773
  loadAs: alice,
732
774
  });
733
775
 
734
- assert(user, "user is null");
776
+ assertLoaded(user);
735
777
 
736
- expect(user.friends.jane).toBeNull();
737
- expect(user.friends.alice).not.toBeNull();
778
+ expect(user.friends.jane?.$jazz.loadingState).toBe(
779
+ CoValueLoadingState.UNAUTHORIZED,
780
+ );
781
+ assert(user.friends.alice);
782
+ assertLoaded(user.friends.alice);
783
+ expect(user.friends.alice.name).toBe("Alice");
738
784
  });
739
785
 
740
786
  test("unaccessible element down the chain with $onError on a record", async () => {
@@ -778,14 +824,20 @@ describe("Deep loading with unauthorized account", async () => {
778
824
  );
779
825
 
780
826
  const user = await User.load(map.$jazz.id, {
781
- resolve: { friends: { $each: { dog: true, $onError: null } } },
827
+ resolve: { friends: { $each: { dog: true, $onError: "catch" } } },
782
828
  loadAs: alice,
783
829
  });
784
830
 
785
- assert(user);
831
+ assertLoaded(user);
786
832
 
787
- expect(user.friends.jane).toBeNull(); // jane is null because her dog is inaccessible
788
- expect(user.friends.alice?.dog).not.toBeNull(); // alice is not null because we have read access to her and her dog
833
+ // jane is not loaded because her dog is inaccessible
834
+ expect(user.friends.jane?.$jazz.loadingState).toBe(
835
+ CoValueLoadingState.UNAUTHORIZED,
836
+ );
837
+ // alice is loaded because we have read access to her and her dog
838
+ assert(user.friends.alice);
839
+ assertLoaded(user.friends.alice);
840
+ expect(user.friends.alice.dog.name).toBe("Giggino");
789
841
  });
790
842
 
791
843
  test("unaccessible list element with $onError and $each with depth", async () => {
@@ -795,7 +847,7 @@ describe("Deep loading with unauthorized account", async () => {
795
847
  return co.optional(Friends);
796
848
  },
797
849
  });
798
- const Friends: co.List<typeof Person> = co.list(Person); // TODO: annoying that we have to annotate
850
+ const Friends = co.list(Person);
799
851
 
800
852
  const list = Friends.create(
801
853
  [
@@ -826,17 +878,19 @@ describe("Deep loading with unauthorized account", async () => {
826
878
  // The error List -> Jane -> Bob should be propagated to the list element Jane
827
879
  // and we should have [null, Alice]
828
880
  const listOnAlice = await Friends.load(list.$jazz.id, {
829
- resolve: { $each: { friends: { $each: true }, $onError: null } },
881
+ resolve: { $each: { friends: { $each: true }, $onError: "catch" } },
830
882
  loadAs: alice,
831
883
  });
832
884
 
833
- assert(listOnAlice, "listOnAlice is null");
885
+ assertLoaded(listOnAlice);
834
886
 
835
- expect(listOnAlice[0]).toBeNull();
836
- expect(listOnAlice[1]).not.toBeNull();
837
- expect(listOnAlice[1]?.name).toBe("Alice");
838
- expect(listOnAlice[1]?.friends).not.toBeNull();
839
- expect(listOnAlice[1]?.friends?.[0]?.name).toBe("Bob");
887
+ expect(listOnAlice[0]?.$jazz.loadingState).toBe(
888
+ CoValueLoadingState.UNAUTHORIZED,
889
+ );
890
+ assert(listOnAlice[1]);
891
+ assertLoaded(listOnAlice[1]);
892
+ expect(listOnAlice[1].name).toBe("Alice");
893
+ expect(listOnAlice[1].friends?.[0]?.name).toBe("Bob");
840
894
  expect(listOnAlice).toHaveLength(2);
841
895
  });
842
896
 
@@ -855,14 +909,18 @@ describe("Deep loading with unauthorized account", async () => {
855
909
  );
856
910
 
857
911
  const friendsOnAlice = await Friend.load(map.$jazz.id, {
858
- resolve: { $each: { $onError: null } },
912
+ resolve: { $each: { $onError: "catch" } },
859
913
  loadAs: alice,
860
914
  });
861
915
 
862
- assert(friendsOnAlice, "friendsOnAlice is null");
916
+ assertLoaded(friendsOnAlice);
863
917
 
864
- expect(friendsOnAlice.jane).toBeNull();
865
- expect(friendsOnAlice.alice).not.toBeNull();
918
+ expect(friendsOnAlice.jane?.$jazz.loadingState).toBe(
919
+ CoValueLoadingState.UNAUTHORIZED,
920
+ );
921
+ assert(friendsOnAlice.alice);
922
+ assertLoaded(friendsOnAlice.alice);
923
+ expect(friendsOnAlice.alice.name).toBe("Alice");
866
924
  });
867
925
 
868
926
  test("unaccessible ref catched with $onError", async () => {
@@ -906,14 +964,21 @@ describe("Deep loading with unauthorized account", async () => {
906
964
  );
907
965
 
908
966
  const user = await User.load(map.$jazz.id, {
909
- resolve: { friends: { $each: { dog: { $onError: null } } } },
967
+ resolve: { friends: { $each: { dog: { $onError: "catch" } } } },
910
968
  loadAs: alice,
911
969
  });
912
970
 
913
- assert(user);
971
+ assertLoaded(user);
914
972
 
915
- expect(user.friends.jane?.dog).toBeNull(); // jane is null because her dog is inaccessible
916
- expect(user.friends.alice?.dog?.name).toBe("Giggino"); // alice is not null because we have read access to her and her dog
973
+ // jane's dog is not loaded because it is inaccessible
974
+ expect(user.friends.jane?.dog.$jazz.loadingState).toBe(
975
+ CoValueLoadingState.UNAUTHORIZED,
976
+ );
977
+ // we have read access to alice and her dog
978
+ const aliceDog = user.friends.alice?.dog;
979
+ assert(aliceDog);
980
+ assertLoaded(aliceDog);
981
+ expect(aliceDog.name).toBe("Giggino");
917
982
  });
918
983
 
919
984
  test("using $onError on the resolve root", async () => {
@@ -923,11 +988,55 @@ describe("Deep loading with unauthorized account", async () => {
923
988
 
924
989
  const map = Person.create({ name: "John" }, onlyBob);
925
990
  const user = await Person.load(map.$jazz.id, {
926
- resolve: { $onError: null },
991
+ resolve: { $onError: "catch" },
992
+ loadAs: alice,
993
+ });
994
+
995
+ expect(user.$jazz.loadingState).toBe(CoValueLoadingState.UNAUTHORIZED);
996
+ });
997
+
998
+ test("using $onError on a plain text value", async () => {
999
+ const Person = co.map({
1000
+ name: co.plainText(),
1001
+ });
1002
+
1003
+ const person = Person.create(
1004
+ { name: Person.shape.name.create("John", onlyBob) },
1005
+ group,
1006
+ );
1007
+
1008
+ const loadedPerson = await Person.load(person.$jazz.id, {
1009
+ resolve: { name: { $onError: "catch" } },
927
1010
  loadAs: alice,
928
1011
  });
929
1012
 
930
- expect(user).toBeNull();
1013
+ expect(loadedPerson.$isLoaded).toBe(true);
1014
+ assertLoaded(loadedPerson);
1015
+ expect(loadedPerson.name.$jazz.loadingState).toBe(
1016
+ CoValueLoadingState.UNAUTHORIZED,
1017
+ );
1018
+ });
1019
+
1020
+ test("using $onError on a file stream", async () => {
1021
+ const Person = co.map({
1022
+ avatar: co.fileStream(),
1023
+ });
1024
+
1025
+ const person = Person.create(
1026
+ { avatar: Person.shape.avatar.create(onlyBob) },
1027
+ group,
1028
+ );
1029
+
1030
+ const loadedPerson = await Person.load(person.$jazz.id, {
1031
+ resolve: { avatar: { $onError: "catch" } },
1032
+ loadAs: alice,
1033
+ });
1034
+
1035
+ expect(loadedPerson.$isLoaded).toBe(true);
1036
+ assertLoaded(loadedPerson);
1037
+ expect(loadedPerson.avatar.$jazz.loadingState).toBe(
1038
+ CoValueLoadingState.UNAUTHORIZED,
1039
+ );
931
1040
  });
932
1041
  });
933
1042
 
@@ -996,7 +1105,7 @@ test("throw when calling ensureLoaded on a ref that's required but missing", asy
996
1105
  ).rejects.toThrow("Failed to deeply load CoValue " + root.$jazz.id);
997
1106
  });
998
1107
 
999
- test("throw when calling ensureLoaded on a ref that is not defined in the schema", async () => {
1108
+ test("returns the value when calling ensureLoaded on a ref that is not defined in the schema", async () => {
1000
1109
  const JazzRoot = co.map({});
1001
1110
 
1002
1111
  const me = await Account.create({
@@ -1006,12 +1115,13 @@ test("throw when calling ensureLoaded on a ref that is not defined in the schema
1006
1115
 
1007
1116
  const root = JazzRoot.create({}, { owner: me });
1008
1117
 
1009
- await expect(
1010
- root.$jazz.ensureLoaded({
1011
- // @ts-expect-error missing required ref
1012
- resolve: { profile: true },
1013
- }),
1014
- ).rejects.toThrow("Failed to deeply load CoValue " + root.$jazz.id);
1118
+ const loadedRoot = await JazzRoot.load(root.$jazz.id, {
1119
+ // @ts-expect-error missing required ref
1120
+ resolve: { profile: true },
1121
+ loadAs: me,
1122
+ });
1123
+
1124
+ expect(loadedRoot.$jazz.loadingState).toBe(CoValueLoadingState.LOADED);
1015
1125
  });
1016
1126
 
1017
1127
  test("should not throw when calling ensureLoaded a record with a deleted ref", async () => {
@@ -1058,3 +1168,86 @@ test("should not throw when calling ensureLoaded a record with a deleted ref", a
1058
1168
 
1059
1169
  unsub();
1060
1170
  });
1171
+
1172
+ // This was a regression that ocurred when we migrated `DeeplyLoaded` to use explicit loading states.
1173
+ // Keeping this test to prevent it from happening again.
1174
+ test("deep loaded CoList nested inside another CoValue can be iterated over", async () => {
1175
+ const TestMap = co.map({ list: co.list(z.number()) });
1176
+
1177
+ const me = await Account.create({
1178
+ creationProps: { name: "Hermes Puggington" },
1179
+ crypto: Crypto,
1180
+ });
1181
+
1182
+ const map = TestMap.create({ list: [1, 2, 3] }, { owner: me });
1183
+
1184
+ const loadedMap = await TestMap.load(map.$jazz.id, {
1185
+ resolve: {
1186
+ list: true,
1187
+ },
1188
+ loadAs: me,
1189
+ });
1190
+ assertLoaded(loadedMap);
1191
+
1192
+ const list = loadedMap.list;
1193
+
1194
+ let expectedValue = 1;
1195
+ // @ts-expect-error - https://github.com/microsoft/TypeScript/issues/62621
1196
+ for (const item of list) {
1197
+ expect(item).toEqual(expectedValue);
1198
+ expectedValue++;
1199
+ }
1200
+ });
1201
+
1202
+ describe("$isLoaded", async () => {
1203
+ const me = await Account.create({
1204
+ creationProps: { name: "Hermes Puggington" },
1205
+ crypto: Crypto,
1206
+ });
1207
+
1208
+ const map = TestMap.create({ list: [] }, { owner: me });
1209
+
1210
+ test("$isLoaded narrows MaybeLoaded to loaded CoValue", async () => {
1211
+ const maybeLoadedMap = await TestMap.load(map.$jazz.id, {
1212
+ loadAs: me,
1213
+ });
1214
+
1215
+ expect(maybeLoadedMap.$isLoaded).toBe(true);
1216
+ if (maybeLoadedMap.$isLoaded) {
1217
+ expect(maybeLoadedMap.$jazz.loadingState).toBe(
1218
+ CoValueLoadingState.LOADED,
1219
+ );
1220
+ expect(maybeLoadedMap.$jazz.id).toBe(map.$jazz.id);
1221
+ expect(maybeLoadedMap.list).toEqual([]);
1222
+ } else {
1223
+ expectTypeOf(
1224
+ maybeLoadedMap.$jazz.loadingState,
1225
+ ).toEqualTypeOf<NotLoadedCoValueState>();
1226
+ }
1227
+ });
1228
+
1229
+ test("$isLoaded narrows MaybeLoaded to not loaded CoValue", async () => {
1230
+ const otherAccount = await Account.create({
1231
+ creationProps: { name: "Other Account" },
1232
+ crypto: Crypto,
1233
+ });
1234
+ const unloadedMap: MaybeLoaded<Loaded<typeof TestMap>> = await TestMap.load(
1235
+ map.$jazz.id,
1236
+ { loadAs: otherAccount },
1237
+ );
1238
+
1239
+ expect(unloadedMap.$isLoaded).toBe(false);
1240
+ if (!unloadedMap.$isLoaded) {
1241
+ expect(unloadedMap.$jazz.loadingState).toBe(
1242
+ CoValueLoadingState.UNAVAILABLE,
1243
+ );
1244
+ expect(unloadedMap.$jazz.id).toBe(map.$jazz.id);
1245
+ // @ts-expect-error - list should not be accessible on NotLoaded
1246
+ unloadedMap.list;
1247
+ } else {
1248
+ expectTypeOf(unloadedMap.$jazz.loadingState).toEqualTypeOf<
1249
+ typeof CoValueLoadingState.LOADED
1250
+ >();
1251
+ }
1252
+ });
1253
+ });