jazz-tools 0.8.15 → 0.8.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. package/CHANGELOG.md +283 -269
  2. package/dist/native/coValues/account.js +3 -6
  3. package/dist/native/coValues/account.js.map +1 -1
  4. package/dist/native/coValues/coList.js +3 -7
  5. package/dist/native/coValues/coList.js.map +1 -1
  6. package/dist/native/coValues/coMap.js +8 -14
  7. package/dist/native/coValues/coMap.js.map +1 -1
  8. package/dist/native/coValues/coStream.js +7 -12
  9. package/dist/native/coValues/coStream.js.map +1 -1
  10. package/dist/native/coValues/deepLoading.js +6 -3
  11. package/dist/native/coValues/deepLoading.js.map +1 -1
  12. package/dist/native/coValues/extensions/imageDef.js.map +1 -1
  13. package/dist/native/coValues/group.js +3 -6
  14. package/dist/native/coValues/group.js.map +1 -1
  15. package/dist/native/coValues/interfaces.js +4 -3
  16. package/dist/native/coValues/interfaces.js.map +1 -1
  17. package/dist/native/exports.js +3 -9
  18. package/dist/native/exports.js.map +1 -1
  19. package/dist/native/implementation/createContext.js +1 -2
  20. package/dist/native/implementation/createContext.js.map +1 -1
  21. package/dist/native/implementation/devtoolsFormatters.js +5 -25
  22. package/dist/native/implementation/devtoolsFormatters.js.map +1 -1
  23. package/dist/native/implementation/refs.js +1 -2
  24. package/dist/native/implementation/refs.js.map +1 -1
  25. package/dist/native/implementation/schema.js +1 -1
  26. package/dist/native/implementation/schema.js.map +1 -1
  27. package/dist/native/implementation/subscriptionScope.js +2 -4
  28. package/dist/native/implementation/subscriptionScope.js.map +1 -1
  29. package/dist/native/index.native.js +1 -1
  30. package/dist/native/index.native.js.map +1 -1
  31. package/dist/native/lib/cache.js.map +1 -1
  32. package/dist/native/lib/cache.test.js +1 -1
  33. package/dist/native/lib/cache.test.js.map +1 -1
  34. package/dist/web/coValues/account.js +3 -6
  35. package/dist/web/coValues/account.js.map +1 -1
  36. package/dist/web/coValues/coList.js +3 -7
  37. package/dist/web/coValues/coList.js.map +1 -1
  38. package/dist/web/coValues/coMap.js +8 -14
  39. package/dist/web/coValues/coMap.js.map +1 -1
  40. package/dist/web/coValues/coStream.js +7 -12
  41. package/dist/web/coValues/coStream.js.map +1 -1
  42. package/dist/web/coValues/deepLoading.js +6 -3
  43. package/dist/web/coValues/deepLoading.js.map +1 -1
  44. package/dist/web/coValues/extensions/imageDef.js.map +1 -1
  45. package/dist/web/coValues/group.js +3 -6
  46. package/dist/web/coValues/group.js.map +1 -1
  47. package/dist/web/coValues/interfaces.js +4 -3
  48. package/dist/web/coValues/interfaces.js.map +1 -1
  49. package/dist/web/exports.js +3 -9
  50. package/dist/web/exports.js.map +1 -1
  51. package/dist/web/implementation/createContext.js +1 -2
  52. package/dist/web/implementation/createContext.js.map +1 -1
  53. package/dist/web/implementation/devtoolsFormatters.js +5 -25
  54. package/dist/web/implementation/devtoolsFormatters.js.map +1 -1
  55. package/dist/web/implementation/refs.js +1 -2
  56. package/dist/web/implementation/refs.js.map +1 -1
  57. package/dist/web/implementation/schema.js +1 -1
  58. package/dist/web/implementation/schema.js.map +1 -1
  59. package/dist/web/implementation/subscriptionScope.js +2 -4
  60. package/dist/web/implementation/subscriptionScope.js.map +1 -1
  61. package/dist/web/lib/cache.js.map +1 -1
  62. package/dist/web/lib/cache.test.js +1 -1
  63. package/dist/web/lib/cache.test.js.map +1 -1
  64. package/package.json +5 -9
  65. package/src/coValues/account.ts +330 -339
  66. package/src/coValues/coList.ts +474 -495
  67. package/src/coValues/coMap.ts +584 -604
  68. package/src/coValues/coStream.ts +624 -650
  69. package/src/coValues/deepLoading.ts +184 -200
  70. package/src/coValues/extensions/imageDef.ts +44 -44
  71. package/src/coValues/group.ts +196 -210
  72. package/src/coValues/interfaces.ts +197 -199
  73. package/src/exports.ts +38 -26
  74. package/src/implementation/createContext.ts +206 -213
  75. package/src/implementation/devtoolsFormatters.ts +80 -100
  76. package/src/implementation/refs.ts +127 -139
  77. package/src/implementation/schema.ts +124 -128
  78. package/src/implementation/subscriptionScope.ts +111 -121
  79. package/src/index.native.ts +3 -3
  80. package/src/lib/cache.test.ts +48 -48
  81. package/src/lib/cache.ts +9 -9
  82. package/src/tests/coList.test.ts +264 -283
  83. package/src/tests/coMap.test.ts +741 -761
  84. package/src/tests/coStream.test.ts +405 -438
  85. package/src/tests/deepLoading.test.ts +251 -256
  86. package/src/tests/groupsAndAccounts.test.ts +70 -74
  87. package/src/tests/schema.test.ts +198 -198
  88. package/src/tests/subscribe.test.ts +312 -299
  89. package/tsconfig.json +2 -4
  90. package/tsconfig.native.json +4 -10
  91. package/tsconfig.web.json +4 -10
  92. package/.eslintrc.cjs +0 -24
  93. package/.prettierrc.js +0 -9
@@ -1,700 +1,674 @@
1
1
  /* eslint-disable @typescript-eslint/ban-ts-comment */
2
2
  import type {
3
- RawAccountID,
4
- AgentID,
5
- BinaryStreamInfo,
6
- CojsonInternalTypes,
7
- JsonValue,
8
- RawBinaryCoStream,
9
- RawCoStream,
10
- SessionID,
3
+ AgentID,
4
+ BinaryStreamInfo,
5
+ CojsonInternalTypes,
6
+ JsonValue,
7
+ RawAccountID,
8
+ RawBinaryCoStream,
9
+ RawCoStream,
10
+ SessionID,
11
11
  } from "cojson";
