jazz-tools 0.19.22 → 0.20.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 (219) hide show
  1. package/.svelte-kit/__package__/react.d.ts.map +1 -1
  2. package/.svelte-kit/__package__/react.tsx +5 -2
  3. package/.turbo/turbo-build.log +71 -83
  4. package/CHANGELOG.md +80 -0
  5. package/dist/better-auth/auth/react.d.ts.map +1 -1
  6. package/dist/better-auth/auth/react.js +5 -2
  7. package/dist/better-auth/auth/react.js.map +1 -1
  8. package/dist/browser/createBrowserContext.d.ts +1 -2
  9. package/dist/browser/createBrowserContext.d.ts.map +1 -1
  10. package/dist/browser/index.js +1 -8
  11. package/dist/browser/index.js.map +1 -1
  12. package/dist/browser/provideBrowserLockSession/SessionIDStorage.d.ts +1 -1
  13. package/dist/{chunk-QCTQH5RS.js → chunk-2OPP7KWV.js} +382 -174
  14. package/dist/chunk-2OPP7KWV.js.map +1 -0
  15. package/dist/{chunk-M2HGBOXS.js → chunk-K4D7IMFM.js} +3 -3
  16. package/dist/chunk-K4D7IMFM.js.map +1 -0
  17. package/dist/chunk-ZQWSQH6L.js +20 -0
  18. package/dist/expo/auth/clerk/index.d.ts.map +1 -1
  19. package/dist/expo/index.js +5 -2
  20. package/dist/expo/index.js.map +1 -1
  21. package/dist/index.js +5 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/inspector/{chunk-YQNK5Y7B.js → chunk-MCTB5ZJC.js} +1 -1
  24. package/dist/inspector/chunk-MCTB5ZJC.js.map +1 -0
  25. package/dist/inspector/contexts/node.d.ts.map +1 -1
  26. package/dist/inspector/{custom-element-KYV64IOC.js → custom-element-5YWVZBWA.js} +1 -1
  27. package/dist/inspector/{custom-element-KYV64IOC.js.map → custom-element-5YWVZBWA.js.map} +1 -1
  28. package/dist/inspector/index.js +3 -3
  29. package/dist/inspector/index.js.map +1 -1
  30. package/dist/inspector/register-custom-element.js +1 -1
  31. package/dist/inspector/standalone.js +1 -1
  32. package/dist/react/auth/Clerk.d.ts.map +1 -1
  33. package/dist/react/hooks.d.ts +1 -1
  34. package/dist/react/hooks.d.ts.map +1 -1
  35. package/dist/react/index.js +61 -47
  36. package/dist/react/index.js.map +1 -1
  37. package/dist/react/provider.d.ts.map +1 -1
  38. package/dist/react/ssr.js +2 -2
  39. package/dist/react/ssr.js.map +1 -1
  40. package/dist/react-core/chunk-UOYH6JFJ.js +10 -0
  41. package/dist/react-core/chunk-UOYH6JFJ.js.map +1 -0
  42. package/dist/react-core/hooks.d.ts +3 -3
  43. package/dist/react-core/hooks.d.ts.map +1 -1
  44. package/dist/react-core/index.js +27 -25
  45. package/dist/react-core/index.js.map +1 -1
  46. package/dist/react-core/provider.d.ts +2 -3
  47. package/dist/react-core/provider.d.ts.map +1 -1
  48. package/dist/react-core/testing.d.ts.map +1 -1
  49. package/dist/react-core/testing.js +4 -10
  50. package/dist/react-core/testing.js.map +1 -1
  51. package/dist/react-native/index.js +61 -53
  52. package/dist/react-native/index.js.map +1 -1
  53. package/dist/react-native-core/ReactNativeContextManager.d.ts +0 -1
  54. package/dist/react-native-core/ReactNativeContextManager.d.ts.map +1 -1
  55. package/dist/react-native-core/hooks.d.ts +1 -1
  56. package/dist/react-native-core/hooks.d.ts.map +1 -1
  57. package/dist/react-native-core/index.js +58 -50
  58. package/dist/react-native-core/index.js.map +1 -1
  59. package/dist/react-native-core/platform.d.ts +0 -4
  60. package/dist/react-native-core/platform.d.ts.map +1 -1
  61. package/dist/react-native-core/provider.d.ts +2 -1
  62. package/dist/react-native-core/provider.d.ts.map +1 -1
  63. package/dist/svelte/jazz.class.svelte.d.ts.map +1 -1
  64. package/dist/svelte/jazz.class.svelte.js +2 -8
  65. package/dist/svelte/tests/AccountCoState.svelte.test.d.ts +2 -0
  66. package/dist/svelte/tests/AccountCoState.svelte.test.d.ts.map +1 -0
  67. package/dist/svelte/tests/AccountCoState.svelte.test.js +59 -0
  68. package/dist/svelte/tests/CoState.svelte.test.js +23 -0
  69. package/dist/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
  70. package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts +11 -0
  71. package/dist/svelte/tests/TestAccountCoStateWrapper.svelte.d.ts.map +1 -0
  72. package/dist/testing.js +7 -7
  73. package/dist/testing.js.map +1 -1
  74. package/dist/tools/coValues/coList.d.ts +2 -2
  75. package/dist/tools/coValues/coList.d.ts.map +1 -1
  76. package/dist/tools/coValues/coMap.d.ts +2 -2
  77. package/dist/tools/coValues/deepLoading.d.ts +2 -2
  78. package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
  79. package/dist/tools/coValues/interfaces.d.ts +32 -0
  80. package/dist/tools/coValues/interfaces.d.ts.map +1 -1
  81. package/dist/tools/exports.d.ts +1 -1
  82. package/dist/tools/exports.d.ts.map +1 -1
  83. package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
  84. package/dist/tools/implementation/createContext.d.ts.map +1 -1
  85. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +3 -2
  86. package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
  87. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts +3 -2
  88. package/dist/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.d.ts.map +1 -1
  89. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +5 -4
  90. package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
  91. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +5 -3
  92. package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
  93. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +7 -3
  94. package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
  95. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts +3 -1
  96. package/dist/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.d.ts.map +1 -1
  97. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +3 -1
  98. package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
  99. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +2 -1
  100. package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
  101. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +6 -1
  102. package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
  103. package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
  104. package/dist/tools/ssr.js +2 -2
  105. package/dist/tools/subscribe/JazzError.d.ts +3 -3
  106. package/dist/tools/subscribe/JazzError.d.ts.map +1 -1
  107. package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
  108. package/dist/tools/subscribe/types.d.ts +5 -1
  109. package/dist/tools/subscribe/types.d.ts.map +1 -1
  110. package/dist/tools/testing.d.ts +3 -3
  111. package/dist/tools/testing.d.ts.map +1 -1
  112. package/dist/tools/tests/deleteCoValues.test.d.ts +2 -0
  113. package/dist/tools/tests/deleteCoValues.test.d.ts.map +1 -0
  114. package/dist/tools/tests/deletedState.test.d.ts +2 -0
  115. package/dist/tools/tests/deletedState.test.d.ts.map +1 -0
  116. package/dist/worker/edge-wasm.js +2 -1
  117. package/dist/worker/edge-wasm.js.map +1 -1
  118. package/dist/worker/wasm.d.ts +2 -0
  119. package/dist/worker/wasm.d.ts.map +1 -0
  120. package/package.json +9 -28
  121. package/src/better-auth/auth/react.tsx +5 -2
  122. package/src/browser/createBrowserContext.ts +2 -5
  123. package/src/expo/auth/clerk/index.tsx +5 -2
  124. package/src/inspector/contexts/node.tsx +1 -2
  125. package/src/inspector/index.tsx +2 -2
  126. package/src/react/auth/Clerk.tsx +5 -2
  127. package/src/react/auth/PasskeyAuth.tsx +2 -2
  128. package/src/react/hooks.tsx +3 -2
  129. package/src/react/provider.tsx +45 -41
  130. package/src/react-core/auth/DemoAuth.tsx +2 -2
  131. package/src/react-core/auth/PassphraseAuth.tsx +2 -2
  132. package/src/react-core/hooks.ts +26 -27
  133. package/src/react-core/provider.tsx +1 -5
  134. package/src/react-core/testing.tsx +3 -11
  135. package/src/react-core/tests/useAccount.selector.test.ts +2 -3
  136. package/src/react-core/tests/useAccount.test.ts +57 -7
  137. package/src/react-core/tests/useCoState.test.ts +37 -0
  138. package/src/react-core/tests/useInboxSender.test.ts +2 -5
  139. package/src/react-core/tests/useSuspenseAccount.test.tsx +68 -0
  140. package/src/react-core/tests/useSuspenseCoState.test.tsx +44 -0
  141. package/src/react-native-core/ReactNativeContextManager.ts +0 -3
  142. package/src/react-native-core/auth/usePasskeyAuth.tsx +2 -2
  143. package/src/react-native-core/hooks.tsx +3 -3
  144. package/src/react-native-core/platform.ts +2 -6
  145. package/src/react-native-core/provider.tsx +47 -43
  146. package/src/svelte/jazz.class.svelte.ts +2 -8
  147. package/src/svelte/tests/AccountCoState.svelte.test.ts +79 -0
  148. package/src/svelte/tests/CoState.svelte.test.ts +36 -0
  149. package/src/svelte/tests/TestAccountCoStateWrapper.svelte +24 -0
  150. package/src/tools/coValues/coList.ts +73 -37
  151. package/src/tools/coValues/deepLoading.ts +2 -0
  152. package/src/tools/coValues/interfaces.ts +170 -32
  153. package/src/tools/exports.ts +1 -0
  154. package/src/tools/implementation/ContextManager.ts +2 -2
  155. package/src/tools/implementation/createContext.ts +4 -0
  156. package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +30 -8
  157. package/src/tools/implementation/zodSchema/schemaTypes/CoDiscriminatedUnionSchema.ts +55 -7
  158. package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +38 -16
  159. package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +40 -8
  160. package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +40 -16
  161. package/src/tools/implementation/zodSchema/schemaTypes/CoVectorSchema.ts +6 -2
  162. package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +6 -2
  163. package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +5 -2
  164. package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +9 -2
  165. package/src/tools/ssr/ssr.ts +2 -2
  166. package/src/tools/subscribe/CoValueCoreSubscription.ts +1 -0
  167. package/src/tools/subscribe/JazzError.ts +4 -1
  168. package/src/tools/subscribe/SubscriptionScope.ts +23 -0
  169. package/src/tools/subscribe/types.ts +5 -0
  170. package/src/tools/testing.ts +5 -5
  171. package/src/tools/tests/PassphraseAuth.test.ts +5 -5
  172. package/src/tools/tests/coList.test.ts +262 -0
  173. package/src/tools/tests/deleteCoValues.test.ts +231 -0
  174. package/src/tools/tests/deletedState.test.ts +110 -0
  175. package/src/tools/tests/request.test.ts +15 -2
  176. package/src/tools/tests/schema.withPermissions.test.ts +27 -4
  177. package/src/worker/edge-wasm.ts +2 -1
  178. package/src/worker/wasm.ts +1 -0
  179. package/tsup.config.ts +0 -4
  180. package/dist/browser/storageOptions.d.ts +0 -8
  181. package/dist/browser/storageOptions.d.ts.map +0 -1
  182. package/dist/browser/tests/storageOptions.test.d.ts +0 -2
  183. package/dist/browser/tests/storageOptions.test.d.ts.map +0 -1
  184. package/dist/chunk-M2HGBOXS.js.map +0 -1
  185. package/dist/chunk-PZ5AY32C.js +0 -10
  186. package/dist/chunk-QCTQH5RS.js.map +0 -1
  187. package/dist/expo/crypto.d.ts +0 -2
  188. package/dist/expo/crypto.d.ts.map +0 -1
  189. package/dist/expo/crypto.js +0 -6
  190. package/dist/expo/crypto.js.map +0 -1
  191. package/dist/inspector/chunk-YQNK5Y7B.js.map +0 -1
  192. package/dist/react-core/chunk-7DYMJ74I.js +0 -12
  193. package/dist/react-core/chunk-7DYMJ74I.js.map +0 -1
  194. package/dist/react-native/chunk-DGUM43GV.js +0 -11
  195. package/dist/react-native/chunk-DGUM43GV.js.map +0 -1
  196. package/dist/react-native/crypto.d.ts +0 -2
  197. package/dist/react-native/crypto.d.ts.map +0 -1
  198. package/dist/react-native/crypto.js +0 -8
  199. package/dist/react-native/crypto.js.map +0 -1
  200. package/dist/react-native-core/chunk-DGUM43GV.js +0 -11
  201. package/dist/react-native-core/chunk-DGUM43GV.js.map +0 -1
  202. package/dist/react-native-core/crypto/RNCrypto.d.ts +0 -2
  203. package/dist/react-native-core/crypto/RNCrypto.d.ts.map +0 -1
  204. package/dist/react-native-core/crypto/RNCrypto.js +0 -3
  205. package/dist/react-native-core/crypto/RNCrypto.js.map +0 -1
  206. package/dist/react-native-core/crypto/RNQuickCrypto.d.ts +0 -17
  207. package/dist/react-native-core/crypto/RNQuickCrypto.d.ts.map +0 -1
  208. package/dist/react-native-core/crypto/index.d.ts +0 -2
  209. package/dist/react-native-core/crypto/index.d.ts.map +0 -1
  210. package/dist/react-native-core/crypto.js +0 -89
  211. package/dist/react-native-core/crypto.js.map +0 -1
  212. package/src/browser/storageOptions.ts +0 -17
  213. package/src/browser/tests/storageOptions.test.ts +0 -33
  214. package/src/expo/crypto.ts +0 -1
  215. package/src/react-native/crypto.ts +0 -1
  216. package/src/react-native-core/crypto/RNCrypto.ts +0 -1
  217. package/src/react-native-core/crypto/RNQuickCrypto.ts +0 -122
  218. package/src/react-native-core/crypto/index.ts +0 -1
  219. /package/dist/{chunk-PZ5AY32C.js.map → chunk-ZQWSQH6L.js.map} +0 -0
