jazz-tools 0.11.8 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +15 -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
@@ -6,94 +6,208 @@ import { type CoList } from "./coList.js";
6
6
  import { type CoKeys, type CoMap } from "./coMap.js";
7
7
  import { type CoValue, type ID } from "./interfaces.js";
8
8
 
9
+ function hasRefValue(value: CoValue, key: string | number) {
10
+ return Boolean(
11
+ (
12
+ value as unknown as {
13
+ _refs: { [key: string]: Ref<CoValue> | undefined };
14
+ }
15
+ )._refs?.[key],
16
+ );
17
+ }
18
+
19
+ function hasReadAccess(value: CoValue, key: string | number) {
20
+ return Boolean(
21
+ (
22
+ value as unknown as {
23
+ _refs: { [key: string]: Ref<CoValue> | undefined };
24
+ }
25
+ )._refs?.[key]?.hasReadAccess(),
26
+ );
27
+ }
28
+
29
+ function isOptionalField(value: CoValue, key: string): boolean {
30
+ return (
31
+ ((value as CoMap)._schema[key] as RefEncoded<CoValue>)?.optional ?? false
32
+ );
33
+ }
34
+
35
+ type FulfillsDepthResult = "unauthorized" | "fulfilled" | "unfulfilled";
36
+
9
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- export function fulfillsDepth(depth: any, value: CoValue): boolean {
38
+ export function fulfillsDepth(depth: any, value: CoValue): FulfillsDepthResult {
39
+ if (depth === true || depth === undefined) {
40
+ return "fulfilled";
41
+ }
42
+
11
43
  if (
12
44
  value._type === "CoMap" ||
13
45
  value._type === "Group" ||
14
46
  value._type === "Account"
15
47
  ) {
16
- if (Array.isArray(depth) && depth.length === 1) {
17
- return Object.entries(value).every(([key, item]) => {
18
- return (
19
- value as unknown as {
20
- _refs: { [key: string]: Ref<CoValue> | undefined };
48
+ const map = value as CoMap;
49
+
50
+ if ("$each" in depth) {
51
+ let result: FulfillsDepthResult = "fulfilled";
52
+
53
+ for (const [key, item] of Object.entries(value)) {
54
+ if (map._raw.get(key) !== undefined) {
55
+ if (!item) {
56
+ if (hasReadAccess(map, key)) {
57
+ result = "unfulfilled";
58
+ continue;
59
+ } else {
60
+ return "unauthorized";
61
+ }
21
62
  }
22
- )._refs[key]
23
- ? item && fulfillsDepth(depth[0], item)
24
- : ((value as CoMap)._schema[ItemsSym] as RefEncoded<CoValue>)!
25
- .optional;
26
- });
63
+
64
+ const innerResult = fulfillsDepth(depth.$each, item);
65
+
66
+ if (innerResult === "unfulfilled") {
67
+ result = "unfulfilled";
68
+ } else if (
69
+ innerResult === "unauthorized" &&
70
+ !isOptionalField(value, ItemsSym)
71
+ ) {
72
+ return "unauthorized"; // If any item is unauthorized, the whole thing is unauthorized
73
+ }
74
+ } else if (!isOptionalField(value, ItemsSym)) {
75
+ return "unfulfilled";
76
+ }
77
+ }
78
+
79
+ return result;
27
80
  } else {
28
- for (const key of Object.keys(depth)) {
29
- const map = value as unknown as {
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
- [key: string]: any;
32
- };
81
+ let result: FulfillsDepthResult = "fulfilled";
33
82
 
83
+ for (const key of Object.keys(depth)) {
34
84
  if (map._raw.get(key) === undefined) {
35
85
  if (!map._schema?.[key]) {
86
+ // Field not defined in schema
36
87
  if (map._schema?.[ItemsSym]) {
37
88
  // CoMap.Record
38
- if (map._schema[ItemsSym].optional) {
89
+ if (isOptionalField(map, ItemsSym)) {
39
90
  continue;
40
91
  } else {
92
+ // All fields are required, so the returned type is not optional and we must comply
41
93
  throw new Error(
42
94
  `The ref ${key} requested on ${map.constructor.name} is missing`,
43
95
  );
44
96
  }
45
97
  } else {
98
+ // Field not defined in CoMap schema
46
99
  throw new Error(
47
100
  `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`,
48
101
  );
49
102
  }
50
- } else if (map._schema[key].optional) {
103
+ } else if (isOptionalField(map, key)) {
51
104
  continue;
52
105
  } else {
106
+ // Field is required but has never been set
53
107
  throw new Error(
54
108
  `The ref ${key} on ${map.constructor.name} is required but missing`,
55
109
  );
56
110
  }
57
- }
111
+ } else {
112
+ const item = (value as Record<string, any>)[key];
58
113
 
59
- if (!map[key]) {
60
- return false;
61
- }
62
- if (!fulfillsDepth(depth[key], map[key])) {
63
- return false;
114
+ if (!item) {
115
+ if (hasReadAccess(map, key)) {
116
+ result = "unfulfilled";
117
+ continue;
118
+ } else {
119
+ return "unauthorized";
120
+ }
121
+ }
122
+
123
+ const innerResult = fulfillsDepth(depth[key], item);
124
+
125
+ if (innerResult === "unfulfilled") {
126
+ result = "unfulfilled";
127
+ } else if (
128
+ innerResult === "unauthorized" &&
129
+ !isOptionalField(value, key)
130
+ ) {
131
+ return "unauthorized"; // If any item is unauthorized, the whole thing is unauthorized
132
+ }
64
133
  }
65
134
  }
66
- return true;
135
+
136
+ return result;
67
137
  }
68
138
  } else if (value._type === "CoList") {
69
- if (depth.length === 0) {
70
- return true;
71
- } else {
72
- const itemDepth = depth[0];
73
- return (value as CoList).every((item, i) =>
74
- (value as CoList)._refs[i]
75
- ? item && fulfillsDepth(itemDepth, item)
76
- : ((value as CoList)._schema[ItemsSym] as RefEncoded<CoValue>)
77
- .optional,
78
- );
139
+ if ("$each" in depth) {
140
+ let result: FulfillsDepthResult = "fulfilled";
141
+
142
+ for (const [key, item] of (value as CoList).entries()) {
143
+ if (hasRefValue(value, key)) {
144
+ if (!item) {
145
+ if (hasReadAccess(value, key)) {
146
+ result = "unfulfilled";
147
+ continue;
148
+ } else {
149
+ return "unauthorized";
150
+ }
151
+ }
152
+
153
+ const innerResult = fulfillsDepth(depth.$each, item);
154
+
155
+ if (innerResult === "unfulfilled") {
156
+ result = "unfulfilled";
157
+ } else if (
158
+ innerResult === "unauthorized" &&
159
+ !isOptionalField(value, ItemsSym)
160
+ ) {
161
+ return "unauthorized"; // If any item is unauthorized, the whole thing is unauthorized
162
+ }
163
+ } else if (!isOptionalField(value, ItemsSym)) {
164
+ return "unfulfilled";
165
+ }
166
+ }
167
+
168
+ return result;
79
169
  }
170
+
171
+ return "fulfilled";
80
172
  } else if (value._type === "CoStream") {
81
- if (depth.length === 0) {
82
- return true;
83
- } else {
84
- const itemDepth = depth[0];
85
- return Object.values((value as CoFeed).perSession).every((entry) =>
86
- entry.ref
87
- ? entry.value && fulfillsDepth(itemDepth, entry.value)
88
- : ((value as CoFeed)._schema[ItemsSym] as RefEncoded<CoValue>)
89
- .optional,
90
- );
173
+ if ("$each" in depth) {
174
+ let result: FulfillsDepthResult = "fulfilled";
175
+
176
+ for (const item of Object.values((value as CoFeed).perSession)) {
177
+ if (item.ref) {
178
+ if (!item.value) {
179
+ if (item.ref.hasReadAccess()) {
180
+ result = "unfulfilled";
181
+ continue;
182
+ } else {
183
+ return "unauthorized";
184
+ }
185
+ }
186
+
187
+ const innerResult = fulfillsDepth(depth.$each, item.value);
188
+
189
+ if (innerResult === "unfulfilled") {
190
+ result = "unfulfilled";
191
+ } else if (
192
+ innerResult === "unauthorized" &&
193
+ !isOptionalField(value, ItemsSym)
194
+ ) {
195
+ return "unauthorized"; // If any item is unauthorized, the whole thing is unauthorized
196
+ }
197
+ } else if (!isOptionalField(value, ItemsSym)) {
198
+ return "unfulfilled";
199
+ }
200
+ }
201
+
202
+ return result;
91
203
  }
204
+
205
+ return "fulfilled";
92
206
  } else if (
93
207
  value._type === "BinaryCoStream" ||
94
208
  value._type === "CoPlainText"
95
209
  ) {
96
- return true;
210
+ return "fulfilled";
97
211
  } else {
98
212
  console.error(value);
99
213
  throw new Error("Unexpected value type: " + value._type);
@@ -101,101 +215,119 @@ export function fulfillsDepth(depth: any, value: CoValue): boolean {
101
215
  }
102
216
 
103
217
  type UnCoNotNull<T> = UnCo<Exclude<T, null>>;
104
- type Clean<T> = UnCo<NonNullable<T>>;
218
+ export type Clean<T> = UnCo<NonNullable<T>>;
105
219
 
106
- export type DepthsIn<
220
+ export type RefsToResolve<
107
221
  V,
108
- DepthLimit extends number = 5,
222
+ DepthLimit extends number = 10,
109
223
  CurrentDepth extends number[] = [],
110
224
  > =
225
+ | boolean
111
226
  | (DepthLimit extends CurrentDepth["length"]
112
227
  ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
228
  any
114
229
  : // Basically V extends CoList - but if we used that we'd introduce circularity into the definition of CoList itself
115
230
  V extends Array<infer Item>
116
231
  ?
117
- | [DepthsIn<UnCoNotNull<Item>, DepthLimit, [0, ...CurrentDepth]>]
118
- | never[]
232
+ | {
233
+ $each: RefsToResolve<
234
+ UnCoNotNull<Item>,
235
+ DepthLimit,
236
+ [0, ...CurrentDepth]
237
+ >;
238
+ }
239
+ | boolean
119
240
  : // Basically V extends CoMap | Group | Account - but if we used that we'd introduce circularity into the definition of CoMap itself
120
241
  V extends { _type: "CoMap" | "Group" | "Account" }
121
242
  ?
122
243
  | {
123
244
  [Key in CoKeys<V> as Clean<V[Key]> extends CoValue
124
245
  ? Key
125
- : never]?: DepthsIn<
246
+ : never]?: RefsToResolve<
126
247
  Clean<V[Key]>,
127
248
  DepthLimit,
128
249
  [0, ...CurrentDepth]
129
250
  >;
130
251
  }
131
252
  | (ItemsSym extends keyof V
132
- ? [
133
- DepthsIn<
253
+ ? {
254
+ $each: RefsToResolve<
134
255
  Clean<V[ItemsSym]>,
135
256
  DepthLimit,
136
257
  [0, ...CurrentDepth]
137
- >,
138
- ]
258
+ >;
259
+ }
139
260
  : never)
140
- | never[]
261
+ | boolean
141
262
  : V extends {
142
263
  _type: "CoStream";
143
264
  byMe: CoFeedEntry<infer Item> | undefined;
144
265
  }
145
266
  ?
146
- | [
147
- DepthsIn<
267
+ | {
268
+ $each: RefsToResolve<
148
269
  UnCoNotNull<Item>,
149
270
  DepthLimit,
150
271
  [0, ...CurrentDepth]
151
- >,
152
- ]
153
- | never[]
154
- : never[])
155
- | never[];
272
+ >;
273
+ }
274
+ | boolean
275
+ : boolean);
276
+
277
+ export type RefsToResolveStrict<T, V> = V extends RefsToResolve<T>
278
+ ? RefsToResolve<T>
279
+ : V;
280
+
281
+ export type Resolved<T, R extends RefsToResolve<T> | undefined> = DeeplyLoaded<
282
+ T,
283
+ R,
284
+ 10,
285
+ []
286
+ >;
156
287
 
157
288
  export type DeeplyLoaded<
158
289
  V,
159
290
  Depth,
160
- DepthLimit extends number = 5,
291
+ DepthLimit extends number = 10,
161
292
  CurrentDepth extends number[] = [],
162
293
  > = DepthLimit extends CurrentDepth["length"]
163
294
  ? V
164
- : // Basically V extends CoList - but if we used that we'd introduce circularity into the definition of CoList itself
165
- [V] extends [Array<infer Item>]
166
- ? Depth extends never[] // []
167
- ? V
168
- : UnCoNotNull<Item> extends CoValue
169
- ? Depth extends Array<infer ItemDepth> // [item-depth]
170
- ? (UnCoNotNull<Item> &
295
+ : Depth extends boolean | undefined // Checking against boolean instead of true because the inference from RefsToResolveStrict transforms true into boolean
296
+ ? V
297
+ : // Basically V extends CoList - but if we used that we'd introduce circularity into the definition of CoList itself
298
+ [V] extends [Array<infer Item>]
299
+ ? UnCoNotNull<Item> extends CoValue
300
+ ? Depth extends { $each: infer ItemDepth }
301
+ ? // Deeply loaded CoList
302
+ (UnCoNotNull<Item> &
171
303
  DeeplyLoaded<
172
304
  UnCoNotNull<Item>,
173
305
  ItemDepth,
174
306
  DepthLimit,
175
307
  [0, ...CurrentDepth]
176
308
  >)[] &
177
- V
309
+ V // the CoList base type needs to be intersected after so that built-in methods return the correct narrowed array type
178
310
  : never
179
311
  : V
180
- : // Basically V extends CoMap | Group | Account - but if we used that we'd introduce circularity into the definition of CoMap itself
181
- [V] extends [{ _type: "CoMap" | "Group" | "Account" }]
182
- ? Depth extends never[]
183
- ? V
184
- : Depth extends Array<infer ItemDepth>
185
- ? ItemsSym extends keyof V
186
- ? V & {
312
+ : // Basically V extends CoMap | Group | Account - but if we used that we'd introduce circularity into the definition of CoMap itself
313
+ [V] extends [{ _type: "CoMap" | "Group" | "Account" }]
314
+ ? ItemsSym extends keyof V
315
+ ? Depth extends { $each: infer ItemDepth }
316
+ ? // Deeply loaded Record-like CoMap
317
+ {
187
318
  [key: string]: DeeplyLoaded<
188
319
  Clean<V[ItemsSym]>,
189
320
  ItemDepth,
190
321
  DepthLimit,
191
322
  [0, ...CurrentDepth]
192
323
  >;
193
- }
324
+ } & V // same reason as in CoList
194
325
  : never
195
- : keyof Depth extends never
326
+ : keyof Depth extends never // Depth = {}
196
327
  ? V
197
- : {
198
- [Key in keyof Depth]-?: Key extends CoKeys<V>
328
+ : // Deeply loaded CoMap
329
+ {
330
+ -readonly [Key in keyof Depth]-?: Key extends CoKeys<V>
199
331
  ? Clean<V[Key]> extends CoValue
200
332
  ?
201
333
  | DeeplyLoaded<
@@ -207,32 +339,31 @@ export type DeeplyLoaded<
207
339
  | (undefined extends V[Key] ? undefined : never)
208
340
  : never
209
341
  : never;
210
- } & V
211
- : [V] extends [
342
+ } & V // same reason as in CoList
343
+ : [V] extends [
344
+ {
345
+ _type: "CoStream";
346
+ byMe: CoFeedEntry<infer Item> | undefined;
347
+ },
348
+ ]
349
+ ? // Deeply loaded CoStream
212
350
  {
213
- _type: "CoStream";
214
- byMe: CoFeedEntry<infer Item> | undefined;
215
- },
216
- ]
217
- ? Depth extends never[]
218
- ? V
219
- : V & {
220
351
  byMe?: { value: UnCoNotNull<Item> };
221
352
  inCurrentSession?: { value: UnCoNotNull<Item> };
222
353
  perSession: {
223
354
  [key: SessionID]: { value: UnCoNotNull<Item> };
224
355
  };
225
- } & { [key: ID<Account>]: { value: UnCoNotNull<Item> } }
226
- : [V] extends [
227
- {
228
- _type: "BinaryCoStream";
229
- },
230
- ]
231
- ? V
356
+ } & { [key: ID<Account>]: { value: UnCoNotNull<Item> } } & V // same reason as in CoList
232
357
  : [V] extends [
233
358
  {
234
- _type: "CoPlainText";
359
+ _type: "BinaryCoStream";
235
360
  },
236
361
  ]
237
362
  ? V
238
- : never;
363
+ : [V] extends [
364
+ {
365
+ _type: "CoPlainText";
366
+ },
367
+ ]
368
+ ? V
369
+ : never;
@@ -10,11 +10,14 @@ import { activeAccountContext } from "../implementation/activeAccountContext.js"
10
10
  import type {
11
11
  CoValue,
12
12
  CoValueClass,
13
- DeeplyLoaded,
14
- DepthsIn,
15
13
  ID,
16
14
  RefEncoded,
15
+ RefsToResolve,
16
+ RefsToResolveStrict,
17
+ Resolved,
17
18
  Schema,
19
+ SubscribeListenerOptions,
20
+ SubscribeRestArgs,
18
21
  } from "../internal.js";
19
22
  import {
20
23
  CoValueBase,
@@ -23,6 +26,7 @@ import {
23
26
  ensureCoValueLoaded,
24
27
  loadCoValueWithoutMe,
25
28
  parseGroupCreateOptions,
29
+ parseSubscribeRestArgs,
26
30
  subscribeToCoValueWithoutMe,
27
31
  subscribeToExistingCoValue,
28
32
  } from "../internal.js";
@@ -229,73 +233,59 @@ export class Group extends CoValueBase implements CoValue {
229
233
  }
230
234
 
231
235
  /** @category Subscription & Loading */
232
- static load<C extends Group, Depth>(
233
- this: CoValueClass<C>,
234
- id: ID<C>,
235
- depth: Depth & DepthsIn<C>,
236
- ): Promise<DeeplyLoaded<C, Depth> | undefined>;
237
- static load<C extends Group, Depth>(
238
- this: CoValueClass<C>,
239
- id: ID<C>,
240
- as: Account,
241
- depth: Depth & DepthsIn<C>,
242
- ): Promise<DeeplyLoaded<C, Depth> | undefined>;
243
- static load<C extends Group, Depth>(
244
- this: CoValueClass<C>,
245
- id: ID<C>,
246
- asOrDepth: Account | (Depth & DepthsIn<C>),
247
- depth?: Depth & DepthsIn<C>,
248
- ): Promise<DeeplyLoaded<C, Depth> | undefined> {
249
- return loadCoValueWithoutMe(this, id, asOrDepth, depth);
236
+ static load<G extends Group, const R extends RefsToResolve<G>>(
237
+ this: CoValueClass<G>,
238
+ id: ID<G>,
239
+ options?: { resolve?: RefsToResolveStrict<G, R>; loadAs?: Account },
240
+ ): Promise<Resolved<G, R> | null> {
241
+ return loadCoValueWithoutMe(this, id, options);
250
242
  }
251
243
 
252
244
  /** @category Subscription & Loading */
253
- static subscribe<C extends Group, Depth>(
254
- this: CoValueClass<C>,
255
- id: ID<C>,
256
- depth: Depth & DepthsIn<C>,
257
- listener: (value: DeeplyLoaded<C, Depth>) => void,
245
+ static subscribe<G extends Group, const R extends RefsToResolve<G>>(
246
+ this: CoValueClass<G>,
247
+ id: ID<G>,
248
+ listener: (value: Resolved<G, R>, unsubscribe: () => void) => void,
258
249
  ): () => void;
259
- static subscribe<C extends Group, Depth>(
260
- this: CoValueClass<C>,
261
- id: ID<C>,
262
- as: Account,
263
- depth: Depth & DepthsIn<C>,
264
- listener: (value: DeeplyLoaded<C, Depth>) => void,
250
+ static subscribe<G extends Group, const R extends RefsToResolve<G>>(
251
+ this: CoValueClass<G>,
252
+ id: ID<G>,
253
+ options: SubscribeListenerOptions<G, R>,
254
+ listener: (value: Resolved<G, R>, unsubscribe: () => void) => void,
265
255
  ): () => void;
266
- static subscribe<C extends Group, Depth>(
267
- this: CoValueClass<C>,
268
- id: ID<C>,
269
- asOrDepth: Account | (Depth & DepthsIn<C>),
270
- depthOrListener:
271
- | (Depth & DepthsIn<C>)
272
- | ((value: DeeplyLoaded<C, Depth>) => void),
273
- listener?: (value: DeeplyLoaded<C, Depth>) => void,
256
+ static subscribe<G extends Group, const R extends RefsToResolve<G>>(
257
+ this: CoValueClass<G>,
258
+ id: ID<G>,
259
+ ...args: SubscribeRestArgs<G, R>
274
260
  ): () => void {
275
- return subscribeToCoValueWithoutMe<C, Depth>(
276
- this,
277
- id,
278
- asOrDepth,
279
- depthOrListener,
280
- listener,
281
- );
261
+ const { options, listener } = parseSubscribeRestArgs(args);
262
+ return subscribeToCoValueWithoutMe<G, R>(this, id, options, listener);
282
263
  }
283
264
 
284
265
  /** @category Subscription & Loading */
285
- ensureLoaded<G extends Group, Depth>(
266
+ ensureLoaded<G extends Group, const R extends RefsToResolve<G>>(
286
267
  this: G,
287
- depth: Depth & DepthsIn<G>,
288
- ): Promise<DeeplyLoaded<G, Depth>> {
289
- return ensureCoValueLoaded(this, depth);
268
+ options?: { resolve?: RefsToResolveStrict<G, R> },
269
+ ): Promise<Resolved<G, R>> {
270
+ return ensureCoValueLoaded(this, options);
290
271
  }
291
272
 
292
273
  /** @category Subscription & Loading */
293
- subscribe<G extends Group, Depth>(
274
+ subscribe<G extends Group, const R extends RefsToResolve<G>>(
275
+ this: G,
276
+ listener: (value: Resolved<G, R>, unsubscribe: () => void) => void,
277
+ ): () => void;
278
+ subscribe<G extends Group, const R extends RefsToResolve<G>>(
279
+ this: G,
280
+ options: { resolve?: RefsToResolveStrict<G, R> },
281
+ listener: (value: Resolved<G, R>, unsubscribe: () => void) => void,
282
+ ): () => void;
283
+ subscribe<G extends Group, const R extends RefsToResolve<G>>(
294
284
  this: G,
295
- depth: Depth & DepthsIn<G>,
296
- listener: (value: DeeplyLoaded<G, Depth>) => void,
285
+ ...args: SubscribeRestArgs<G, R>
297
286
  ): () => void {
298
- return subscribeToExistingCoValue(this, depth, listener);
287
+ const { options, listener } = parseSubscribeRestArgs(args);
288
+ return subscribeToExistingCoValue(this, options, listener);
299
289
  }
300
290
 
301
291
  /**
@@ -167,12 +167,9 @@ export class Inbox {
167
167
  );
168
168
  }
169
169
 
170
- return loadCoValue(
171
- Schema,
172
- message.get("payload") as ID<I>,
173
- account,
174
- [],
175
- );
170
+ return loadCoValue(Schema, message.get("payload") as ID<I>, {
171
+ loadAs: account,
172
+ });
176
173
  })
177
174
  .then((value) => {
178
175
  if (!value) {