12
12
  import { MAX_RECOMMENDED_TX_SIZE, cojsonInternals } from "cojson";
13
13
  import type {
14
- CoValue,
15
- Schema,
16
- SchemaFor,
17
- Group,
18
- ID,
19
- IfCo,
20
- UnCo,
21
- CoValueClass,
22
- DeeplyLoaded,
23
- DepthsIn,
24
- AnonymousJazzAgent,
14
+ AnonymousJazzAgent,
15
+ CoValue,
16
+ CoValueClass,
17
+ DeeplyLoaded,
18
+ DepthsIn,
19
+ Group,
20
+ ID,
21
+ IfCo,
22
+ Schema,
23
+ SchemaFor,
24
+ UnCo,
25
25
  } from "../internal.js";
26
26
  import {
27
- ItemsSym,
28
- Account,
29
- CoValueBase,
30
- Ref,
31
- inspect,
32
- co,
33
- SchemaInit,
34
- isRefEncoded,
35
- loadCoValue,
36
- subscribeToCoValue,
37
- ensureCoValueLoaded,
38
- subscribeToExistingCoValue,
27
+ Account,
28
+ CoValueBase,
29
+ ItemsSym,
30
+ Ref,
31
+ SchemaInit,
32
+ co,
33
+ ensureCoValueLoaded,
34
+ inspect,
35
+ isRefEncoded,
36
+ loadCoValue,
37
+ subscribeToCoValue,
38
+ subscribeToExistingCoValue,
39
39
  } from "../internal.js";
40
40
 
41
41
  export type CoStreamEntry<Item> = SingleCoStreamEntry<Item> & {
42
- all: IterableIterator<SingleCoStreamEntry<Item>>;
42
+ all: IterableIterator<SingleCoStreamEntry<Item>>;
43
43
  };
44
44
 
45
45
  export type SingleCoStreamEntry<Item> = {
46
- value: NonNullable<Item> extends CoValue ? NonNullable<Item> | null : Item;
47
- ref: NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never;
48
- by?: Account | null;
49
- madeAt: Date;
50
- tx: CojsonInternalTypes.TransactionID;
46
+ value: NonNullable<Item> extends CoValue ? NonNullable<Item> | null : Item;
47
+ ref: NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never;
48
+ by?: Account | null;
49
+ madeAt: Date;
50
+ tx: CojsonInternalTypes.TransactionID;
51
51
  };
52
52
 
53
53
  /** @category CoValues */