@@ -549,7 +549,7 @@ export class CoListJazzApi<L extends CoList> extends CoValueJazzApi<L> {
549
549
  "private",
550
550
  );
551
551
 
552
- return this.raw.entries().length;
552
+ return this.raw.length();
553
553
  }
554
554
 
555
555
  /**
@@ -567,7 +567,7 @@ export class CoListJazzApi<L extends CoList> extends CoValueJazzApi<L> {
567
567
  this.raw.prepend(item);
568
568
  }
569
569
 
570
- return this.raw.entries().length;
570
+ return this.raw.length();
571
571
  }
572
572
 
573
573
  /**
@@ -936,40 +936,65 @@ function toRawItems<Item>(
936
936
  return rawItems;
937
937
  }
938
938
 
939
+ function getCoListItemValue(target: CoList, key: string) {
940
+ const rawValue = target.$jazz.raw.get(Number(key));
941
+
942
+ if (rawValue === undefined) {
943
+ return undefined;
944
+ }
945
+
946
+ const itemDescriptor: Schema = target.$jazz.schema[ItemsSym];
947
+
948
+ if (itemDescriptor === "json") {
949
+ return rawValue;
950
+ } else if ("encoded" in itemDescriptor) {
951
+ return itemDescriptor.encoded.decode(rawValue);
952
+ } else if (isRefEncoded(itemDescriptor)) {
953
+ if (rawValue === null) {
954
+ return undefined;
955
+ }
956
+
957
+ return accessChildByKey(target, rawValue as string, key);
958
+ }
959
+
960
+ return undefined;
961
+ }
962
+
939
963
  const CoListProxyHandler: ProxyHandler<CoList> = {
940
964
  get(target, key, receiver) {
941
- if (typeof key === "string" && !isNaN(+key)) {
942
- const itemDescriptor = target.$jazz.schema[ItemsSym] as Schema;
943
- const rawValue = target.$jazz.raw.get(Number(key));
944
- if (itemDescriptor === "json") {
945
- return rawValue;
946
- } else if ("encoded" in itemDescriptor) {
947
- return rawValue === undefined
948
- ? undefined
949
- : itemDescriptor.encoded.decode(rawValue);
950
- } else if (isRefEncoded(itemDescriptor)) {
951
- return rawValue === undefined || rawValue === null
952
- ? undefined
953
- : accessChildByKey(target, rawValue as string, key);
954
- }
955
- } else if (key === "length") {
956
- return target.$jazz.raw.entries().length;
957
- } else {
965
+ if (typeof key === "symbol") {
958
966
  return Reflect.get(target, key, receiver);
959
967
  }
968
+
969
+ if (!isNaN(+key)) {
970
+ return getCoListItemValue(target, key);
971
+ } else if (key === "length") {
972
+ return target.$jazz.raw.length();
973
+ }
974
+
975
+ return Reflect.get(target, key, receiver);
960
976
  },
961
977
  set(target, key, value, receiver) {
978
+ if (typeof key === "symbol") {
979
+ return Reflect.set(target, key, value, receiver);
980
+ }
981
+
962
982
  if (key === ItemsSym && typeof value === "object" && SchemaInit in value) {
963
- (target.constructor as typeof CoList)._schema ||= {};
964
- (target.constructor as typeof CoList)._schema[ItemsSym] =
965
- value[SchemaInit];
983
+ const constructor = target.constructor as typeof CoList;
984
+
985
+ if (!constructor._schema) {
986
+ constructor._schema = {};
987
+ }
988
+
989
+ constructor._schema[ItemsSym] = value[SchemaInit];
966
990
  return true;
967
991
  }
968
- if (typeof key === "string" && !isNaN(+key)) {
992
+
993
+ if (!isNaN(+key)) {
969
994
  throw Error("Cannot update a CoList directly. Use `$jazz.set` instead.");
970
- } else {
971
- return Reflect.set(target, key, value, receiver);
972
995
  }
996
+
997
+ return Reflect.set(target, key, value, receiver);
973
998
  },
974
999
  defineProperty(target, key, descriptor) {
975
1000
  if (
@@ -978,9 +1003,13 @@ const CoListProxyHandler: ProxyHandler<CoList> = {
978
1003
  typeof descriptor.value === "object" &&
979
1004
  SchemaInit in descriptor.value
980
1005
  ) {
981
- (target.constructor as typeof CoList)._schema ||= {};
982
- (target.constructor as typeof CoList)._schema[ItemsSym] =
983
- descriptor.value[SchemaInit];
1006
+ const constructor = target.constructor as typeof CoList;
1007
+
1008
+ if (!constructor._schema) {
1009
+ constructor._schema = {};
1010
+ }
1011
+
1012
+ constructor._schema[ItemsSym] = descriptor.value[SchemaInit];
984
1013
  return true;
985
1014
  } else {
986
1015
  return Reflect.defineProperty(target, key, descriptor);
@@ -988,7 +1017,7 @@ const CoListProxyHandler: ProxyHandler<CoList> = {
988
1017
  },
989
1018
  has(target, key) {
990
1019
  if (typeof key === "string" && !isNaN(+key)) {
991
- return Number(key) < target.$jazz.raw.entries().length;
1020
+ return Number(key) < target.$jazz.raw.length();
992
1021
  } else {
993
1022
  return Reflect.has(target, key);
994
1023
  }
@@ -996,11 +1025,17 @@ const CoListProxyHandler: ProxyHandler<CoList> = {
996
1025
  ownKeys(target) {
997
1026
  const keys = Reflect.ownKeys(target);
998
1027
  // Add numeric indices for all entries in the list
999
- const indexKeys = target.$jazz.raw.entries().map((_entry, i) => String(i));
1000
- keys.push(...indexKeys);
1028
+ const length = target.$jazz.raw.length();
1029
+ for (let i = 0; i < length; i++) {
1030
+ keys.push(String(i));
1031
+ }
1001
1032
  return keys;
1002
1033
  },
1003
1034
  getOwnPropertyDescriptor(target, key) {
1035
+ if (typeof key === "symbol") {
1036
+ return Reflect.getOwnPropertyDescriptor(target, key);
1037
+ }
1038
+
1004
1039
  if (key === TypeSym) {
1005
1040
  // Make TypeSym non-enumerable so it doesn't show up in Object.keys()
1006
1041
  return {
@@ -1009,23 +1044,24 @@ const CoListProxyHandler: ProxyHandler<CoList> = {
1009
1044
  writable: false,
1010
1045
  value: target[TypeSym],
1011
1046
  };
1012
- } else if (key in target) {
1013
- return Reflect.getOwnPropertyDescriptor(target, key);
1014
- } else if (typeof key === "string" && !isNaN(+key)) {
1047
+ } else if (!isNaN(+key)) {
1015
1048
  const index = Number(key);
1016
- if (index >= 0 && index < target.$jazz.raw.entries().length) {
1049
+ if (index >= 0 && index < target.$jazz.raw.length()) {
1017
1050
  return {
1018
1051
  enumerable: true,
1019
1052
  configurable: true,
1020
- writable: true,
1053
+ writable: false,
1054
+ value: getCoListItemValue(target, key),
1021
1055
  };
1022
1056
  }
1023
1057
  } else if (key === "length") {
1024
1058
  return {
1025
1059
  enumerable: false,
1026
1060
  configurable: false,
1027
- writable: false,
1061
+ writable: true, // Must be writable, otherwise JS complains
1062
+ value: target.$jazz.raw.length(),
1028
1063
  };
1029
1064
  }
1065
+ return Reflect.getOwnPropertyDescriptor(target, key);
1030
1066
  },
1031
1067
  };
@@ -46,6 +46,7 @@ export type NotLoaded<T> = {
46
46
  id: ID<T>;
47
47
  loadingState:
48
48
  | typeof CoValueLoadingState.LOADING
49
+ | typeof CoValueLoadingState.DELETED
49
50
  | typeof CoValueLoadingState.UNAVAILABLE
50
51
  | typeof CoValueLoadingState.UNAUTHORIZED;
51
52
  };
@@ -70,6 +71,7 @@ export type Inaccessible<T> = {
70
71
  $jazz: {
71
72
  id: ID<T>;
72
73
  loadingState:
74
+ | typeof CoValueLoadingState.DELETED
73
75
  | typeof CoValueLoadingState.UNAVAILABLE
74
76
  | typeof CoValueLoadingState.UNAUTHORIZED;
75
77
  };
@@ -32,6 +32,7 @@ import {
32
32
  } from "../internal.js";
33
33
  import type { BranchDefinition } from "../subscribe/types.js";
34
34
  import { CoValueHeader } from "cojson";
35
+ import { JazzError } from "../subscribe/JazzError.js";
35
36
 
36
37
  /** @category Abstract interfaces */
