jazz-tools 0.11.8 → 0.12.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 (62) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +22 -0
  3. package/dist/auth/DemoAuth.d.ts.map +1 -1
  4. package/dist/auth/PassphraseAuth.d.ts.map +1 -1
  5. package/dist/{chunk-HH3Z4JSB.js → chunk-QJNU65NK.js} +414 -275
  6. package/dist/chunk-QJNU65NK.js.map +1 -0
  7. package/dist/coValues/account.d.ts +15 -17
  8. package/dist/coValues/account.d.ts.map +1 -1
  9. package/dist/coValues/coFeed.d.ts +23 -18
  10. package/dist/coValues/coFeed.d.ts.map +1 -1
  11. package/dist/coValues/coList.d.ts +14 -7
  12. package/dist/coValues/coList.d.ts.map +1 -1
  13. package/dist/coValues/coMap.d.ts +36 -33
  14. package/dist/coValues/coMap.d.ts.map +1 -1
  15. package/dist/coValues/coPlainText.d.ts +7 -5
  16. package/dist/coValues/coPlainText.d.ts.map +1 -1
  17. package/dist/coValues/deepLoading.d.ts +36 -19
  18. package/dist/coValues/deepLoading.d.ts.map +1 -1
  19. package/dist/coValues/group.d.ts +14 -7
  20. package/dist/coValues/group.d.ts.map +1 -1
  21. package/dist/coValues/inbox.d.ts.map +1 -1
  22. package/dist/coValues/interfaces.d.ts +45 -11
  23. package/dist/coValues/interfaces.d.ts.map +1 -1
  24. package/dist/exports.d.ts +1 -1
  25. package/dist/exports.d.ts.map +1 -1
  26. package/dist/implementation/refs.d.ts +3 -0
  27. package/dist/implementation/refs.d.ts.map +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/testing.d.ts +1 -1
  30. package/dist/testing.d.ts.map +1 -1
  31. package/dist/testing.js +4 -2
  32. package/dist/testing.js.map +1 -1
  33. package/package.json +2 -2
  34. package/src/auth/DemoAuth.ts +3 -1
  35. package/src/auth/PassphraseAuth.ts +3 -1
  36. package/src/coValues/account.ts +43 -49
  37. package/src/coValues/coFeed.ts +74 -146
  38. package/src/coValues/coList.ts +47 -54
  39. package/src/coValues/coMap.ts +47 -54
  40. package/src/coValues/coPlainText.ts +23 -40
  41. package/src/coValues/deepLoading.ts +233 -102
  42. package/src/coValues/group.ts +44 -54
  43. package/src/coValues/inbox.ts +3 -6
  44. package/src/coValues/interfaces.ts +216 -105
  45. package/src/exports.ts +7 -1
  46. package/src/implementation/refs.ts +45 -7
  47. package/src/testing.ts +4 -1
  48. package/src/tests/ContextManager.test.ts +20 -6
  49. package/src/tests/PassphraseAuth.test.ts +3 -1
  50. package/src/tests/account.test.ts +26 -2
  51. package/src/tests/coFeed.test.ts +26 -19
  52. package/src/tests/coList.test.ts +18 -18
  53. package/src/tests/coMap.test.ts +67 -19
  54. package/src/tests/coPlainText.test.ts +8 -4
  55. package/src/tests/coRichText.test.ts +10 -8
  56. package/src/tests/deepLoading.test.ts +321 -80
  57. package/src/tests/groupsAndAccounts.test.ts +10 -12
  58. package/src/tests/inbox.test.ts +1 -1
  59. package/src/tests/schemaUnion.test.ts +8 -18
  60. package/src/tests/subscribe.test.ts +52 -33
  61. package/src/tests/testing.test.ts +1 -1
  62. package/dist/chunk-HH3Z4JSB.js.map +0 -1
@@ -38,7 +38,7 @@ var AnonymousJazzAgent = class {
38
38
  };
39
39
 
40
40
  // src/coValues/interfaces.ts
41
- import { RawAccount as RawAccount2 } from "cojson";
41
+ import { RawAccount as RawAccount3 } from "cojson";
42
42
 
43
43
  // src/implementation/inspect.ts
44
44
  var inspect = Symbol.for("nodejs.util.inspect.custom");
@@ -48,19 +48,55 @@ var SchemaInit = "$SchemaInit$";
48
48
  var ItemsSym = "$items$";
49
49
 
50
50
  // src/coValues/deepLoading.ts