54
54
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
55
  export class CoStream<Item = any> extends CoValueBase implements CoValue {
56
- static Of<Item>(item: IfCo<Item, Item>): typeof CoStream<Item> {
57
- return class CoStreamOf extends CoStream<Item> {
58
- [co.items] = item;
59
- };
60
- }
61
-
62
- declare id: ID<this>;
63
- declare _type: "CoStream";
64
- static {
65
- this.prototype._type = "CoStream";
66
- }
67
- declare _raw: RawCoStream;
68
-
69
- /** @internal This is only a marker type and doesn't exist at runtime */
70
- [ItemsSym]!: Item;
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- static _schema: any;
73
- get _schema(): {
74
- [ItemsSym]: SchemaFor<Item>;
75
- } {
76
- return (this.constructor as typeof CoStream)._schema;
77
- }
78
-
79
- [key: ID<Account>]: CoStreamEntry<Item>;
80
-
81
- get byMe(): CoStreamEntry<Item> | undefined {
82
- if (this._loadedAs._type === "Account") {
83
- return this[this._loadedAs.id];
84
- } else {
85
- return undefined;
86
- }
87
- }
88
- perSession!: {
89
- [key: SessionID]: CoStreamEntry<Item>;
56
+ static Of<Item>(item: IfCo<Item, Item>): typeof CoStream<Item> {
57
+ return class CoStreamOf extends CoStream<Item> {
58
+ [co.items] = item;
90
59
  };
91
- get inCurrentSession(): CoStreamEntry<Item> | undefined {
92
- if (this._loadedAs._type === "Account") {
93
- return this.perSession[this._loadedAs.sessionID!];
94
- } else {
95
- return undefined;
96
- }
97
- }
98
-
99
- constructor(
100
- options:
101
- | { init: Item[]; owner: Account | Group }
102
- | { fromRaw: RawCoStream },
103
- ) {
104
- super();
105
-
106
- if (options && "fromRaw" in options) {
107
- Object.defineProperties(this, {
108
- id: {
109
- value: options.fromRaw.id,
110
- enumerable: false,
111
- },
112
- _raw: { value: options.fromRaw, enumerable: false },
113
- });
114
- }
115
-
116
- return new Proxy(this, CoStreamProxyHandler as ProxyHandler<this>);
117
- }
118
-
119
- static create<S extends CoStream>(
120
- this: CoValueClass<S>,
121
- init: S extends CoStream<infer Item> ? UnCo<Item>[] : never,
122
- options: { owner: Account | Group },
123
- ) {
124
- const instance = new this({ init, owner: options.owner });
125
- const raw = options.owner._raw.createStream();
126
-
127
- Object.defineProperties(instance, {
128
- id: {
129
- value: raw.id,
130
- enumerable: false,
131
- },
132
- _raw: { value: raw, enumerable: false },
133
- });
134
-
135
- if (init) {
136
- instance.push(...init);
137
- }
138
- return instance;
139
- }
140
-
141
- push(...items: Item[]) {
142
- for (const item of items) {
143
- this.pushItem(item);
144
- }
145
- }
146
-
147
- private pushItem(item: Item) {
148
- const itemDescriptor = this._schema[ItemsSym] as Schema;
149
-
150
- if (itemDescriptor === "json") {
151
- this._raw.push(item as JsonValue);
152
- } else if ("encoded" in itemDescriptor) {
153
- this._raw.push(itemDescriptor.encoded.encode(item));
154
- } else if (isRefEncoded(itemDescriptor)) {
155
- this._raw.push((item as unknown as CoValue).id);
156
- }
157
- }
158
-
159
- toJSON(): {
160
- id: string;
161
- _type: "CoStream";
162
- [key: string]: unknown;
163
- in: { [key: string]: unknown };
164
- } {
165
- const itemDescriptor = this._schema[ItemsSym] as Schema;
166
- const mapper =
167
- itemDescriptor === "json"
168
- ? (v: unknown) => v
169
- : "encoded" in itemDescriptor
170
- ? itemDescriptor.encoded.encode
171
- : (v: unknown) => v && (v as CoValue).id;
172
-
173
- return {
174
- id: this.id,
175
- _type: this._type,
176
- ...Object.fromEntries(
177
- Object.entries(this).map(([account, entry]) => [
178
- account,
179
- mapper(entry.value),
180
- ]),
181
- ),
182
- in: Object.fromEntries(
183
- Object.entries(this.perSession).map(([session, entry]) => [
184
- session,
185
- mapper(entry.value),
186
- ]),
187
- ),
188
- };
189
- }
190
-
191
- [inspect](): {
192
- id: string;
193
- _type: "CoStream";
194
- [key: string]: unknown;
195
- in: { [key: string]: unknown };
196
- } {
197
- return this.toJSON();
198
- }
199
-
200
- static schema<V extends CoStream>(
201
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
- this: { new (...args: any): V } & typeof CoStream,
203
- def: { [ItemsSym]: V["_schema"][ItemsSym] },
204
- ) {
205
- this._schema ||= {};
206
- Object.assign(this._schema, def);
207
- }
208
-
209
- /** @category Subscription & Loading */
210
- static load<S extends CoStream, Depth>(
211
- this: CoValueClass<S>,
212
- id: ID<S>,
213
- as: Account,
214
- depth: Depth & DepthsIn<S>,
215
- ): Promise<DeeplyLoaded<S, Depth> | undefined> {
216
- return loadCoValue(this, id, as, depth);
217
- }
218
-
219
- /** @category Subscription & Loading */
220
- static subscribe<S extends CoStream, Depth>(
221
- this: CoValueClass<S>,
222
- id: ID<S>,
223
- as: Account,
224
- depth: Depth & DepthsIn<S>,
225
- listener: (value: DeeplyLoaded<S, Depth>) => void,
226
- ): () => void {
227
- return subscribeToCoValue<S, Depth>(this, id, as, depth, listener);
228
- }
229
-
230
- /** @category Subscription & Loading */
231
- ensureLoaded<S extends CoStream, Depth>(
232
- this: S,
233
- depth: Depth & DepthsIn<S>,
234
- ): Promise<DeeplyLoaded<S, Depth> | undefined> {
235
- return ensureCoValueLoaded(this, depth);
236
- }
60
+ }
61
+
62
+ declare id: ID<this>;
63
+ declare _type: "CoStream";
64
+ static {
65
+ this.prototype._type = "CoStream";
66
+ }
67
+ declare _raw: RawCoStream;
68
+
69
+ /** @internal This is only a marker type and doesn't exist at runtime */
70
+ [ItemsSym]!: Item;
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ static _schema: any;
73
+ get _schema(): {
74
+ [ItemsSym]: SchemaFor<Item>;
75
+ } {
76
+ return (this.constructor as typeof CoStream)._schema;
77
+ }
78
+
79
+ [key: ID<Account>]: CoStreamEntry<Item>;
80
+
81
+ get byMe(): CoStreamEntry<Item> | undefined {
82
+ if (this._loadedAs._type === "Account") {
83
+ return this[this._loadedAs.id];
84
+ } else {
85
+ return undefined;
86
+ }
87
+ }
88
+ perSession!: {
89
+ [key: SessionID]: CoStreamEntry<Item>;
90
+ };
91
+ get inCurrentSession(): CoStreamEntry<Item> | undefined {
92
+ if (this._loadedAs._type === "Account") {
93
+ return this.perSession[this._loadedAs.sessionID!];
94
+ } else {
95
+ return undefined;
96
+ }
97
+ }
98
+
99
+ constructor(
100
+ options:
101
+ | { init: Item[]; owner: Account | Group }
102
+ | { fromRaw: RawCoStream },
103
+ ) {
104
+ super();
105
+
106
+ if (options && "fromRaw" in options) {
107
+ Object.defineProperties(this, {
108
+ id: {
109
+ value: options.fromRaw.id,
110
+ enumerable: false,
111
+ },
112
+ _raw: { value: options.fromRaw, enumerable: false },
113
+ });
114
+ }
115
+
116
+ return new Proxy(this, CoStreamProxyHandler as ProxyHandler<this>);
117
+ }
118
+
119
+ static create<S extends CoStream>(
120
+ this: CoValueClass<S>,
121
+ init: S extends CoStream<infer Item> ? UnCo<Item>[] : never,
122
+ options: { owner: Account | Group },
123
+ ) {
124
+ const instance = new this({ init, owner: options.owner });
125
+ const raw = options.owner._raw.createStream();
126
+
127
+ Object.defineProperties(instance, {
128
+ id: {
129
+ value: raw.id,
130
+ enumerable: false,
131
+ },
132
+ _raw: { value: raw, enumerable: false },
133
+ });
134
+
135
+ if (init) {
136
+ instance.push(...init);
137
+ }
138
+ return instance;
139
+ }
140
+
141
+ push(...items: Item[]) {
142
+ for (const item of items) {
143
+ this.pushItem(item);
144
+ }
145
+ }
146
+
147
+ private pushItem(item: Item) {
148
+ const itemDescriptor = this._schema[ItemsSym] as Schema;
149
+
150
+ if (itemDescriptor === "json") {
151
+ this._raw.push(item as JsonValue);
152
+ } else if ("encoded" in itemDescriptor) {
153
+ this._raw.push(itemDescriptor.encoded.encode(item));
154
+ } else if (isRefEncoded(itemDescriptor)) {
155
+ this._raw.push((item as unknown as CoValue).id);
156
+ }
157
+ }
158
+
159
+ toJSON(): {
160
+ id: string;
161
+ _type: "CoStream";
162
+ [key: string]: unknown;
163
+ in: { [key: string]: unknown };
164
+ } {
165
+ const itemDescriptor = this._schema[ItemsSym] as Schema;
166
+ const mapper =
167
+ itemDescriptor === "json"
168
+ ? (v: unknown) => v
169
+ : "encoded" in itemDescriptor
170
+ ? itemDescriptor.encoded.encode
171
+ : (v: unknown) => v && (v as CoValue).id;
237
172
 
238
- /** @category Subscription & Loading */
239
- subscribe<S extends CoStream, Depth>(
240
- this: S,
241
- depth: Depth & DepthsIn<S>,
242
- listener: (value: DeeplyLoaded<S, Depth>) => void,
243
- ): () => void {
244
- return subscribeToExistingCoValue(this, depth, listener);
245
- }
173
+ return {
174
+ id: this.id,
175
+ _type: this._type,
176
+ ...Object.fromEntries(
177
+ Object.entries(this).map(([account, entry]) => [
178
+ account,
179
+ mapper(entry.value),
180
+ ]),
181
+ ),
182
+ in: Object.fromEntries(
183
+ Object.entries(this.perSession).map(([session, entry]) => [
184
+ session,
185
+ mapper(entry.value),
186
+ ]),
187
+ ),
188
+ };
189
+ }
190
+
191
+ [inspect](): {
192
+ id: string;
193
+ _type: "CoStream";
194
+ [key: string]: unknown;
195
+ in: { [key: string]: unknown };
196
+ } {
197
+ return this.toJSON();
198
+ }
199
+
200
+ static schema<V extends CoStream>(
201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
+ this: { new (...args: any): V } & typeof CoStream,
203
+ def: { [ItemsSym]: V["_schema"][ItemsSym] },
204
+ ) {
205
+ this._schema ||= {};
206
+ Object.assign(this._schema, def);
207
+ }
208
+
209
+ /** @category Subscription & Loading */
210
+ static load<S extends CoStream, Depth>(
211
+ this: CoValueClass<S>,
212
+ id: ID<S>,
213
+ as: Account,
214
+ depth: Depth & DepthsIn<S>,
215
+ ): Promise<DeeplyLoaded<S, Depth> | undefined> {
216
+ return loadCoValue(this, id, as, depth);
217
+ }
218
+
219
+ /** @category Subscription & Loading */
220
+ static subscribe<S extends CoStream, Depth>(
221
+ this: CoValueClass<S>,
222
+ id: ID<S>,
223
+ as: Account,
224
+ depth: Depth & DepthsIn<S>,
225
+ listener: (value: DeeplyLoaded<S, Depth>) => void,
226
+ ): () => void {
227
+ return subscribeToCoValue<S, Depth>(this, id, as, depth, listener);
228
+ }
229
+
230
+ /** @category Subscription & Loading */
231
+ ensureLoaded<S extends CoStream, Depth>(
232
+ this: S,
233
+ depth: Depth & DepthsIn<S>,
234
+ ): Promise<DeeplyLoaded<S, Depth> | undefined> {
235
+ return ensureCoValueLoaded(this, depth);
236
+ }
237
+
238
+ /** @category Subscription & Loading */
239
+ subscribe<S extends CoStream, Depth>(
240
+ this: S,
241
+ depth: Depth & DepthsIn<S>,
242
+ listener: (value: DeeplyLoaded<S, Depth>) => void,
243
+ ): () => void {
244
+ return subscribeToExistingCoValue(this, depth, listener);
245
+ }
246
246
  }
247
247
 
248
248
  function entryFromRawEntry<Item>(
249
- accessFrom: CoValue,
250
- rawEntry: {
251
- by: RawAccountID | AgentID;
252
- tx: CojsonInternalTypes.TransactionID;
253
- at: Date;
254
- value: JsonValue;
255
- },
256
- loadedAs: Account | AnonymousJazzAgent,
257
- accountID: ID<Account> | undefined,
258
- itemField: Schema,
249
+ accessFrom: CoValue,
250
+ rawEntry: {
251
+ by: RawAccountID | AgentID;
252
+ tx: CojsonInternalTypes.TransactionID;
253
+ at: Date;
254
+ value: JsonValue;
255
+ },
256
+ loadedAs: Account | AnonymousJazzAgent,
257
+ accountID: ID<Account> | undefined,
258
+ itemField: Schema,
259
259
  ): Omit<CoStreamEntry<Item>, "all"> {
260
- return {
261
- get value(): NonNullable<Item> extends CoValue
262
- ? (CoValue & Item) | null
263
- : Item {
264
- if (itemField === "json") {
265
- return rawEntry.value as NonNullable<Item> extends CoValue
266
- ? (CoValue & Item) | null
267
- : Item;
268
- } else if ("encoded" in itemField) {
269
- return itemField.encoded.decode(rawEntry.value);
270
- } else if (isRefEncoded(itemField)) {
271
- return this.ref?.accessFrom(
272
- accessFrom,
273
- rawEntry.by +
274
- rawEntry.tx.sessionID +
275
- rawEntry.tx.txIndex +
276
- ".value",
277
- ) as NonNullable<Item> extends CoValue
278
- ? (CoValue & Item) | null
279
- : Item;
280
- } else {
281
- throw new Error("Invalid item field schema");
282
- }
283
- },
284
- get ref(): NonNullable<Item> extends CoValue
285
- ? Ref<NonNullable<Item>>
286
- : never {
287
- if (itemField !== "json" && isRefEncoded(itemField)) {
288
- const rawId = rawEntry.value;
289
- return new Ref(
290
- rawId as unknown as ID<CoValue>,
291
- loadedAs,
292
- itemField,
293
- ) as NonNullable<Item> extends CoValue
294
- ? Ref<NonNullable<Item>>
295
- : never;
296
- } else {
297
- return undefined as never;
298
- }
299
- },
300
- get by() {
301
- return (
302
- accountID &&
303
- new Ref<Account>(
304
- accountID as unknown as ID<Account>,
305
- loadedAs,
306
- { ref: Account, optional: false },
307
- )?.accessFrom(
308
- accessFrom,
309
- rawEntry.by +
310
- rawEntry.tx.sessionID +
311
- rawEntry.tx.txIndex +
312
- ".by",
313
- )
314
- );
315
- },
316
- madeAt: rawEntry.at,
317
- tx: rawEntry.tx,
318
- };
260
+ return {
261
+ get value(): NonNullable<Item> extends CoValue
262
+ ? (CoValue & Item) | null
263
+ : Item {
264
+ if (itemField === "json") {
265
+ return rawEntry.value as NonNullable<Item> extends CoValue
266
+ ? (CoValue & Item) | null
267
+ : Item;
268
+ } else if ("encoded" in itemField) {
269
+ return itemField.encoded.decode(rawEntry.value);
270
+ } else if (isRefEncoded(itemField)) {
271
+ return this.ref?.accessFrom(
272
+ accessFrom,
273
+ rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".value",
274
+ ) as NonNullable<Item> extends CoValue ? (CoValue & Item) | null : Item;
275
+ } else {
276
+ throw new Error("Invalid item field schema");
277
+ }
278
+ },
279
+ get ref(): NonNullable<Item> extends CoValue
280
+ ? Ref<NonNullable<Item>>
281
+ : never {
282
+ if (itemField !== "json" && isRefEncoded(itemField)) {
283
+ const rawId = rawEntry.value;
284
+ return new Ref(
285
+ rawId as unknown as ID<CoValue>,
286
+ loadedAs,
287
+ itemField,
288
+ ) as NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never;
289
+ } else {
290
+ return undefined as never;
291
+ }
292
+ },
293
+ get by() {
294
+ return (
295
+ accountID &&
296
+ new Ref<Account>(accountID as unknown as ID<Account>, loadedAs, {
297
+ ref: Account,
298
+ optional: false,
299
+ })?.accessFrom(
300
+ accessFrom,
301
+ rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".by",
302
+ )
303
+ );
304
+ },
305
+ madeAt: rawEntry.at,
306
+ tx: rawEntry.tx,
307
+ };
319
308
  }
320
309
 
321
310
  export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
322
- get(target, key, receiver) {
323
- if (typeof key === "string" && key.startsWith("co_")) {
324
- const rawEntry = target._raw.lastItemBy(key as RawAccountID);
325
-
326
- if (!rawEntry) return;
327
- const entry = entryFromRawEntry(
311
+ get(target, key, receiver) {
312
+ if (typeof key === "string" && key.startsWith("co_")) {
313
+ const rawEntry = target._raw.lastItemBy(key as RawAccountID);
314
+
315
+ if (!rawEntry) return;
316
+ const entry = entryFromRawEntry(
317
+ receiver,
318
+ rawEntry,
319
+ target._loadedAs,
320
+ key as unknown as ID<Account>,
321
+ target._schema[ItemsSym],
322
+ );
323
+
324
+ Object.defineProperty(entry, "all", {
325
+ get: () => {
326
+ const allRawEntries = target._raw.itemsBy(key as RawAccountID);
327
+ return (function* () {
328
+ while (true) {
329
+ const rawEntry = allRawEntries.next();
330
+ if (rawEntry.done) return;
331
+ yield entryFromRawEntry(
328
332
  receiver,
329
- rawEntry,
333
+ rawEntry.value,
330
334
  target._loadedAs,
331
335
  key as unknown as ID<Account>,
332
336
  target._schema[ItemsSym],
333
- );
334
-
335
- Object.defineProperty(entry, "all", {
336
- get: () => {
337
- const allRawEntries = target._raw.itemsBy(
338
- key as RawAccountID,
339
- );
340
- return (function* () {
341
- while (true) {
342
- const rawEntry = allRawEntries.next();
343
- if (rawEntry.done) return;
344
- yield entryFromRawEntry(
345
- receiver,
346
- rawEntry.value,
347
- target._loadedAs,
348
- key as unknown as ID<Account>,
349
- target._schema[ItemsSym],
350
- );
351
- }
352
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
- })() satisfies IterableIterator<SingleCoStreamEntry<any>>;
354
- },
355
- });
356
-
357
- return entry;
358
- } else if (key === "perSession") {
359
- return new Proxy(
360
- {},
361
- CoStreamPerSessionProxyHandler(target, receiver),
362
- );
363
- } else {
364
- return Reflect.get(target, key, receiver);
365
- }
366
- },
367
- set(target, key, value, receiver) {
368
- if (
369
- key === ItemsSym &&
370
- typeof value === "object" &&
371
- SchemaInit in value
372
- ) {
373
- (target.constructor as typeof CoStream)._schema ||= {};
374
- (target.constructor as typeof CoStream)._schema[ItemsSym] =
375
- value[SchemaInit];
376
- return true;
377
- } else {
378
- return Reflect.set(target, key, value, receiver);
379
- }
380
- },
381
- defineProperty(target, key, descriptor) {
382
- if (
383
- descriptor.value &&
384
- key === ItemsSym &&
385
- typeof descriptor.value === "object" &&
386
- SchemaInit in descriptor.value
387
- ) {
388
- (target.constructor as typeof CoStream)._schema ||= {};
389
- (target.constructor as typeof CoStream)._schema[ItemsSym] =
390
- descriptor.value[SchemaInit];
391
- return true;
392
- } else {
393
- return Reflect.defineProperty(target, key, descriptor);
394
- }
395
- },
396
- ownKeys(target) {
397
- const keys = Reflect.ownKeys(target);
398
-
399
- for (const accountID of target._raw.accounts()) {
400
- keys.push(accountID);
401
- }
402
-
403
- return keys;
404
- },
405
- getOwnPropertyDescriptor(target, key) {
406
- if (typeof key === "string" && key.startsWith("co_")) {
407
- return {
408
- configurable: true,
409
- enumerable: true,
410
- writable: false,
411
- };
412
- } else {
413
- return Reflect.getOwnPropertyDescriptor(target, key);
414
- }
415
- },
337
+ );
338
+ }
339
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
340
+ })() satisfies IterableIterator<SingleCoStreamEntry<any>>;
341
+ },
342
+ });
343
+
344
+ return entry;
345
+ } else if (key === "perSession") {
346
+ return new Proxy({}, CoStreamPerSessionProxyHandler(target, receiver));
347
+ } else {
348
+ return Reflect.get(target, key, receiver);
349
+ }
350
+ },
351
+ set(target, key, value, receiver) {
352
+ if (key === ItemsSym && typeof value === "object" && SchemaInit in value) {
353
+ (target.constructor as typeof CoStream)._schema ||= {};
354
+ (target.constructor as typeof CoStream)._schema[ItemsSym] =
355
+ value[SchemaInit];
356
+ return true;
357
+ } else {
358
+ return Reflect.set(target, key, value, receiver);
359
+ }
360
+ },
361
+ defineProperty(target, key, descriptor) {
362
+ if (
363
+ descriptor.value &&
364
+ key === ItemsSym &&
365
+ typeof descriptor.value === "object" &&
366
+ SchemaInit in descriptor.value
367
+ ) {
368
+ (target.constructor as typeof CoStream)._schema ||= {};
369
+ (target.constructor as typeof CoStream)._schema[ItemsSym] =
370
+ descriptor.value[SchemaInit];
371
+ return true;
372
+ } else {
373
+ return Reflect.defineProperty(target, key, descriptor);
374
+ }
375
+ },
376
+ ownKeys(target) {
377
+ const keys = Reflect.ownKeys(target);
378
+
379
+ for (const accountID of target._raw.accounts()) {
380
+ keys.push(accountID);
381
+ }
382
+
383
+ return keys;
384
+ },
385
+ getOwnPropertyDescriptor(target, key) {
386
+ if (typeof key === "string" && key.startsWith("co_")) {
387
+ return {
388
+ configurable: true,
389
+ enumerable: true,
390
+ writable: false,
391
+ };
392
+ } else {
393
+ return Reflect.getOwnPropertyDescriptor(target, key);
394
+ }
395
+ },
416
396
  };