37
38
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -177,8 +178,7 @@ export function loadCoValue<
177
178
  loadAs: options.loadAs,
178
179
  syncResolution: true,
179
180
  skipRetry: options.skipRetry,
180
- onUnavailable: resolve,
181
- onUnauthorized: resolve,
181
+ onError: resolve,
182
182
  unstable_branch: options.unstable_branch,
183
183
  },
184
184
  (value, unsubscribe) => {
@@ -223,13 +223,22 @@ type SubscribeListener<V extends CoValue, R extends RefsToResolve<V>> = (
223
223
  unsubscribe: () => void,
224
224
  ) => void;
225
225
 
226
+ export type SubscribeCallback<V> = (value: V, unsubscribe: () => void) => void;
227
+
226
228
  export type SubscribeListenerOptions<
227
229
  V extends CoValue,
228
230
  R extends RefsToResolve<V>,
229
231
  > = {
230
232
  resolve?: RefsToResolveStrict<V, R>;
231
233
  loadAs?: Account | AnonymousJazzAgent;
234
+ onError?: (value: NotLoaded<V>) => void;
235
+ /**
236
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
237
+ */
232
238
  onUnauthorized?: (value: NotLoaded<V>) => void;
239
+ /**
240
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
241
+ */
233
242
  onUnavailable?: (value: NotLoaded<V>) => void;
234
243
  unstable_branch?: BranchDefinition;
235
244
  };
@@ -257,6 +266,7 @@ export function parseSubscribeRestArgs<
257
266
  options: {
258
267
  resolve: args[0].resolve,
259
268
  loadAs: args[0].loadAs,
269
+ onError: args[0].onError,
260
270
  onUnauthorized: args[0].onUnauthorized,
261
271
  onUnavailable: args[0].onUnavailable,
262
272
  unstable_branch: args[0].unstable_branch,
@@ -304,7 +314,14 @@ export function subscribeToCoValue<
304
314
  options: {
305
315
  resolve?: RefsToResolveStrict<V, R>;
306
316
  loadAs: Account | AnonymousJazzAgent;
317
+ onError?: (value: Inaccessible<V>) => void;
318
+ /**
319
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
320
+ */
307
321
  onUnavailable?: (value: Inaccessible<V>) => void;
322
+ /**
323
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
324
+ */
308
325
  onUnauthorized?: (value: Inaccessible<V>) => void;
309
326
  syncResolution?: boolean;
310
327
  skipRetry?: boolean;
@@ -342,6 +359,9 @@ export function subscribeToCoValue<
342
359
  return;
343
360
  }
344
361
 
362
+ options.onError?.(value as Inaccessible<V>);
363
+
364
+ // Backward compatibility, going to remove this in the next minor release
345
365
  switch (value.$jazz.loadingState) {
346
366
  case CoValueLoadingState.UNAVAILABLE:
347
367
  options.onUnavailable?.(value as Inaccessible<V>);
@@ -381,7 +401,14 @@ export function subscribeToExistingCoValue<
381
401
  options:
382
402
  | {
383
403
  resolve?: RefsToResolveStrict<V, R>;
404
+ onError?: (value: NotLoaded<V>) => void;
405
+ /**
406
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
407
+ */
384
408
  onUnavailable?: (value: NotLoaded<V>) => void;
409
+ /**
410
+ * @deprecated Use `onError` instead. This callback will be removed in a future version.
411
+ */
385
412
  onUnauthorized?: (value: NotLoaded<V>) => void;
386
413
  unstable_branch?: BranchDefinition;
387
414
  }
@@ -394,6 +421,7 @@ export function subscribeToExistingCoValue<
394
421
  {
395
422
  loadAs: existing.$jazz.loadedAs,
396
423
  resolve: options?.resolve,
424
+ onError: options?.onError,
397
425
  onUnavailable: options?.onUnavailable,
398
426
  onUnauthorized: options?.onUnauthorized,
399
427
  unstable_branch: options?.unstable_branch,
@@ -688,23 +716,11 @@ export async function exportCoValue<
688
716
  options.unstable_branch,
689
717
  );
690
718
 
691
- const value = await new Promise<Loaded<S, R> | null>((resolve) => {
692
- rootNode.setListener(() => {
693
- const value = rootNode.getCurrentValue();
694
-
695
- if (value.$isLoaded) {
696
- resolve(value as Loaded<S, R>);
697
- } else if (
698
- value.$jazz.loadingState === CoValueLoadingState.UNAVAILABLE ||
699
- value.$jazz.loadingState === CoValueLoadingState.UNAUTHORIZED
700
- ) {
701
- resolve(null);
702
- rootNode.destroy();
703
- }
704
- });
705
- });
706
-
707
- if (!value) {
719
+ try {
720
+ await rootNode.getPromise();
721
+ rootNode.destroy();
722
+ } catch (error) {
723
+ rootNode.destroy();
708
724
  return null;
709
725
  }
710
726
 
@@ -857,19 +873,141 @@ export async function unstable_mergeBranchWithResolve<
857
873
  options.branch,
858
874
  );
859
875
 
860
- await new Promise<void>((resolve, reject) => {
861
- rootNode.setListener((value) => {
862
- if (value.type === CoValueLoadingState.UNAVAILABLE) {
863
- reject(new Error("Unable to load the branch. " + value.toString()));
864
- } else if (value.type === CoValueLoadingState.UNAUTHORIZED) {
865
- reject(new Error("Unable to load the branch. " + value.toString()));
866
- } else if (value.type === CoValueLoadingState.LOADED) {
867
- resolve();
868
- }
869
-
870
- rootNode.destroy();
871
- });
872
- });
876
+ try {
877
+ await rootNode.getPromise();
878
+ rootNode.destroy();
879
+ } catch (error) {
880
+ rootNode.destroy();
881
+ throw error;
882
+ }
873
883
 
874
884
  unstable_mergeBranch(rootNode);
875
885
  }
886
+
887
+ /**
888
+ * Permanently delete a group of coValues
889
+ *
890
+ * This operation is irreversible and will permanently delete the coValues from the local machine and the sync servers.
891
+ *
892
+ */
893
+ export async function deleteCoValues<
894
+ S extends CoValueClassOrSchema,
895
+ const R extends ResolveQuery<S>,
896
+ >(
897
+ cls: S,
898
+ id: ID<CoValue>,
899
+ options: {
900
+ resolve?: ResolveQueryStrict<S, R>;
901
+ loadAs?: Account | AnonymousJazzAgent;
902
+ } = {},
903
+ ) {
904
+ const loadAs = options.loadAs ?? activeAccountContext.get();
905
+ const node = "node" in loadAs ? loadAs.node : loadAs.$jazz.localNode;
906
+
907
+ const resolve = options.resolve ?? true;
908
+
909
+ const rootNode = new SubscriptionScope<CoValue>(
910
+ node,
911
+ resolve as any,
912
+ id,
913
+ {
914
+ ref: coValueClassFromCoValueClassOrSchema(cls),
915
+ optional: false,
916
+ },
917
+ false,
918
+ false,
919
+ undefined,
920
+ );
921
+
922
+ try {
923
+ await rootNode.getPromise();
924
+ rootNode.destroy();
925
+ } catch (error) {
926
+ rootNode.destroy();
927
+ throw error;
928
+ }
929
+
930
+ // We validate permissions to fail early if one of the loaded coValues is not deletable
931
+ const errors = validateDeletePermissions(rootNode);
932
+
933
+ if (errors.length > 0) {
934
+ const combined = new JazzError(
935
+ id,
936
+ CoValueLoadingState.DELETED,
937
+ errors.flatMap((e) => e.issues),
938
+ );
939
+ throw new Error(combined.toString());
940
+ }
941
+
942
+ const deletedValues = deleteCoValueFromSubscription(rootNode);
943
+
944
+ await Promise.allSettled(
945
+ Array.from(deletedValues, (value) => value.waitForSync()),
946
+ );
947
+ }
948
+
949
+ function validateDeletePermissions(
950
+ rootNode: SubscriptionScope<CoValue>,
951
+ path: string[] = [],
952
+ errors: JazzError[] = [],
953
+ ): JazzError[] {
954
+ for (const [key, childNode] of rootNode.childNodes.entries()) {
955
+ validateDeletePermissions(childNode, [...path, key], errors);
956
+ }
957
+
958
+ if (rootNode.value.type !== CoValueLoadingState.LOADED) {
959
+ return errors;
960
+ }
961
+
962
+ const core = rootNode.value.value.$jazz.raw.core;
963
+
964
+ // Account and Group coValues are not deletable, we skip them to make it easier to delete all coValues owned by an account
965
+ if (core.isGroupOrAccount()) {
966
+ return errors;
967
+ }
968
+
969
+ const result = core.validateDeletePermissions();
970
+ if (!result.ok) {
971
+ errors.push(
972
+ new JazzError(core.id, CoValueLoadingState.DELETED, [
973
+ {
974
+ code: "deleteError",
975
+ message: `Jazz Delete Error: ${result.message}`,
976
+ params: {},
977
+ path,
978
+ },
979
+ ]),
980
+ );
981
+ }
982
+
983
+ return errors;
984
+ }
985
+
986
+ function deleteCoValueFromSubscription(
987
+ rootNode: SubscriptionScope<CoValue>,
988
+ values = new Set<AvailableCoValueCore>(),
989
+ ) {
990
+ for (const childNode of rootNode.childNodes.values()) {
991
+ deleteCoValueFromSubscription(childNode, values);
992
+ }
993
+
994
+ if (rootNode.value.type !== CoValueLoadingState.LOADED) {
995
+ return values;
996
+ }
997
+
998
+ const core = rootNode.value.value.$jazz.raw.core;
999
+
1000
+ // Account and Group coValues are not deletable, we skip them to make it easier to delete all coValues owned by an account
1001
+ if (core.isGroupOrAccount()) {
1002
+ return values;
1003
+ }
1004
+
1005
+ try {
1006
+ core.deleteCoValue();
1007
+ values.add(core);
1008
+ } catch (error) {
1009
+ console.error("Failed to delete coValue", error);
1010
+ }
1011
+
1012
+ return values;
1013
+ }
@@ -67,6 +67,7 @@ export {
67
67
  unstable_loadUnique,
68
68
  getUnloadedCoValueWithoutId,
69
69
  setDefaultSchemaPermissions,
70
+ deleteCoValues,
70
71
  getJazzErrorType,
71
72
  } from "./internal.js";
72
73
 
@@ -1,5 +1,4 @@
1
1
  import { AgentSecret, LocalNode, cojsonInternals } from "cojson";
2
- import { PureJSCrypto } from "cojson/dist/crypto/PureJSCrypto";
3
2
  import { AuthSecretStorage } from "../auth/AuthSecretStorage.js";
4
3
  import { InMemoryKVStore } from "../auth/InMemoryKVStore.js";
5
4
  import { KvStore, KvStoreContext } from "../auth/KvStoreContext.js";
@@ -10,6 +9,7 @@ import { AnonymousJazzAgent } from "./anonymousJazzAgent.js";
10
9
  import { createAnonymousJazzContext } from "./createContext.js";
11
10
  import { InstanceOfSchema } from "./zodSchema/typeConverters/InstanceOfSchema.js";
12
11
  import { SubscriptionCache } from "../subscribe/SubscriptionCache.js";
12
+ import { WasmCrypto } from "cojson/crypto/WasmCrypto";
13
13
 
14
14
  export type JazzContextManagerAuthProps = {
15
15
  credentials?: AuthCredentials;
@@ -47,7 +47,7 @@ type PlatformSpecificContext<Acc extends Account> =
47
47
  function getAnonymousFallback() {
48
48
  const context = createAnonymousJazzContext({
49
49
  peers: [],
50
- crypto: new PureJSCrypto(),
50
+ crypto: WasmCrypto.createSync(),
51
51
  });
52
52
 
53
53
  return {
@@ -272,6 +272,10 @@ export async function createJazzContext<
272
272
 
273
273
  const credentials = options.credentials ?? (await authSecretStorage.get());
274
274
 
275
+ if (options.storage) {
276
+ options.storage.enableDeletedCoValuesErasure();
277
+ }
278
+
275
279
  if (credentials && !options.newAccountProps) {
276
280
  context = await createJazzContextFromExistingCredentials({
277
281
  credentials: {
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  Account,
3
- AccountCreationProps,
4
3
  BranchDefinition,
5
4
  CoMapSchemaDefinition,
6
5
  coOptionalDefiner,
@@ -10,12 +9,12 @@ import {
10
9
  RefsToResolve,
11
10
  Resolved,
12
11
  Simplify,
12
+ SubscribeCallback,
13
13
  SubscribeListenerOptions,
14
14
  unstable_mergeBranchWithResolve,
15
15
  } from "../../../internal.js";
16
16
  import { AnonymousJazzAgent } from "../../anonymousJazzAgent.js";
17
17
  import { InstanceOrPrimitiveOfSchema } from "../typeConverters/InstanceOrPrimitiveOfSchema.js";
18
- import { InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded } from "../typeConverters/InstanceOrPrimitiveOfSchemaCoValuesMaybeLoaded.js";
19
18
  import { z } from "../zodReExport.js";
20
19
  import { AnyZodOrCoValueSchema, Loaded, ResolveQuery } from "../zodSchema.js";
21
20
  import {
@@ -161,6 +160,15 @@ export class AccountSchema<
161
160
  );
162
161
  }
163
162
 
163
+ subscribe<
164
+ const R extends RefsToResolve<
165
+ Simplify<AccountInstance<Shape>>
166
+ // @ts-expect-error we can't statically enforce the schema's resolve query is a valid resolve query, but in practice it is
167
+ > = DefaultResolveQuery,
168
+ >(
169
+ id: string,
170
+ listener: SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
171
+ ): () => void;
164
172
  subscribe<
165
173
  const R extends RefsToResolve<
166
174
  Simplify<AccountInstance<Shape>>
@@ -169,16 +177,30 @@ export class AccountSchema<
169
177
  >(
170
178
  id: string,
171
179
  options: SubscribeListenerOptions<Simplify<AccountInstance<Shape>>, R>,
172
- listener: (
173
- value: Resolved<Simplify<AccountInstance<Shape>>, R>,
174
- unsubscribe: () => void,
175
- ) => void,
180
+ listener: SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
181
+ ): () => void;
182
+ subscribe<const R extends RefsToResolve<Simplify<AccountInstance<Shape>>>>(
183
+ id: string,
184
+ optionsOrListener:
185
+ | SubscribeListenerOptions<Simplify<AccountInstance<Shape>>, R>
186
+ | SubscribeCallback<Resolved<Simplify<AccountInstance<Shape>>, R>>,
187
+ maybeListener?: SubscribeCallback<
188
+ Resolved<Simplify<AccountInstance<Shape>>, R>
189
+ >,
176
190
  ): () => void {
191
+ if (typeof optionsOrListener === "function") {
192
+ return this.coValueClass.subscribe(
193
+ id,
194
+ withSchemaResolveQuery({}, this.resolveQuery),
195
+ // @ts-expect-error
196
+ optionsOrListener,
197
+ );
198
+ }
177
199
  return this.coValueClass.subscribe(
178
200
  id,
179
201
  // @ts-expect-error
180
- withSchemaResolveQuery(options, this.resolveQuery),
181
- listener,
202
+ withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
203
+ maybeListener,
182
204
  );
183
205
  }
184
206
 
@@ -11,6 +11,7 @@ import {
11
11
  Resolved,
12
12
  SchemaUnion,
13
13
  SchemaUnionConcreteSubclass,
14
+ SubscribeCallback,
14
15
  SubscribeListenerOptions,
15
16
  coOptionalDefiner,
16
17
  } from "../../../internal.js";
@@ -101,6 +102,20 @@ export class CoDiscriminatedUnionSchema<
101
102
  ) as any;
102
103
  }
103
104
 
105
+ subscribe<
106
+ const R extends RefsToResolve<
107
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
108
+ // @ts-expect-error
109
+ > = DefaultResolveQuery,
110
+ >(
111
+ id: string,
112
+ listener: SubscribeCallback<
113
+ Resolved<
114
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
115
+ R
116
+ >
117
+ >,
118
+ ): () => void;
104
119
  subscribe<
105
120
  const R extends RefsToResolve<
106
121
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
@@ -112,19 +127,52 @@ export class CoDiscriminatedUnionSchema<
112
127
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
113
128
  R
114
129
  >,
115
- listener: (
116
- value: Resolved<
130
+ listener: SubscribeCallback<
131
+ Resolved<
117
132
  CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
118
133
  R
119
- >,
120
- unsubscribe: () => void,
121
- ) => void,
134
+ >
135
+ >,
136
+ ): () => void;
137
+ subscribe<
138
+ const R extends RefsToResolve<
139
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion
140
+ >,
141
+ >(
142
+ id: string,
143
+ optionsOrListener:
144
+ | SubscribeListenerOptions<
145
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> &
146
+ SchemaUnion,
147
+ R
148
+ >
149
+ | SubscribeCallback<
150
+ Resolved<
151
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> &
152
+ SchemaUnion,
153
+ R
154
+ >
155
+ >,
156
+ maybeListener?: SubscribeCallback<
157
+ Resolved<
158
+ CoDiscriminatedUnionInstanceCoValuesMaybeLoaded<Options> & SchemaUnion,
159
+ R
160
+ >
161
+ >,
122
162
  ): () => void {
163
+ if (typeof optionsOrListener === "function") {
164
+ // @ts-expect-error
165
+ return this.coValueClass.subscribe(
166
+ id,
167
+ withSchemaResolveQuery({}, this.resolveQuery),
168
+ optionsOrListener,
169
+ );
170
+ }
123
171
  // @ts-expect-error
124
172
  return this.coValueClass.subscribe(
125
173
  id,
126
- withSchemaResolveQuery(options, this.resolveQuery),
127
- listener,
174
+ withSchemaResolveQuery(optionsOrListener, this.resolveQuery),
175
+ maybeListener,
128
176
  );
129
177
  }
130
178