51
+ function hasRefValue(value, key) {
52
+ return Boolean(
53
+ value._refs?.[key]
54
+ );
55
+ }
56
+ function hasReadAccess(value, key) {
57
+ return Boolean(
58
+ value._refs?.[key]?.hasReadAccess()
59
+ );
60
+ }
61
+ function isOptionalField(value, key) {
62
+ return value._schema[key]?.optional ?? false;
63
+ }
51
64
  function fulfillsDepth(depth, value) {
65
+ if (depth === true || depth === void 0) {
66
+ return "fulfilled";
67
+ }
52
68
  if (value._type === "CoMap" || value._type === "Group" || value._type === "Account") {
53
- if (Array.isArray(depth) && depth.length === 1) {
54
- return Object.entries(value).every(([key, item]) => {
55
- return value._refs[key] ? item && fulfillsDepth(depth[0], item) : value._schema[ItemsSym].optional;
56
- });
69
+ const map = value;
70
+ if ("$each" in depth) {
71
+ let result = "fulfilled";
72
+ for (const [key, item] of Object.entries(value)) {
73
+ if (map._raw.get(key) !== void 0) {
74
+ if (!item) {
75
+ if (hasReadAccess(map, key)) {
76
+ result = "unfulfilled";
77
+ continue;
78
+ } else {
79
+ return "unauthorized";
80
+ }
81
+ }
82
+ const innerResult = fulfillsDepth(depth.$each, item);
83
+ if (innerResult === "unfulfilled") {
84
+ result = "unfulfilled";
85
+ } else if (innerResult === "unauthorized" && !isOptionalField(value, ItemsSym)) {
86
+ return "unauthorized";
87
+ }
88
+ } else if (!isOptionalField(value, ItemsSym)) {
89
+ return "unfulfilled";
90
+ }
91
+ }
92
+ return result;
57
93
  } else {
94
+ let result = "fulfilled";
58
95
  for (const key of Object.keys(depth)) {
59
- const map = value;
60
96
  if (map._raw.get(key) === void 0) {
61
97
  if (!map._schema?.[key]) {
62
98
  if (map._schema?.[ItemsSym]) {
63
- if (map._schema[ItemsSym].optional) {
99
+ if (isOptionalField(map, ItemsSym)) {
64
100
  continue;
65
101
  } else {
66
102
  throw new Error(
@@ -72,49 +108,96 @@ function fulfillsDepth(depth, value) {
72
108
  `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`
73
109
  );
74
110
  }
75
- } else if (map._schema[key].optional) {
111
+ } else if (isOptionalField(map, key)) {
76
112
  continue;
77
113
  } else {
78
114
  throw new Error(
79
115
  `The ref ${key} on ${map.constructor.name} is required but missing`
80
116
  );
81
117
  }
82
- }
83
- if (!map[key]) {
84
- return false;
85
- }
86
- if (!fulfillsDepth(depth[key], map[key])) {
87
- return false;
118
+ } else {
119
+ const item = value[key];
120
+ if (!item) {
121
+ if (hasReadAccess(map, key)) {
122
+ result = "unfulfilled";
123
+ continue;
124
+ } else {
125
+ return "unauthorized";
126
+ }
127
+ }
128
+ const innerResult = fulfillsDepth(depth[key], item);
129
+ if (innerResult === "unfulfilled") {
130
+ result = "unfulfilled";
131
+ } else if (innerResult === "unauthorized" && !isOptionalField(value, key)) {
132
+ return "unauthorized";
133
+ }
88
134
  }
89
135
  }
90
- return true;
136
+ return result;
91
137
  }
92
138
  } else if (value._type === "CoList") {
93
- if (depth.length === 0) {
94
- return true;
95
- } else {
96
- const itemDepth = depth[0];
97
- return value.every(
98
- (item, i) => value._refs[i] ? item && fulfillsDepth(itemDepth, item) : value._schema[ItemsSym].optional
99
- );
139
+ if ("$each" in depth) {
140
+ let result = "fulfilled";
141
+ for (const [key, item] of value.entries()) {
142
+ if (hasRefValue(value, key)) {
143
+ if (!item) {
144
+ if (hasReadAccess(value, key)) {
145
+ result = "unfulfilled";
146
+ continue;
147
+ } else {
148
+ return "unauthorized";
149
+ }
150
+ }
151
+ const innerResult = fulfillsDepth(depth.$each, item);
152
+ if (innerResult === "unfulfilled") {
153
+ result = "unfulfilled";
154
+ } else if (innerResult === "unauthorized" && !isOptionalField(value, ItemsSym)) {
155
+ return "unauthorized";
156
+ }
157
+ } else if (!isOptionalField(value, ItemsSym)) {
158
+ return "unfulfilled";
159
+ }
160
+ }
161
+ return result;
100
162
  }
163
+ return "fulfilled";
101
164
  } else if (value._type === "CoStream") {
102
- if (depth.length === 0) {
103
- return true;
104
- } else {
105
- const itemDepth = depth[0];
106
- return Object.values(value.perSession).every(
107
- (entry) => entry.ref ? entry.value && fulfillsDepth(itemDepth, entry.value) : value._schema[ItemsSym].optional
108
- );
165
+ if ("$each" in depth) {
166
+ let result = "fulfilled";
167
+ for (const item of Object.values(value.perSession)) {
168
+ if (item.ref) {
169
+ if (!item.value) {
170
+ if (item.ref.hasReadAccess()) {
171
+ result = "unfulfilled";
172
+ continue;
173
+ } else {
174
+ return "unauthorized";
175
+ }
176
+ }
177
+ const innerResult = fulfillsDepth(depth.$each, item.value);
178
+ if (innerResult === "unfulfilled") {
179
+ result = "unfulfilled";
180
+ } else if (innerResult === "unauthorized" && !isOptionalField(value, ItemsSym)) {
181
+ return "unauthorized";
182
+ }
183
+ } else if (!isOptionalField(value, ItemsSym)) {
184
+ return "unfulfilled";
185
+ }
186
+ }
187
+ return result;
109
188
  }
189
+ return "fulfilled";
110
190
  } else if (value._type === "BinaryCoStream" || value._type === "CoPlainText") {
111
- return true;
191
+ return "fulfilled";
112
192
  } else {
113
193
  console.error(value);
114
194
  throw new Error("Unexpected value type: " + value._type);
115
195
  }
116
196
  }
117
197
 
198
+ // src/implementation/refs.ts
199
+ import { RawAccount, RawGroup } from "cojson";
200
+
118
201
  // src/lib/cache.ts
119
202
  var weakMap = /* @__PURE__ */ new WeakMap();
120
203
  var coValuesCache = {
@@ -140,8 +223,30 @@ var Ref = class _Ref {
140
223
  throw new Error("Ref must be constructed with a ref schema");
141
224
  }
142
225
  }
143
- get value() {
144
- const node = "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
226
+ getNode() {
227
+ return "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
228
+ }
229
+ hasReadAccess() {
230
+ const node = this.getNode();
231
+ const raw = node.getLoaded(this.id);
232
+ if (!raw) {
233
+ return true;
234
+ }
235
+ if (raw instanceof RawAccount || raw instanceof RawGroup) {
236
+ return true;
237
+ }
238
+ const group = raw.core.getGroup();
239
+ if (group instanceof RawAccount) {
240
+ if (node.account.id !== group.id) {
241
+ return false;
242
+ }
243
+ } else if (group.myRole() === void 0) {
244
+ return false;
245
+ }
246
+ return true;
247
+ }
248
+ getValueWithoutAccessCheck() {
249
+ const node = this.getNode();
145
250
  const raw = node.getLoaded(this.id);
146
251
  if (raw) {
147
252
  return coValuesCache.get(
@@ -152,6 +257,12 @@ var Ref = class _Ref {
152
257
  return null;
153
258
  }
154
259
  }
260
+ get value() {
261
+ if (!this.hasReadAccess()) {
262
+ return null;
263
+ }
264
+ return this.getValueWithoutAccessCheck();
265
+ }
155
266
  async loadHelper() {
156
267
  const node = "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
157
268
  const raw = await node.load(this.id);
@@ -194,7 +305,7 @@ var Ref = class _Ref {
194
305
  } else if (this.value !== null) {
195
306
  const freshValueInstance = instantiateRefEncoded(
196
307
  this.schema,
197
- this.value?._raw
308
+ this.value._raw
198
309
  );
199
310
  TRACE_ACCESSES && console.log("freshValueInstance", freshValueInstance);
200
311
  subScope.cachedValues[this.id] = freshValueInstance;
@@ -697,7 +808,7 @@ function isCoValueClass(value) {
697
808
  }
698
809
  var CoValueBase = class {
699
810
  get _owner() {
700
- const owner = this._raw.group instanceof RawAccount2 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group);
811
+ const owner = this._raw.group instanceof RawAccount3 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group);
701
812
  const subScope = subscriptionsScopes.get(this);
702
813
  if (subScope) {
703
814
  subScope.onRefAccessedOrSet(this.id, owner.id);
@@ -708,7 +819,7 @@ var CoValueBase = class {
708
819
  /** @private */
709
820
  get _loadedAs() {
710
821
  const rawAccount = this._raw.core.node.account;
711
- if (rawAccount instanceof RawAccount2) {
822
+ if (rawAccount instanceof RawAccount3) {
712
823
  return coValuesCache.get(
713
824
  rawAccount,
714
825
  () => RegisteredSchemas["Account"].fromRaw(rawAccount)
@@ -748,77 +859,90 @@ var CoValueBase = class {
748
859
  return casted;
749
860
  }
750
861
  };
751
- function loadCoValueWithoutMe(cls, id, asOrDepth, depth) {
752
- if (isAccountInstance(asOrDepth) || isAnonymousAgentInstance(asOrDepth)) {
753
- if (!depth) {
754
- throw new Error(
755
- "Depth is required when loading a CoValue as an Account or AnonymousJazzAgent"
756
- );
757
- }
758
- return loadCoValue2(cls, id, asOrDepth, depth);
759
- }
760
- return loadCoValue2(cls, id, activeAccountContext.get(), asOrDepth);
862
+ function loadCoValueWithoutMe(cls, id, options) {
863
+ return loadCoValue2(cls, id, {
864
+ ...options,
865
+ loadAs: options?.loadAs ?? activeAccountContext.get()
866
+ });
761
867
  }
762
- function loadCoValue2(cls, id, as, depth) {
868
+ function loadCoValue2(cls, id, options) {
763
869
  return new Promise((resolve) => {
764
870
  subscribeToCoValue(
765
871
  cls,
766
872
  id,
767
- as,
768
- depth,
873
+ {
874
+ resolve: options.resolve,
875
+ loadAs: options.loadAs,
876
+ onUnavailable: () => {
877
+ resolve(null);
878
+ },
879
+ onUnauthorized: () => {
880
+ resolve(null);
881
+ }
882
+ },
769
883
  (value, unsubscribe) => {
770
884
  resolve(value);
771
885
  unsubscribe();
772
- },
773
- () => {
774
- resolve(void 0);
775
886
  }
776
887
  );
777
888
  });
778
889
  }
779
- async function ensureCoValueLoaded(existing, depth) {
890
+ async function ensureCoValueLoaded(existing, options) {
780
891
  const response = await loadCoValue2(
781
892
  existing.constructor,
782
893
  existing.id,
783
- existing._loadedAs,
784
- depth
894
+ {
895
+ loadAs: existing._loadedAs,
896
+ resolve: options?.resolve
897
+ }
785
898
  );
786
899
  if (!response) {
787
900
  throw new Error("Failed to deeply load CoValue " + existing.id);
788
901
  }
789
902
  return response;
790
903
  }
791
- function subscribeToCoValueWithoutMe(cls, id, asOrDepth, depthOrListener, listener) {
792
- if (isAccountInstance(asOrDepth) || isAnonymousAgentInstance(asOrDepth)) {
793
- if (typeof depthOrListener !== "function") {
794
- return subscribeToCoValue(
795
- cls,
796
- id,
797
- asOrDepth,
798
- depthOrListener,
799
- listener
800
- );
904
+ function parseSubscribeRestArgs(args) {
905
+ if (args.length === 2) {
906
+ if (typeof args[0] === "object" && args[0] && typeof args[1] === "function") {
907
+ return {
908
+ options: {
909
+ resolve: args[0].resolve,
910
+ loadAs: args[0].loadAs,
911
+ onUnauthorized: args[0].onUnauthorized,
912
+ onUnavailable: args[0].onUnavailable
913
+ },
914
+ listener: args[1]
915
+ };
916
+ } else {
917
+ throw new Error("Invalid arguments");
918
+ }
919
+ } else {
920
+ if (typeof args[0] === "function") {
921
+ return { options: {}, listener: args[0] };
922
+ } else {
923
+ throw new Error("Invalid arguments");
801
924
  }
802
- throw new Error("Invalid arguments");
803
- }
804
- if (typeof depthOrListener !== "function") {
805
- throw new Error("Invalid arguments");
806
925
  }
926
+ }
927
+ function subscribeToCoValueWithoutMe(cls, id, options, listener) {
807
928
  return subscribeToCoValue(
808
929
  cls,
809
930
  id,
810
- activeAccountContext.get(),
811
- asOrDepth,
812
- depthOrListener
931
+ {
932
+ ...options,
933
+ loadAs: options.loadAs ?? activeAccountContext.get()
934
+ },
935
+ listener
813
936
  );
814
937
  }
815
- function subscribeToCoValue(cls, id, as, depth, listener, onUnavailable, syncResolution) {
816
- const ref2 = new Ref(id, as, { ref: cls, optional: false });
938
+ function subscribeToCoValue(cls, id, options, listener) {
939
+ const ref2 = new Ref(id, options.loadAs, { ref: cls, optional: false });
817
940
  let unsubscribed = false;
818
941
  let unsubscribe;
819
- function subscribe(value) {
942
+ function subscribe() {
943
+ const value = ref2.getValueWithoutAccessCheck();
820
944
  if (!value) {
821
- onUnavailable && onUnavailable();
945
+ options.onUnavailable?.();
822
946
  return;
823
947
  }
824
948
  if (unsubscribed) return;
@@ -826,27 +950,48 @@ function subscribeToCoValue(cls, id, as, depth, listener, onUnavailable, syncRes
826
950
  value,
827
951
  cls,
828
952
  (update, subscription2) => {
829
- if (subscription2.syncResolution) return false;
830
- subscription2.syncResolution = true;
831
- const isLoaded = fulfillsDepth(depth, update);
832
- subscription2.syncResolution = false;
833
- if (isLoaded) {
834
- listener(
835
- update,
836
- subscription2.unsubscribeAll
953
+ if (subscription2.syncResolution) return;
954
+ if (!ref2.hasReadAccess()) {
955
+ options.onUnauthorized?.();
956
+ return;
957
+ }
958
+ let result;
959
+ try {
960
+ subscription2.syncResolution = true;
961
+ result = fulfillsDepth(options.resolve, update);
962
+ } catch (e) {
963
+ console.error(
964
+ "Failed to load / subscribe to CoValue",
965
+ e,
966
+ e instanceof Error ? e.stack : void 0
837
967
  );
968
+ options.onUnavailable?.();
969
+ return;
970
+ } finally {
971
+ subscription2.syncResolution = false;
972
+ }
973
+ if (result === "unauthorized") {
974
+ options.onUnauthorized?.();
975
+ return;
976
+ }
977
+ if (result === "fulfilled") {
978
+ listener(update, subscription2.unsubscribeAll);
838
979
  }
839
980
  }
840
981
  );
841
982
  unsubscribe = subscription.unsubscribeAll;
842
983
  }
843
- const sync = syncResolution ? ref2.syncLoad() : void 0;
984
+ const sync = options.syncResolution ? ref2.syncLoad() : void 0;
844
985
  if (sync) {
845
- subscribe(sync);
986
+ subscribe();
846
987
  } else {
847
- ref2.load().then((value) => subscribe(value)).catch((e) => {
848
- console.error("Failed to load / subscribe to CoValue", e);
849
- onUnavailable?.();
988
+ ref2.load().then(() => subscribe()).catch((e) => {
989
+ console.error(
990
+ "Failed to load / subscribe to CoValue",
991
+ e,
992
+ e instanceof Error ? e.stack : void 0
993
+ );
994
+ options.onUnavailable?.();
850
995
  });
851
996
  }
852
997
  return function unsubscribeAtAnyPoint() {
@@ -854,25 +999,31 @@ function subscribeToCoValue(cls, id, as, depth, listener, onUnavailable, syncRes
854
999
  unsubscribe && unsubscribe();
855
1000
  };
856
1001
  }
857
- function createCoValueObservable(options) {
1002
+ function createCoValueObservable() {
858
1003
  let currentValue = void 0;
859
1004
  let subscriberCount = 0;
860
- function subscribe(cls, id, as, depth, listener, onUnavailable) {
1005
+ function subscribe(cls, id, options, listener) {
861
1006
  subscriberCount++;
862
1007
  const unsubscribe = subscribeToCoValue(
863
1008
  cls,
864
1009
  id,
865
- as,
866
- depth,
1010
+ {
1011
+ loadAs: options.loadAs,
1012
+ resolve: options.resolve,
1013
+ onUnavailable: () => {
1014
+ currentValue = null;
1015
+ options.onUnavailable?.();
1016
+ },
1017
+ onUnauthorized: () => {
1018
+ currentValue = null;
1019
+ options.onUnauthorized?.();
1020
+ },
1021
+ syncResolution: options.syncResolution
1022
+ },
867
1023
  (value) => {
868
1024
  currentValue = value;
869
1025
  listener();
870
- },
871
- () => {
872
- currentValue = null;
873
- onUnavailable?.();
874
- },
875
- options?.syncResolution
1026
+ }
876
1027
  );
877
1028
  return () => {
878
1029
  unsubscribe();
@@ -888,12 +1039,16 @@ function createCoValueObservable(options) {
888
1039
  };
889
1040
  return observable;
890
1041
  }
891
- function subscribeToExistingCoValue(existing, depth, listener) {
1042
+ function subscribeToExistingCoValue(existing, options, listener) {
892
1043
  return subscribeToCoValue(
893
1044
  existing.constructor,
894
1045
  existing.id,
895
- existing._loadedAs,
896
- depth,
1046
+ {
1047
+ loadAs: existing._loadedAs,
1048
+ resolve: options?.resolve,
1049
+ onUnavailable: options?.onUnavailable,
1050
+ onUnauthorized: options?.onUnauthorized
1051
+ },
897
1052
  listener
898
1053
  );
899
1054
  }
@@ -903,12 +1058,6 @@ function isAccountInstance(instance) {
903
1058
  }
904
1059
  return "_type" in instance && instance._type === "Account";
905
1060
  }
906
- function isAnonymousAgentInstance(instance) {
907
- if (typeof instance !== "object" || instance === null) {
908
- return false;
909
- }
910
- return "_type" in instance && instance._type === "Anonymous";
911
- }
912
1061
  function parseCoValueCreateOptions(options) {
913
1062
  const Group2 = RegisteredSchemas["Group"];
914
1063
  if (!options) {
@@ -934,7 +1083,7 @@ function parseGroupCreateOptions(options) {
934
1083
 
935
1084
  // src/coValues/inbox.ts
936
1085
  import {
937
- RawAccount as RawAccount3
1086
+ RawAccount as RawAccount4
938
1087
  } from "cojson";
939
1088
  function createInboxRoot(account) {
940
1089
  if (!account.isLocalNodeOwner) {
@@ -957,7 +1106,7 @@ function createInboxRoot(account) {
957
1106
  }
958
1107
  function createInboxMessage(payload, inboxOwner) {
959
1108
  const group = payload._raw.group;
960
- if (group instanceof RawAccount3) {
1109
+ if (group instanceof RawAccount4) {
961
1110
  throw new Error("Inbox messages should be owned by a group");
962
1111
  }
963
1112
  group.addMember(inboxOwner, "writer");
@@ -1015,12 +1164,9 @@ var Inbox = class _Inbox {
1015
1164
  new Error("Unable to load inbox message " + id)
1016
1165
  );
1017
1166
  }
1018
- return loadCoValue2(
1019
- Schema,
1020
- message.get("payload"),
1021
- account,
1022
- []
1023
- );
1167
+ return loadCoValue2(Schema, message.get("payload"), {
1168
+ loadAs: account
1169
+ });
1024
1170
  }).then((value) => {
1025
1171
  if (!value) {
1026
1172
  return Promise.reject(
@@ -1397,17 +1543,32 @@ var _CoMap = class _CoMap extends CoValueBase {
1397
1543
  }
1398
1544
  return RecordLikeCoMap;
1399
1545
  }
1400
- static load(id, asOrDepth, depth) {
1401
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
1546
+ /**
1547
+ * Load a `CoMap` with a given ID, as a given account.
1548
+ *
1549
+ * `depth` specifies which (if any) fields that reference other CoValues to load as well before resolving.
1550
+ * The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
1551
+ *
1552
+ * You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
1553
+ *
1554
+ * Check out the `load` methods on `CoMap`/`CoList`/`CoFeed`/`Group`/`Account` to see which depth structures are valid to nest.
1555
+ *
1556
+ * @example
1557
+ * ```ts
1558
+ * const person = await Person.load(
1559
+ * "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
1560
+ * { pet: {} }
1561
+ * );
1562
+ * ```
1563
+ *
1564
+ * @category Subscription & Loading
1565
+ */
1566
+ static load(id, options) {
1567
+ return loadCoValueWithoutMe(this, id, options);
1402
1568
  }
1403
- static subscribe(id, asOrDepth, depthOrListener, listener) {
1404
- return subscribeToCoValueWithoutMe(
1405
- this,
1406
- id,
1407
- asOrDepth,
1408
- depthOrListener,
1409
- listener
1410
- );
1569
+ static subscribe(id, ...args) {
1570
+ const { options, listener } = parseSubscribeRestArgs(args);
1571
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
1411
1572
  }
1412
1573
  static findUnique(unique, ownerID, as) {
1413
1574
  as ||= activeAccountContext.get();
@@ -1430,20 +1591,12 @@ var _CoMap = class _CoMap extends CoValueBase {
1430
1591
  *
1431
1592
  * @category Subscription & Loading
1432
1593
  */
1433
- ensureLoaded(depth) {
1434
- return ensureCoValueLoaded(this, depth);
1594
+ ensureLoaded(options) {
1595
+ return ensureCoValueLoaded(this, options);
1435
1596
  }
1436
- /**
1437
- * Given an already loaded `CoMap`, subscribe to updates to the `CoMap` and ensure that the specified fields are loaded to the specified depth.
1438
- *
1439
- * Works like `CoMap.subscribe()`, but you don't need to pass the ID or the account to load as again.
1440
- *
1441
- * Returns an unsubscribe function that you should call when you no longer need updates.
1442
- *
1443
- * @category Subscription & Loading
1444
- **/
1445
- subscribe(depth, listener) {
1446
- return subscribeToExistingCoValue(this, depth, listener);
1597
+ subscribe(...args) {
1598
+ const { options, listener } = parseSubscribeRestArgs(args);
1599
+ return subscribeToExistingCoValue(this, options, listener);
1447
1600
  }
1448
1601
  applyDiff(newValues) {
1449
1602
  for (const key in newValues) {
@@ -1625,7 +1778,7 @@ var Profile = class extends CoMap {
1625
1778
  // src/coValues/account.ts
1626
1779
  import {
1627
1780
  LocalNode as LocalNode2,
1628
- RawAccount as RawAccount4,
1781
+ RawAccount as RawAccount5,
1629
1782
  cojsonInternals as cojsonInternals2
1630
1783
  } from "cojson";
1631
1784
  var _Account = class _Account extends CoValueBase {
@@ -1638,7 +1791,7 @@ var _Account = class _Account extends CoValueBase {
1638
1791
  get _loadedAs() {
1639
1792
  if (this.isLocalNodeOwner) return this;
1640
1793
  const rawAccount = this._raw.core.node.account;
1641
- if (rawAccount instanceof RawAccount4) {
1794
+ if (rawAccount instanceof RawAccount5) {
1642
1795
  return coValuesCache.get(rawAccount, () => _Account.fromRaw(rawAccount));
1643
1796
  }
1644
1797
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -1729,7 +1882,9 @@ var _Account = class _Account extends CoValueBase {
1729
1882
  valueID,
1730
1883
  inviteSecret
1731
1884
  );
1732
- return loadCoValue2(coValueClass, valueID, this, []);
1885
+ return loadCoValue2(coValueClass, valueID, {
1886
+ loadAs: this
1887
+ });
1733
1888
  }
1734
1889
  /** @private */
1735
1890
  static async create(options) {
@@ -1800,25 +1955,21 @@ var _Account = class _Account extends CoValueBase {
1800
1955
  migrate(creationProps) {
1801
1956
  creationProps;
1802
1957
  }
1803
- static load(id, asOrDepth, depth) {
1804
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
1958
+ /** @category Subscription & Loading */
1959
+ static load(id, options) {
1960
+ return loadCoValueWithoutMe(this, id, options);
1805
1961
  }
1806
- static subscribe(id, asOrDepth, depthOrListener, listener) {
1807
- return subscribeToCoValueWithoutMe(
1808
- this,
1809
- id,
1810
- asOrDepth,
1811
- depthOrListener,
1812
- listener
1813
- );
1962
+ static subscribe(id, ...args) {
1963
+ const { options, listener } = parseSubscribeRestArgs(args);
1964
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
1814
1965
  }
1815
1966
  /** @category Subscription & Loading */
1816
- ensureLoaded(depth) {
1817
- return ensureCoValueLoaded(this, depth);
1967
+ ensureLoaded(options) {
1968
+ return ensureCoValueLoaded(this, options);
1818
1969
  }
1819
- /** @category Subscription & Loading */
1820
- subscribe(depth, listener) {
1821
- return subscribeToExistingCoValue(this, depth, listener);
1970
+ subscribe(...args) {
1971
+ const { options, listener } = parseSubscribeRestArgs(args);
1972
+ return subscribeToExistingCoValue(this, options, listener);
1822
1973
  }
1823
1974
  /**
1824
1975
  * Wait for the `Account` to be uploaded to the other peers.
@@ -2058,36 +2209,29 @@ var _CoFeed = class _CoFeed extends CoValueBase {
2058
2209
  this._schema ||= {};
2059
2210
  Object.assign(this._schema, def);
2060
2211
  }
2061
- static load(id, asOrDepth, depth) {
2062
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
2063
- }
2064
- static subscribe(id, asOrDepth, depthOrListener, listener) {
2065
- return subscribeToCoValueWithoutMe(
2066
- this,
2067
- id,
2068
- asOrDepth,
2069
- depthOrListener,
2070
- listener
2071
- );
2072
- }
2073
2212
  /**
2074
- * Ensure a `CoFeed` is loaded to the specified depth
2075
- *
2076
- * @returns A new instance of the same CoFeed that's loaded to the specified depth,
2077
- * or undefined if it cannot be loaded that deeply
2213
+ * Load a `CoFeed`
2078
2214
  * @category Subscription & Loading
2079
2215
  */
2080
- ensureLoaded(depth) {
2081
- return ensureCoValueLoaded(this, depth);
2216
+ static load(id, options) {
2217
+ return loadCoValueWithoutMe(this, id, options);
2218
+ }
2219
+ static subscribe(id, ...args) {
2220
+ const { options, listener } = parseSubscribeRestArgs(args);
2221
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
2082
2222
  }
2083
2223
  /**
2084
- * An instance method to subscribe to an existing `CoFeed`
2224
+ * Ensure a `CoFeed` is loaded to the specified depth
2085
2225
  *
2086
- * No need to provide an ID or Account since they're already part of the instance.
2226
+ * @returns A new instance of the same CoFeed that's loaded to the specified depth
2087
2227
  * @category Subscription & Loading
2088
2228
  */
2089
- subscribe(depth, listener) {
2090
- return subscribeToExistingCoValue(this, depth, listener);
2229
+ ensureLoaded(options) {
2230
+ return ensureCoValueLoaded(this, options);
2231
+ }
2232
+ subscribe(...args) {
2233
+ const { options, listener } = parseSubscribeRestArgs(args);
2234
+ return subscribeToExistingCoValue(this, options, listener);
2091
2235
  }
2092
2236
  /**
2093
2237
  * Wait for the `CoFeed` to be uploaded to the other peers.
@@ -2336,18 +2480,26 @@ var FileStream = class extends CoValueBase {
2336
2480
  }
2337
2481
  return new Blob(chunks.chunks, { type: chunks.mimeType });
2338
2482
  }
2339
- static async loadAsBlob(id, asOrOptions, optionsOrUndefined) {
2340
- const as = isAccountInstance(asOrOptions) ? asOrOptions : activeAccountContext.get();
2341
- const options = isAccountInstance(asOrOptions) ? optionsOrUndefined : asOrOptions;
2342
- let stream = await this.load(id, as, []);
2483
+ /**
2484
+ * Load a `FileStream` as a `Blob`
2485
+ *
2486
+ * @category Content
2487
+ */
2488
+ static async loadAsBlob(id, options) {
2489
+ let stream = await this.load(id, options);
2343
2490
  if (!options?.allowUnfinished && !stream?.isBinaryStreamEnded()) {
2344
2491
  stream = await new Promise((resolve) => {
2345
- subscribeToCoValue(this, id, as, [], (value, unsubscribe) => {
2346
- if (value.isBinaryStreamEnded()) {
2347
- unsubscribe();
2348
- resolve(value);
2492
+ subscribeToCoValueWithoutMe(
2493
+ this,
2494
+ id,
2495
+ options || {},
2496
+ (value, unsubscribe) => {
2497
+ if (value.isBinaryStreamEnded()) {
2498
+ unsubscribe();
2499
+ resolve(value);
2500
+ }
2349
2501
  }
2350
- });
2502
+ );
2351
2503
  });
2352
2504
  }
2353
2505
  return stream?.toBlob({
@@ -2411,27 +2563,26 @@ var FileStream = class extends CoValueBase {
2411
2563
  [inspect]() {
2412
2564
  return this.toJSON();
2413
2565
  }
2414
- static load(id, asOrDepth, depth) {
2415
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
2416
- }
2417
- static subscribe(id, asOrDepth, depthOrListener, listener) {
2418
- return subscribeToCoValueWithoutMe(
2419
- this,
2420
- id,
2421
- asOrDepth,
2422
- depthOrListener,
2423
- listener
2424
- );
2566
+ /**
2567
+ * Load a `FileStream`
2568
+ * @category Subscription & Loading
2569
+ */
2570
+ static load(id, options) {
2571
+ return loadCoValueWithoutMe(this, id, options);
2425
2572
  }
2426
- ensureLoaded(depth) {
2427
- return ensureCoValueLoaded(this, depth);
2573
+ /**
2574
+ * Subscribe to a `FileStream`, when you have an ID but don't have a `FileStream` instance yet
2575
+ * @category Subscription & Loading
2576
+ */
2577
+ static subscribe(id, options, listener) {
2578
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
2428
2579
  }
2429
2580
  /**
2430
2581
  * An instance method to subscribe to an existing `FileStream`
2431
2582
  * @category Subscription & Loading
2432
2583
  */
2433
- subscribe(depth, listener) {
2434
- return subscribeToExistingCoValue(this, depth, listener);
2584
+ subscribe(listener) {
2585
+ return subscribeToExistingCoValue(this, {}, listener);
2435
2586
  }
2436
2587
  /**
2437
2588
  * Wait for the `FileStream` to be uploaded to the other peers.
@@ -2444,7 +2595,7 @@ var FileStream = class extends CoValueBase {
2444
2595
  };
2445
2596
 
2446
2597
  // src/coValues/coList.ts
2447
- import { RawAccount as RawAccount5 } from "cojson";
2598
+ import { RawAccount as RawAccount6 } from "cojson";
2448
2599
  import { calcPatch } from "fast-myers-diff";
2449
2600
  var _CoList = class _CoList extends Array {
2450
2601
  /**
@@ -2483,7 +2634,7 @@ var _CoList = class _CoList extends Array {
2483
2634
  }
2484
2635
  /** @category Collaboration */
2485
2636
  get _owner() {
2486
- return this._raw.group instanceof RawAccount5 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group);
2637
+ return this._raw.group instanceof RawAccount6 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group);
2487
2638
  }
2488
2639
  /**
2489
2640
  * If a `CoList`'s items are a `co.ref(...)`, you can use `coList._refs[i]` to access
@@ -2515,7 +2666,7 @@ var _CoList = class _CoList extends Array {
2515
2666
  }
2516
2667
  get _loadedAs() {
2517
2668
  const rawAccount = this._raw.core.node.account;
2518
- if (rawAccount instanceof RawAccount5) {
2669
+ if (rawAccount instanceof RawAccount6) {
2519
2670
  return coValuesCache.get(
2520
2671
  rawAccount,
2521
2672
  () => RegisteredSchemas["Account"].fromRaw(rawAccount)
@@ -2690,39 +2841,48 @@ var _CoList = class _CoList extends Array {
2690
2841
  this._schema ||= {};
2691
2842
  Object.assign(this._schema, def);
2692
2843
  }
2693
- static load(id, asOrDepth, depth) {
2694
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
2695
- }
2696
- static subscribe(id, asOrDepth, depthOrListener, listener) {
2697
- return subscribeToCoValueWithoutMe(
2698
- this,
2699
- id,
2700
- asOrDepth,
2701
- depthOrListener,
2702
- listener
2703
- );
2704
- }
2705
2844
  /**
2706
- * Given an already loaded `CoList`, ensure that items are loaded to the specified depth.
2845
+ * Load a `CoList` with a given ID, as a given account.
2707
2846
  *
2708
- * Works like `CoList.load()`, but you don't need to pass the ID or the account to load as again.
2847
+ * `depth` specifies if item CoValue references should be loaded as well before resolving.
2848
+ * The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
2849
+ *
2850
+ * You can pass `[]` or for shallowly loading only this CoList, or `[itemDepth]` for recursively loading referenced CoValues.
2851
+ *
2852
+ * Check out the `load` methods on `CoMap`/`CoList`/`CoFeed`/`Group`/`Account` to see which depth structures are valid to nest.
2853
+ *
2854
+ * @example
2855
+ * ```ts
2856
+ * const animalsWithVets =
2857
+ * await ListOfAnimals.load(
2858
+ * "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
2859
+ * me,
2860
+ * [{ vet: {} }]
2861
+ * );
2862
+ * ```
2709
2863
  *
2710
2864
  * @category Subscription & Loading
2711
2865
  */
2712
- ensureLoaded(depth) {
2713
- return ensureCoValueLoaded(this, depth);
2866
+ static load(id, options) {
2867
+ return loadCoValueWithoutMe(this, id, options);
2868
+ }
2869
+ static subscribe(id, ...args) {
2870
+ const { options, listener } = parseSubscribeRestArgs(args);
2871
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
2714
2872
  }
2715
2873
  /**
2716
- * Given an already loaded `CoList`, subscribe to updates to the `CoList` and ensure that items are loaded to the specified depth.
2717
- *
2718
- * Works like `CoList.subscribe()`, but you don't need to pass the ID or the account to load as again.
2874
+ * Given an already loaded `CoList`, ensure that items are loaded to the specified depth.
2719
2875
  *
2720
- * Returns an unsubscribe function that you should call when you no longer need updates.
2876
+ * Works like `CoList.load()`, but you don't need to pass the ID or the account to load as again.
2721
2877
  *
2722
2878
  * @category Subscription & Loading
2723
- **/
2724
- subscribe(depth, listener) {
2725
- return subscribeToExistingCoValue(this, depth, listener);
2879
+ */
2880
+ ensureLoaded(options) {
2881
+ return ensureCoValueLoaded(this, options);
2882
+ }
2883
+ subscribe(...args) {
2884
+ const { options, listener } = parseSubscribeRestArgs(args);
2885
+ return subscribeToExistingCoValue(this, options, listener);
2726
2886
  }
2727
2887
  /** @category Type Helpers */
2728
2888
  castAs(cl) {
@@ -2937,25 +3097,21 @@ var _Group = class _Group extends CoValueBase {
2937
3097
  await this._raw.revokeExtend(parent._raw);
2938
3098
  return this;
2939
3099
  }
2940
- static load(id, asOrDepth, depth) {
2941
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
3100
+ /** @category Subscription & Loading */
3101
+ static load(id, options) {
3102
+ return loadCoValueWithoutMe(this, id, options);
2942
3103
  }
2943
- static subscribe(id, asOrDepth, depthOrListener, listener) {
2944
- return subscribeToCoValueWithoutMe(
2945
- this,
2946
- id,
2947
- asOrDepth,
2948
- depthOrListener,
2949
- listener
2950
- );
3104
+ static subscribe(id, ...args) {
3105
+ const { options, listener } = parseSubscribeRestArgs(args);
3106
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
2951
3107
  }
2952
3108
  /** @category Subscription & Loading */
2953
- ensureLoaded(depth) {
2954
- return ensureCoValueLoaded(this, depth);
3109
+ ensureLoaded(options) {
3110
+ return ensureCoValueLoaded(this, options);
2955
3111
  }
2956
- /** @category Subscription & Loading */
2957
- subscribe(depth, listener) {
2958
- return subscribeToExistingCoValue(this, depth, listener);
3112
+ subscribe(...args) {
3113
+ const { options, listener } = parseSubscribeRestArgs(args);
3114
+ return subscribeToExistingCoValue(this, options, listener);
2959
3115
  }
2960
3116
  /**
2961
3117
  * Wait for the `Group` to be uploaded to the other peers.
@@ -2983,12 +3139,12 @@ function isAccountID(id) {
2983
3139
 
2984
3140
  // src/coValues/coPlainText.ts
2985
3141
  import {
2986
- RawAccount as RawAccount6,
3142
+ RawAccount as RawAccount7,
2987
3143
  stringifyOpID
2988
3144
  } from "cojson";
2989
3145
  var CoPlainText = class extends String {
2990
3146
  get _owner() {
2991
- return this._raw.group instanceof RawAccount6 ? Account.fromRaw(this._raw.group) : Group.fromRaw(this._raw.group);
3147
+ return this._raw.group instanceof RawAccount7 ? Account.fromRaw(this._raw.group) : Group.fromRaw(this._raw.group);
2992
3148
  }
2993
3149
  get _loadedAs() {
2994
3150
  return Account.fromNode(this._raw.core.node);
@@ -3051,34 +3207,13 @@ var CoPlainText = class extends String {
3051
3207
  *
3052
3208
  * @category Subscription & Loading
3053
3209
  */
3054
- static load(id, as) {
3055
- return loadCoValue2(this, id, as ?? activeAccountContext.get(), []);
3210
+ static load(id, options) {
3211
+ return loadCoValueWithoutMe(this, id, options);
3056
3212
  }
3057
- static subscribe(id, asOrListener, listener) {
3058
- if (isAccountInstance(asOrListener)) {
3059
- return subscribeToCoValue(this, id, asOrListener, [], listener);
3060
- }
3061
- return subscribeToCoValue(
3062
- this,
3063
- id,
3064
- activeAccountContext.get(),
3065
- [],
3066
- listener
3067
- );
3213
+ static subscribe(id, ...args) {
3214
+ const { options, listener } = parseSubscribeRestArgs(args);
3215
+ return subscribeToCoValueWithoutMe(this, id, options, listener);
3068
3216
  }
3069
- // /**
3070
- // * Effectful version of `CoMap.subscribe()` that returns a stream of updates.
3071
- // *
3072
- // * Needs to be run inside an `AccountCtx` context.
3073
- // *
3074
- // * @category Subscription & Loading
3075
- // */
3076
- // static subscribeEf<T extends CoPlainText>(
3077
- // this: CoValueClass<T>,
3078
- // id: ID<T>,
3079
- // ): Stream.Stream<T, UnavailableError, AccountCtx> {
3080
- // return subscribeToCoValueEf(this, id, []);
3081
- // }
3082
3217
  /**
3083
3218
  * Given an already loaded `CoPlainText`, subscribe to updates to the `CoPlainText` and ensure that the specified fields are loaded to the specified depth.
3084
3219
  *
@@ -3089,7 +3224,7 @@ var CoPlainText = class extends String {
3089
3224
  * @category Subscription & Loading
3090
3225
  **/
3091
3226
  subscribe(listener) {
3092
- return subscribeToExistingCoValue(this, [], listener);
3227
+ return subscribeToExistingCoValue(this, {}, listener);
3093
3228
  }
3094
3229
  };
3095
3230
 
@@ -3956,7 +4091,9 @@ var DemoAuth = class {
3956
4091
  throw new Error("No credentials found");
3957
4092
  }
3958
4093
  const currentAccount = await Account.getMe().ensureLoaded({
3959
- profile: {}
4094
+ resolve: {
4095
+ profile: true
4096
+ }
3960
4097
  });
3961
4098
  currentAccount.profile.name = username;
3962
4099
  await this.authSecretStorage.set({
@@ -4097,7 +4234,9 @@ var PassphraseAuth = class {
4097
4234
  });
4098
4235
  if (name?.trim()) {
4099
4236
  const currentAccount = await Account.getMe().ensureLoaded({
4100
- profile: {}
4237
+ resolve: {
4238
+ profile: true
4239
+ }
4101
4240
  });
4102
4241
  currentAccount.profile.name = name;
4103
4242
  }
@@ -4240,4 +4379,4 @@ export {
4240
4379
  consumeInviteLink
4241
4380
  };
4242
4381
  /* istanbul ignore file -- @preserve */
4243
- //# sourceMappingURL=chunk-HH3Z4JSB.js.map
4382
+ //# sourceMappingURL=chunk-QJNU65NK.js.map