417
397
 
418
398
  const CoStreamPerSessionProxyHandler = (
419
- innerTarget: CoStream,
420
- accessFrom: CoStream,
399
+ innerTarget: CoStream,
400
+ accessFrom: CoStream,
421
401
  ): ProxyHandler<Record<string, never>> => ({
422
- get(_target, key, receiver) {
423
- if (typeof key === "string" && key.includes("session")) {
424
- const sessionID = key as SessionID;
425
- const rawEntry = innerTarget._raw.lastItemIn(sessionID);
426
-
427
- if (!rawEntry) return;
428
- const by = cojsonInternals.accountOrAgentIDfromSessionID(sessionID);
429
-
430
- const entry = entryFromRawEntry(
402
+ get(_target, key, receiver) {
403
+ if (typeof key === "string" && key.includes("session")) {
404
+ const sessionID = key as SessionID;
405
+ const rawEntry = innerTarget._raw.lastItemIn(sessionID);
406
+
407
+ if (!rawEntry) return;
408
+ const by = cojsonInternals.accountOrAgentIDfromSessionID(sessionID);
409
+
410
+ const entry = entryFromRawEntry(
411
+ accessFrom,
412
+ rawEntry,
413
+ innerTarget._loadedAs,
414
+ cojsonInternals.isAccountID(by)
415
+ ? (by as unknown as ID<Account>)
416
+ : undefined,
417
+ innerTarget._schema[ItemsSym],
418
+ );
419
+
420
+ Object.defineProperty(entry, "all", {
421
+ get: () => {
422
+ const allRawEntries = innerTarget._raw.itemsIn(sessionID);
423
+ return (function* () {
424
+ while (true) {
425
+ const rawEntry = allRawEntries.next();
426
+ if (rawEntry.done) return;
427
+ yield entryFromRawEntry(
431
428
  accessFrom,
432
- rawEntry,
429
+ rawEntry.value,
433
430
  innerTarget._loadedAs,
434
431
  cojsonInternals.isAccountID(by)
435
- ? (by as unknown as ID<Account>)
436
- : undefined,
432
+ ? (by as unknown as ID<Account>)
433
+ : undefined,
437
434
  innerTarget._schema[ItemsSym],
438
- );
439
-
440
- Object.defineProperty(entry, "all", {
441
- get: () => {
442
- const allRawEntries = innerTarget._raw.itemsIn(sessionID);
443
- return (function* () {
444
- while (true) {
445
- const rawEntry = allRawEntries.next();
446
- if (rawEntry.done) return;
447
- yield entryFromRawEntry(
448
- accessFrom,
449
- rawEntry.value,
450
- innerTarget._loadedAs,
451
- cojsonInternals.isAccountID(by)
452
- ? (by as unknown as ID<Account>)
453
- : undefined,
454
- innerTarget._schema[ItemsSym],
455
- );
456
- }
457
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
458
- })() satisfies IterableIterator<SingleCoStreamEntry<any>>;
459
- },
460
- });
461
-
462
- return entry;
463
- } else {
464
- return Reflect.get(innerTarget, key, receiver);
465
- }
466
- },
467
- ownKeys() {
468
- return innerTarget._raw.sessions();
469
- },
470
- getOwnPropertyDescriptor(target, key) {
471
- if (typeof key === "string" && key.startsWith("co_")) {
472
- return {
473
- configurable: true,
474
- enumerable: true,
475
- writable: false,
476
- };
477
- } else {
478
- return Reflect.getOwnPropertyDescriptor(target, key);
479
- }
480
- },
435
+ );
436
+ }
437
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
438
+ })() satisfies IterableIterator<SingleCoStreamEntry<any>>;
439
+ },
440
+ });
441
+
442
+ return entry;
443
+ } else {
444
+ return Reflect.get(innerTarget, key, receiver);
445
+ }
446
+ },
447
+ ownKeys() {
448
+ return innerTarget._raw.sessions();
449
+ },
450
+ getOwnPropertyDescriptor(target, key) {
451
+ if (typeof key === "string" && key.startsWith("co_")) {
452
+ return {
453
+ configurable: true,
454
+ enumerable: true,
455
+ writable: false,
456
+ };
457
+ } else {
458
+ return Reflect.getOwnPropertyDescriptor(target, key);
459
+ }
460
+ },
481
461
  });
482
462
 
483
463
  /** @category CoValues */
484
464
  export class BinaryCoStream extends CoValueBase implements CoValue {
485
- declare id: ID<this>;
486
- declare _type: "BinaryCoStream";
487
- declare _raw: RawBinaryCoStream;
488
-
489
- constructor(
490
- options:
491
- | {
492
- owner: Account | Group;
493
- }
494
- | {
495
- fromRaw: RawBinaryCoStream;
496
- },
497
- ) {
498
- super();
499
-
500
- let raw: RawBinaryCoStream;
501
-
502
- if ("fromRaw" in options) {
503
- raw = options.fromRaw;
504
- } else {
505
- const rawOwner = options.owner._raw;
506
- raw = rawOwner.createBinaryStream();
507
- }
508
-
509
- Object.defineProperties(this, {
510
- id: {
511
- value: raw.id,
512
- enumerable: false,
513
- },
514
- _type: { value: "BinaryCoStream", enumerable: false },
515
- _raw: { value: raw, enumerable: false },
516
- });
517
- }
518
-
519
- static create<S extends BinaryCoStream>(
520
- this: CoValueClass<S>,
521
- options: { owner: Account | Group },
522
- ) {
523
- return new this(options);
524
- }
525
-
526
- getChunks(options?: {
527
- allowUnfinished?: boolean;
528
- }):
529
- | (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
530
- | undefined {
531
- return this._raw.getBinaryChunks(options?.allowUnfinished);
532
- }
533
-
534
- isBinaryStreamEnded(): boolean {
535
- return this._raw.isBinaryStreamEnded();
536
- }
537
-
538
- start(options: BinaryStreamInfo): void {
539
- this._raw.startBinaryStream(options);
540
- }
541
-
542
- push(data: Uint8Array): void {
543
- this._raw.pushBinaryStreamChunk(data);
544
- }
545
-
546
- end(): void {
547
- this._raw.endBinaryStream();
548
- }
549
-
550
- toBlob(options?: { allowUnfinished?: boolean }): Blob | undefined {
551
- const chunks = this.getChunks({
552
- allowUnfinished: options?.allowUnfinished,
553
- });
554
-
555
- if (!chunks) {
556
- return undefined;
465
+ declare id: ID<this>;
466
+ declare _type: "BinaryCoStream";
467
+ declare _raw: RawBinaryCoStream;
468
+
469
+ constructor(
470
+ options:
471
+ | {
472
+ owner: Account | Group;
557
473
  }
558
-
559
- // @ts-ignore
560
- return new Blob(chunks.chunks, { type: chunks.mimeType });
561
- }
562
-
563
- static async loadAsBlob(
564
- id: ID<BinaryCoStream>,
565
- as: Account,
566
- options?: {
567
- allowUnfinished?: boolean;
474
+ | {
475
+ fromRaw: RawBinaryCoStream;
568
476
  },
569
- ): Promise<Blob | undefined> {
570
- let stream = await this.load(id, as, []);
571
-
572
- /**
573
- * If the user hasn't requested an incomplete blob and the
574
- * stream isn't complete wait for the stream download before progressing
575
- */
576
- if (!options?.allowUnfinished && !stream?.isBinaryStreamEnded()) {
577
- stream = await new Promise<BinaryCoStream>((resolve) => {
578
- const unsubscribe = subscribeToCoValue(
579
- this,
580
- id,
581
- as,
582
- [],
583
- (value) => {
584
- if (value.isBinaryStreamEnded()) {
585
- unsubscribe();
586
- resolve(value);
587
- }
588
- },
589
- );
590
- });
591
- }
592
-
593
- return stream?.toBlob({
594
- allowUnfinished: options?.allowUnfinished,
477
+ ) {
478
+ super();
479
+
480
+ let raw: RawBinaryCoStream;
481
+
482
+ if ("fromRaw" in options) {
483
+ raw = options.fromRaw;
484
+ } else {
485
+ const rawOwner = options.owner._raw;
486
+ raw = rawOwner.createBinaryStream();
487
+ }
488
+
489
+ Object.defineProperties(this, {
490
+ id: {
491
+ value: raw.id,
492
+ enumerable: false,
493
+ },
494
+ _type: { value: "BinaryCoStream", enumerable: false },
495
+ _raw: { value: raw, enumerable: false },
496
+ });
497
+ }
498
+
499
+ static create<S extends BinaryCoStream>(
500
+ this: CoValueClass<S>,
501
+ options: { owner: Account | Group },
502
+ ) {
503
+ return new this(options);
504
+ }
505
+
506
+ getChunks(options?: {
507
+ allowUnfinished?: boolean;
508
+ }):
509
+ | (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
510
+ | undefined {
511
+ return this._raw.getBinaryChunks(options?.allowUnfinished);
512
+ }
513
+
514
+ isBinaryStreamEnded(): boolean {
515
+ return this._raw.isBinaryStreamEnded();
516
+ }
517
+
518
+ start(options: BinaryStreamInfo): void {
519
+ this._raw.startBinaryStream(options);
520
+ }
521
+
522
+ push(data: Uint8Array): void {
523
+ this._raw.pushBinaryStreamChunk(data);
524
+ }
525
+
526
+ end(): void {
527
+ this._raw.endBinaryStream();
528
+ }
529
+
530
+ toBlob(options?: { allowUnfinished?: boolean }): Blob | undefined {
531
+ const chunks = this.getChunks({
532
+ allowUnfinished: options?.allowUnfinished,
533
+ });
534
+
535
+ if (!chunks) {
536
+ return undefined;
537
+ }
538
+
539
+ // @ts-ignore
540
+ return new Blob(chunks.chunks, { type: chunks.mimeType });
541
+ }
542
+
543
+ static async loadAsBlob(
544
+ id: ID<BinaryCoStream>,
545
+ as: Account,
546
+ options?: {
547
+ allowUnfinished?: boolean;
548
+ },
549
+ ): Promise<Blob | undefined> {
550
+ let stream = await this.load(id, as, []);
551
+
552
+ /**
553
+ * If the user hasn't requested an incomplete blob and the
554
+ * stream isn't complete wait for the stream download before progressing
555
+ */
556
+ if (!options?.allowUnfinished && !stream?.isBinaryStreamEnded()) {
557
+ stream = await new Promise<BinaryCoStream>((resolve) => {
558
+ const unsubscribe = subscribeToCoValue(this, id, as, [], (value) => {
559
+ if (value.isBinaryStreamEnded()) {
560
+ unsubscribe();
561
+ resolve(value);
562
+ }
595
563
  });
564
+ });
596
565
  }
597
566
 
598
- static async createFromBlob(
599
- blob: Blob | File,
600
- options: {
601
- owner: Group | Account;
602
- onProgress?: (progress: number) => void;
603
- },
604
- ): Promise<BinaryCoStream> {
605
- const stream = this.create({ owner: options.owner });
606
-
607
- const start = Date.now();
608
-
609
- const data = new Uint8Array(await blob.arrayBuffer());
610
- stream.start({
611
- mimeType: blob.type,
612
- totalSizeBytes: blob.size,
613
- fileName: blob instanceof File ? blob.name : undefined,
614
- });
615
- const chunkSize = MAX_RECOMMENDED_TX_SIZE;
616
-
617
- let lastProgressUpdate = Date.now();
618
-
619
- for (let idx = 0; idx < data.length; idx += chunkSize) {
620
- stream.push(data.slice(idx, idx + chunkSize));
621
-
622
- if (Date.now() - lastProgressUpdate > 100) {
623
- options.onProgress?.(idx / data.length);
624
- lastProgressUpdate = Date.now();
625
- }
567
+ return stream?.toBlob({
568
+ allowUnfinished: options?.allowUnfinished,
569
+ });
570
+ }
626
571
 
627
- await new Promise((resolve) => setTimeout(resolve, 0));
628
- }
629
- stream.end();
630
- const end = Date.now();
631
-
632
- console.debug(
633
- "Finished creating binary stream in",
634
- (end - start) / 1000,
635
- "s - Throughput in MB/s",
636
- (1000 * (blob.size / (end - start))) / (1024 * 1024),
637
- );
638
- options.onProgress?.(1);
639
-
640
- return stream;
641
- }
642
-
643
- toJSON(): {
644
- id: string;
645
- _type: "BinaryCoStream";
646
- mimeType?: string;
647
- totalSizeBytes?: number;
648
- fileName?: string;
649
- chunks?: Uint8Array[];
650
- finished?: boolean;
651
- } {
652
- return {
653
- id: this.id,
654
- _type: this._type,
655
- ...this.getChunks(),
656
- };
657
- }
658
-
659
- [inspect]() {
660
- return this.toJSON();
661
- }
662
-
663
- /** @category Subscription & Loading */
664
- static load<B extends BinaryCoStream, Depth>(
665
- this: CoValueClass<B>,
666
- id: ID<B>,
667
- as: Account,
668
- depth: Depth & DepthsIn<B>,
669
- ): Promise<DeeplyLoaded<B, Depth> | undefined> {
670
- return loadCoValue(this, id, as, depth);
671
- }
672
-
673
- /** @category Subscription & Loading */
674
- static subscribe<B extends BinaryCoStream, Depth>(
675
- this: CoValueClass<B>,
676
- id: ID<B>,
677
- as: Account,
678
- depth: Depth & DepthsIn<B>,
679
- listener: (value: DeeplyLoaded<B, Depth>) => void,
680
- ): () => void {
681
- return subscribeToCoValue<B, Depth>(this, id, as, depth, listener);
682
- }
683
-
684
- /** @category Subscription & Loading */
685
- ensureLoaded<B extends BinaryCoStream, Depth>(
686
- this: B,
687
- depth: Depth & DepthsIn<B>,
688
- ): Promise<DeeplyLoaded<B, Depth> | undefined> {
689
- return ensureCoValueLoaded(this, depth);
690
- }
691
-
692
- /** @category Subscription & Loading */
693
- subscribe<B extends BinaryCoStream, Depth>(
694
- this: B,
695
- depth: Depth & DepthsIn<B>,
696
- listener: (value: DeeplyLoaded<B, Depth>) => void,
697
- ): () => void {
698
- return subscribeToExistingCoValue(this, depth, listener);
699
- }
572
+ static async createFromBlob(
573
+ blob: Blob | File,
574
+ options: {
575
+ owner: Group | Account;
576
+ onProgress?: (progress: number) => void;
577
+ },
578
+ ): Promise<BinaryCoStream> {
579
+ const stream = this.create({ owner: options.owner });
580
+
581
+ const start = Date.now();
582
+
583
+ const data = new Uint8Array(await blob.arrayBuffer());
584
+ stream.start({
585
+ mimeType: blob.type,
586
+ totalSizeBytes: blob.size,
587
+ fileName: blob instanceof File ? blob.name : undefined,
588
+ });
589
+ const chunkSize = MAX_RECOMMENDED_TX_SIZE;
590
+
591
+ let lastProgressUpdate = Date.now();
592
+
593
+ for (let idx = 0; idx < data.length; idx += chunkSize) {
594
+ stream.push(data.slice(idx, idx + chunkSize));
595
+
596
+ if (Date.now() - lastProgressUpdate > 100) {
597
+ options.onProgress?.(idx / data.length);
598
+ lastProgressUpdate = Date.now();
599
+ }
600
+
601
+ await new Promise((resolve) => setTimeout(resolve, 0));
602
+ }
603
+ stream.end();
604
+ const end = Date.now();
605
+
606
+ console.debug(
607
+ "Finished creating binary stream in",
608
+ (end - start) / 1000,
609
+ "s - Throughput in MB/s",
610
+ (1000 * (blob.size / (end - start))) / (1024 * 1024),
611
+ );
612
+ options.onProgress?.(1);
613
+
614
+ return stream;
615
+ }
616
+
617
+ toJSON(): {
618
+ id: string;
619
+ _type: "BinaryCoStream";
620
+ mimeType?: string;
621
+ totalSizeBytes?: number;
622
+ fileName?: string;
623
+ chunks?: Uint8Array[];
624
+ finished?: boolean;
625
+ } {
626
+ return {
627
+ id: this.id,
628
+ _type: this._type,
629
+ ...this.getChunks(),
630
+ };
631
+ }
632
+
633
+ [inspect]() {
634
+ return this.toJSON();
635
+ }
636
+
637
+ /** @category Subscription & Loading */
638
+ static load<B extends BinaryCoStream, Depth>(
639
+ this: CoValueClass<B>,
640
+ id: ID<B>,
641
+ as: Account,
642
+ depth: Depth & DepthsIn<B>,
643
+ ): Promise<DeeplyLoaded<B, Depth> | undefined> {
644
+ return loadCoValue(this, id, as, depth);
645
+ }
646
+
647
+ /** @category Subscription & Loading */
648
+ static subscribe<B extends BinaryCoStream, Depth>(
649
+ this: CoValueClass<B>,
650
+ id: ID<B>,
651
+ as: Account,
652
+ depth: Depth & DepthsIn<B>,
653
+ listener: (value: DeeplyLoaded<B, Depth>) => void,
654
+ ): () => void {
655
+ return subscribeToCoValue<B, Depth>(this, id, as, depth, listener);
656
+ }
657
+
658
+ /** @category Subscription & Loading */
659
+ ensureLoaded<B extends BinaryCoStream, Depth>(
660
+ this: B,
661
+ depth: Depth & DepthsIn<B>,
662
+ ): Promise<DeeplyLoaded<B, Depth> | undefined> {
663
+ return ensureCoValueLoaded(this, depth);
664
+ }
665
+
666
+ /** @category Subscription & Loading */
667
+ subscribe<B extends BinaryCoStream, Depth>(
668
+ this: B,
669
+ depth: Depth & DepthsIn<B>,
670
+ listener: (value: DeeplyLoaded<B, Depth>) => void,
671
+ ): () => void {
672
+ return subscribeToExistingCoValue(this, depth, listener);
673
+ }
700
674
  }