cojson 0.2.2 → 0.2.3

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 (58) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/dist/account.d.ts +7 -7
  3. package/dist/account.js +2 -2
  4. package/dist/account.js.map +1 -1
  5. package/dist/coValue.d.ts +26 -23
  6. package/dist/coValue.js +14 -0
  7. package/dist/coValue.js.map +1 -1
  8. package/dist/coValueCore.d.ts +6 -6
  9. package/dist/coValueCore.js.map +1 -1
  10. package/dist/coValues/coList.d.ts +22 -22
  11. package/dist/coValues/coList.js +3 -2
  12. package/dist/coValues/coList.js.map +1 -1
  13. package/dist/coValues/coMap.d.ts +29 -35
  14. package/dist/coValues/coMap.js +17 -8
  15. package/dist/coValues/coMap.js.map +1 -1
  16. package/dist/coValues/coStream.d.ts +28 -27
  17. package/dist/coValues/coStream.js +15 -6
  18. package/dist/coValues/coStream.js.map +1 -1
  19. package/dist/coValues/static.d.ts +4 -4
  20. package/dist/coValues/static.js.map +1 -1
  21. package/dist/group.d.ts +8 -6
  22. package/dist/group.js +20 -4
  23. package/dist/group.js.map +1 -1
  24. package/dist/index.d.ts +7 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/media.d.ts +1 -2
  27. package/dist/node.d.ts +7 -3
  28. package/dist/node.js +37 -7
  29. package/dist/node.js.map +1 -1
  30. package/dist/queries.d.ts +114 -0
  31. package/dist/queries.js +260 -0
  32. package/dist/queries.js.map +1 -0
  33. package/dist/{testUtils.d.ts → tests/testUtils.d.ts} +9 -9
  34. package/dist/{testUtils.js → tests/testUtils.js} +7 -5
  35. package/dist/tests/testUtils.js.map +1 -0
  36. package/package.json +2 -2
  37. package/src/account.ts +5 -5
  38. package/src/coValue.ts +54 -28
  39. package/src/coValueCore.ts +6 -6
  40. package/src/coValues/coList.ts +73 -37
  41. package/src/coValues/coMap.ts +134 -68
  42. package/src/coValues/coStream.ts +86 -55
  43. package/src/coValues/static.ts +5 -5
  44. package/src/group.ts +50 -11
  45. package/src/index.ts +10 -8
  46. package/src/media.ts +1 -2
  47. package/src/node.ts +70 -19
  48. package/src/queries.ts +519 -0
  49. package/src/{account.test.ts → tests/account.test.ts} +4 -4
  50. package/src/{coValue.test.ts → tests/coValue.test.ts} +5 -5
  51. package/src/{coValueCore.test.ts → tests/coValueCore.test.ts} +7 -7
  52. package/src/{crypto.test.ts → tests/crypto.test.ts} +3 -3
  53. package/src/{group.test.ts → tests/group.test.ts} +2 -2
  54. package/src/{permissions.test.ts → tests/permissions.test.ts} +5 -5
  55. package/src/tests/queries.test.ts +301 -0
  56. package/src/{sync.test.ts → tests/sync.test.ts} +10 -10
  57. package/src/{testUtils.ts → tests/testUtils.ts} +8 -6
  58. package/dist/testUtils.js.map +0 -1
@@ -1,48 +1,49 @@
1
- import { JsonObject, JsonValue } from '../jsonValue.js';
2
- import { TransactionID } from '../ids.js';
3
- import { CoID, ReadableCoValue, WriteableCoValue } from '../coValue.js';
4
- import { CoValueCore, accountOrAgentIDfromSessionID } from '../coValueCore.js';
5
- import { AccountID, isAccountID } from '../account.js';
6
- import { Group } from '../group.js';
7
- import { parseJSON } from '../jsonStringify.js';
8
-
9
- type MapOp<K extends string, V extends JsonValue | undefined> = {
1
+ import { JsonObject, JsonValue } from "../jsonValue.js";
2
+ import { TransactionID } from "../ids.js";
3
+ import { CoID, CoValue, isCoValue } from "../coValue.js";
4
+ import { CoValueCore, accountOrAgentIDfromSessionID } from "../coValueCore.js";
5
+ import { AccountID, isAccountID } from "../account.js";
6
+ import { Group } from "../group.js";
7
+ import { parseJSON } from "../jsonStringify.js";
8
+
9
+ type MapOp<K extends string, V extends JsonValue | CoValue | undefined> = {
10
10
  txID: TransactionID;
11
11
  madeAt: number;
12
12
  changeIdx: number;
13
13
  } & MapOpPayload<K, V>;
14
14
  // TODO: add after TransactionID[] for conflicts/ordering
15
15
 
16
- export type MapOpPayload<K extends string, V extends JsonValue | undefined> = {
17
- op: "set";
18
- key: K;
19
- value: V;
20
- } |
21
- {
22
- op: "del";
23
- key: K;
24
- };
25
-
26
- export type MapK<M extends { [key: string]: JsonValue | undefined; }> = keyof M & string;
27
- export type MapV<M extends { [key: string]: JsonValue | undefined; }> = M[MapK<M>];
28
-
16
+ export type MapOpPayload<
17
+ K extends string,
18
+ V extends JsonValue | CoValue | undefined
19
+ > =
20
+ | {
21
+ op: "set";
22
+ key: K;
23
+ value: V extends CoValue ? CoID<V> : Exclude<V, CoValue>;
24
+ }
25
+ | {
26
+ op: "del";
27
+ key: K;
28
+ };
29
29
 
30
30
  /** A collaborative map with precise shape `M` and optional static metadata `Meta` */
31
31
  export class CoMap<
32
- M extends { [key: string]: JsonValue | undefined; },
33
- Meta extends JsonObject | null = null,
34
- > implements ReadableCoValue {
35
- id: CoID<CoMap<M, Meta>>;
32
+ M extends { [key: string]: JsonValue | CoValue | undefined },
33
+ Meta extends JsonObject | null = null
34
+ > implements CoValue
35
+ {
36
+ id: CoID<this>;
36
37
  type = "comap" as const;
37
38
  core: CoValueCore;
38
39
  /** @internal */
39
40
  ops: {
40
- [KK in MapK<M>]?: MapOp<KK, M[KK]>[];
41
+ [Key in keyof M & string]?: MapOp<Key, M[Key]>[];
41
42
  };
42
43
 
43
44
  /** @internal */
44
45
  constructor(core: CoValueCore) {
45
- this.id = core.id as CoID<CoMap<M, Meta>>;
46
+ this.id = core.id as CoID<this>;
46
47
  this.core = core;
47
48
  this.ops = {};
48
49
 
@@ -61,11 +62,18 @@ export class CoMap<
61
62
  protected fillOpsFromCoValue() {
62
63
  this.ops = {};
63
64
 
64
- for (const { txID, changes, madeAt } of this.core.getValidSortedTransactions()) {
65
- for (const [changeIdx, changeUntyped] of (
66
- parseJSON(changes)
65
+ for (const {
66
+ txID,
67
+ changes,
68
+ madeAt,
69
+ } of this.core.getValidSortedTransactions()) {
70
+ for (const [changeIdx, changeUntyped] of parseJSON(
71
+ changes
67
72
  ).entries()) {
68
- const change = changeUntyped as MapOpPayload<MapK<M>, MapV<M>>;
73
+ const change = changeUntyped as MapOpPayload<
74
+ keyof M & string,
75
+ M[keyof M & string]
76
+ >;
69
77
  let entries = this.ops[change.key];
70
78
  if (!entries) {
71
79
  entries = [];
@@ -75,18 +83,25 @@ export class CoMap<
75
83
  txID,
76
84
  madeAt,
77
85
  changeIdx,
78
- ...(change as MapOpPayload<MapK<M>, MapV<M>>),
86
+ ...(change as MapOpPayload<
87
+ keyof M & string,
88
+ M[keyof M & string]
89
+ >),
79
90
  });
80
91
  }
81
92
  }
82
93
  }
83
94
 
84
- keys(): MapK<M>[] {
85
- return Object.keys(this.ops) as MapK<M>[];
95
+ keys(): (keyof M & string)[] {
96
+ return Object.keys(this.ops) as (keyof M & string)[];
86
97
  }
87
98
 
88
99
  /** Returns the current value for the given key. */
89
- get<K extends MapK<M>>(key: K): M[K] | undefined {
100
+ get<K extends keyof M & string>(
101
+ key: K
102
+ ):
103
+ | (M[K] extends CoValue ? CoID<M[K]> : Exclude<M[K], CoValue>)
104
+ | undefined {
90
105
  const ops = this.ops[key];
91
106
  if (!ops) {
92
107
  return undefined;
@@ -101,7 +116,12 @@ export class CoMap<
101
116
  }
102
117
  }
103
118
 
104
- getAtTime<K extends MapK<M>>(key: K, time: number): M[K] | undefined {
119
+ getAtTime<K extends keyof M & string>(
120
+ key: K,
121
+ time: number
122
+ ):
123
+ | (M[K] extends CoValue ? CoID<M[K]> : Exclude<M[K], CoValue>)
124
+ | undefined {
105
125
  const ops = this.ops[key];
106
126
  if (!ops) {
107
127
  return undefined;
@@ -121,8 +141,8 @@ export class CoMap<
121
141
  }
122
142
 
123
143
  /** Returns the accountID of the last account to modify the value for the given key. */
124
- whoEdited<K extends MapK<M>>(key: K): AccountID | undefined {
125
- const tx = this.getLastTxID(key);
144
+ whoEdited<K extends keyof M & string>(key: K): AccountID | undefined {
145
+ const tx = this.getLastTxID(key);
126
146
  if (!tx) {
127
147
  return undefined;
128
148
  }
@@ -134,7 +154,7 @@ export class CoMap<
134
154
  }
135
155
  }
136
156
 
137
- getLastTxID<K extends MapK<M>>(key: K): TransactionID | undefined {
157
+ getLastTxID<K extends keyof M & string>(key: K): TransactionID | undefined {
138
158
  const ops = this.ops[key];
139
159
  if (!ops) {
140
160
  return undefined;
@@ -145,7 +165,15 @@ export class CoMap<
145
165
  return lastEntry.txID;
146
166
  }
147
167
 
148
- getLastEntry<K extends MapK<M>>(key: K): { at: number; txID: TransactionID; value: M[K]; } | undefined {
168
+ getLastEntry<K extends keyof M & string>(
169
+ key: K
170
+ ):
171
+ | {
172
+ at: number;
173
+ txID: TransactionID;
174
+ value: M[K] extends CoValue ? CoID<M[K]> : Exclude<M[K], CoValue>;
175
+ }
176
+ | undefined {
149
177
  const ops = this.ops[key];
150
178
  if (!ops) {
151
179
  return undefined;
@@ -156,21 +184,43 @@ export class CoMap<
156
184
  if (lastEntry.op === "del") {
157
185
  return undefined;
158
186
  } else {
159
- return { at: lastEntry.madeAt, txID: lastEntry.txID, value: lastEntry.value };
187
+ return {
188
+ at: lastEntry.madeAt,
189
+ txID: lastEntry.txID,
190
+ value: lastEntry.value,
191
+ };
160
192
  }
161
193
  }
162
194
 
163
- getHistory<K extends MapK<M>>(key: K): { at: number; txID: TransactionID; value: M[K] | undefined; }[] {
195
+ getHistory<K extends keyof M & string>(
196
+ key: K
197
+ ): {
198
+ at: number;
199
+ txID: TransactionID;
200
+ value:
201
+ | (M[K] extends CoValue ? CoID<M[K]> : Exclude<M[K], CoValue>)
202
+ | undefined;
203
+ }[] {
164
204
  const ops = this.ops[key];
165
205
  if (!ops) {
166
206
  return [];
167
207
  }
168
208
 
169
- const history: { at: number; txID: TransactionID; value: M[K] | undefined; }[] = [];
209
+ const history: {
210
+ at: number;
211
+ txID: TransactionID;
212
+ value:
213
+ | (M[K] extends CoValue ? CoID<M[K]> : Exclude<M[K], CoValue>)
214
+ | undefined;
215
+ }[] = [];
170
216
 
171
217
  for (const op of ops) {
172
218
  if (op.op === "del") {
173
- history.push({ at: op.madeAt, txID: op.txID, value: undefined });
219
+ history.push({
220
+ at: op.madeAt,
221
+ txID: op.txID,
222
+ value: undefined,
223
+ });
174
224
  } else {
175
225
  history.push({ at: op.madeAt, txID: op.txID, value: op.value });
176
226
  }
@@ -192,25 +242,28 @@ export class CoMap<
192
242
  return json;
193
243
  }
194
244
 
195
- subscribe(listener: (coMap: CoMap<M, Meta>) => void): () => void {
245
+ subscribe(listener: (coMap: this) => void): () => void {
196
246
  return this.core.subscribe((content) => {
197
- listener(content as CoMap<M, Meta>);
247
+ listener(content as this);
198
248
  });
199
249
  }
200
250
 
201
- edit(changer: (editable: WriteableCoMap<M, Meta>) => void): CoMap<M, Meta> {
251
+ edit(changer: (editable: WriteableCoMap<M, Meta>) => void): this {
202
252
  const editable = new WriteableCoMap<M, Meta>(this.core);
203
253
  changer(editable);
204
- return new CoMap(this.core);
254
+ return new CoMap(this.core) as this;
205
255
  }
206
256
  }
207
257
 
208
258
  export class WriteableCoMap<
209
- M extends { [key: string]: JsonValue | undefined; },
210
- Meta extends JsonObject | null = null,
211
- > extends CoMap<M, Meta> implements WriteableCoValue {
259
+ M extends { [key: string]: JsonValue | CoValue | undefined },
260
+ Meta extends JsonObject | null = null
261
+ >
262
+ extends CoMap<M, Meta>
263
+ implements CoValue
264
+ {
212
265
  /** @internal */
213
- edit(_changer: (editable: WriteableCoMap<M, Meta>) => void): CoMap<M, Meta> {
266
+ edit(_changer: (editable: WriteableCoMap<M, Meta>) => void): this {
214
267
  throw new Error("Already editing.");
215
268
  }
216
269
 
@@ -219,14 +272,21 @@ export class WriteableCoMap<
219
272
  * If `privacy` is `"private"` **(default)**, both `key` and `value` are encrypted in the transaction, only readable by other members of the group this `CoMap` belongs to. Not even sync servers can see the content in plaintext.
220
273
  *
221
274
  * If `privacy` is `"trusting"`, both `key` and `value` are stored in plaintext in the transaction, visible to everyone who gets a hold of it, including sync servers. */
222
- set<K extends MapK<M>>(key: K, value: M[K], privacy: "private" | "trusting" = "private"): void {
223
- this.core.makeTransaction([
224
- {
225
- op: "set",
226
- key,
227
- value,
228
- },
229
- ], privacy);
275
+ set<K extends keyof M & string>(
276
+ key: K,
277
+ value: M[K] extends CoValue ? M[K] | CoID<M[K]> : M[K],
278
+ privacy: "private" | "trusting" = "private"
279
+ ): void {
280
+ this.core.makeTransaction(
281
+ [
282
+ {
283
+ op: "set",
284
+ key,
285
+ value: isCoValue(value) ? value.id : value,
286
+ },
287
+ ],
288
+ privacy
289
+ );
230
290
 
231
291
  this.fillOpsFromCoValue();
232
292
  }
@@ -236,13 +296,19 @@ export class WriteableCoMap<
236
296
  * If `privacy` is `"private"` **(default)**, `key` is encrypted in the transaction, only readable by other members of the group this `CoMap` belongs to. Not even sync servers can see the content in plaintext.
237
297
  *
238
298
  * If `privacy` is `"trusting"`, `key` is stored in plaintext in the transaction, visible to everyone who gets a hold of it, including sync servers. */
239
- delete(key: MapK<M>, privacy: "private" | "trusting" = "private"): void {
240
- this.core.makeTransaction([
241
- {
242
- op: "del",
243
- key,
244
- },
245
- ], privacy);
299
+ delete(
300
+ key: keyof M & string,
301
+ privacy: "private" | "trusting" = "private"
302
+ ): void {
303
+ this.core.makeTransaction(
304
+ [
305
+ {
306
+ op: "del",
307
+ key,
308
+ },
309
+ ],
310
+ privacy
311
+ );
246
312
 
247
313
  this.fillOpsFromCoValue();
248
314
  }
@@ -1,14 +1,13 @@
1
1
  import { JsonObject, JsonValue } from "../jsonValue.js";
2
- import { CoID, ReadableCoValue, WriteableCoValue } from "../coValue.js";
2
+ import { CoValue, CoID, isCoValue } from "../coValue.js";
3
3
  import { CoValueCore, accountOrAgentIDfromSessionID } from "../coValueCore.js";
4
4
  import { Group } from "../group.js";
5
5
  import { SessionID } from "../ids.js";
6
6
  import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
7
- import { AccountID } from "../index.js";
8
- import { isAccountID } from "../account.js";
7
+ import { AccountID, isAccountID } from "../account.js";
9
8
  import { parseJSON } from "../jsonStringify.js";
10
9
 
11
- export type BinaryChunkInfo = {
10
+ export type BinaryStreamInfo = {
12
11
  mimeType: string;
13
12
  fileName?: string;
14
13
  totalSizeBytes?: number;
@@ -16,7 +15,7 @@ export type BinaryChunkInfo = {
16
15
 
17
16
  export type BinaryStreamStart = {
18
17
  type: "start";
19
- } & BinaryChunkInfo;
18
+ } & BinaryStreamInfo;
20
19
 
21
20
  export type BinaryStreamChunk = {
22
21
  type: "chunk";
@@ -34,20 +33,25 @@ export type BinaryStreamItem =
34
33
  | BinaryStreamChunk
35
34
  | BinaryStreamEnd;
36
35
 
36
+ export type CoStreamItem<T extends JsonValue | CoValue> = {
37
+ item: T extends CoValue ? CoID<T> : Exclude<T, CoValue>;
38
+ madeAt: number;
39
+ };
40
+
37
41
  export class CoStream<
38
- T extends JsonValue,
42
+ T extends JsonValue | CoValue,
39
43
  Meta extends JsonObject | null = null
40
- > implements ReadableCoValue
44
+ > implements CoValue
41
45
  {
42
- id: CoID<CoStream<T, Meta>>;
46
+ id: CoID<this>;
43
47
  type = "costream" as const;
44
48
  core: CoValueCore;
45
49
  items: {
46
- [key: SessionID]: {item: T, madeAt: number}[];
50
+ [key: SessionID]: CoStreamItem<T>[];
47
51
  };
48
52
 
49
53
  constructor(core: CoValueCore) {
50
- this.id = core.id as CoID<CoStream<T, Meta>>;
54
+ this.id = core.id as CoID<this>;
51
55
  this.core = core;
52
56
  this.items = {};
53
57
  this.fillFromCoValue();
@@ -71,18 +75,22 @@ export class CoStream<
71
75
  changes,
72
76
  } of this.core.getValidSortedTransactions()) {
73
77
  for (const changeUntyped of parseJSON(changes)) {
74
- const change = changeUntyped as T;
78
+ const change = changeUntyped as T extends CoValue
79
+ ? CoID<T>
80
+ : Exclude<T, CoValue>;
75
81
  let entries = this.items[txID.sessionID];
76
82
  if (!entries) {
77
83
  entries = [];
78
84
  this.items[txID.sessionID] = entries;
79
85
  }
80
- entries.push({item: change, madeAt});
86
+ entries.push({ item: change, madeAt });
81
87
  }
82
88
  }
83
89
  }
84
90
 
85
- getSingleStream(): T[] | undefined {
91
+ getSingleStream():
92
+ | (T extends CoValue ? CoID<T> : Exclude<T, CoValue>)[]
93
+ | undefined {
86
94
  if (Object.keys(this.items).length === 0) {
87
95
  return undefined;
88
96
  } else if (Object.keys(this.items).length !== 1) {
@@ -91,36 +99,54 @@ export class CoStream<
91
99
  );
92
100
  }
93
101
 
94
- return Object.values(this.items)[0]?.map(item => item.item);
102
+ return Object.values(this.items)[0]?.map((item) => item.item);
95
103
  }
96
104
 
97
- getLastItemsPerAccount(): {[account: AccountID]: T | undefined} {
98
- const result: {[account: AccountID]: {item: T, madeAt: number} | undefined} = {};
105
+ getLastItemsPerAccount(): {
106
+ [account: AccountID]:
107
+ | (T extends CoValue ? CoID<T> : Exclude<T, CoValue>)
108
+ | undefined;
109
+ } {
110
+ const result: { [account: AccountID]: CoStreamItem<T> | undefined } =
111
+ {};
99
112
 
100
113
  for (const [sessionID, items] of Object.entries(this.items)) {
101
- const account = accountOrAgentIDfromSessionID(sessionID as SessionID);
114
+ const account = accountOrAgentIDfromSessionID(
115
+ sessionID as SessionID
116
+ );
102
117
  if (!isAccountID(account)) continue;
103
118
  if (items.length > 0) {
104
119
  const lastItemOfSession = items[items.length - 1]!;
105
- if (!result[account] || lastItemOfSession.madeAt > result[account]!.madeAt) {
120
+ if (
121
+ !result[account] ||
122
+ lastItemOfSession.madeAt > result[account]!.madeAt
123
+ ) {
106
124
  result[account] = lastItemOfSession;
107
125
  }
108
126
  }
109
127
  }
110
128
 
111
- return Object.fromEntries(Object.entries(result).map(([account, item]) =>
112
- [account, item?.item]
113
- ));
129
+ return Object.fromEntries(
130
+ Object.entries(result).map(([account, item]) => [
131
+ account,
132
+ item?.item,
133
+ ])
134
+ );
114
135
  }
115
136
 
116
- getLastItemFrom(account: AccountID): T | undefined {
117
- let lastItem: {item: T, madeAt: number} | undefined;
137
+ getLastItemFrom(
138
+ account: AccountID
139
+ ): (T extends CoValue ? CoID<T> : Exclude<T, CoValue>) | undefined {
140
+ let lastItem: CoStreamItem<T> | undefined;
118
141
 
119
142
  for (const [sessionID, items] of Object.entries(this.items)) {
120
143
  if (sessionID.startsWith(account)) {
121
144
  if (items.length > 0) {
122
145
  const lastItemOfSession = items[items.length - 1]!;
123
- if (!lastItem || lastItemOfSession.madeAt > lastItem.madeAt) {
146
+ if (
147
+ !lastItem ||
148
+ lastItemOfSession.madeAt > lastItem.madeAt
149
+ ) {
124
150
  lastItem = lastItemOfSession;
125
151
  }
126
152
  }
@@ -130,32 +156,35 @@ export class CoStream<
130
156
  return lastItem?.item;
131
157
  }
132
158
 
133
- getLastItemFromMe(): T | undefined {
159
+ getLastItemFromMe():
160
+ | (T extends CoValue ? CoID<T> : Exclude<T, CoValue>)
161
+ | undefined {
134
162
  const myAccountID = this.core.node.account.id;
135
163
  if (!isAccountID(myAccountID)) return undefined;
136
164
  return this.getLastItemFrom(myAccountID);
137
165
  }
138
166
 
139
167
  toJSON(): {
140
- [key: SessionID]: T[];
168
+ [key: SessionID]: (T extends CoValue ? CoID<T> : Exclude<T, CoValue>)[];
141
169
  } {
142
- return Object.fromEntries(Object.entries(this.items).map(([sessionID, items]) =>
143
- [sessionID, items.map(item => item.item)]
144
- ));
170
+ return Object.fromEntries(
171
+ Object.entries(this.items).map(([sessionID, items]) => [
172
+ sessionID,
173
+ items.map((item) => item.item),
174
+ ])
175
+ );
145
176
  }
146
177
 
147
- subscribe(listener: (coMap: CoStream<T, Meta>) => void): () => void {
178
+ subscribe(listener: (coStream: this) => void): () => void {
148
179
  return this.core.subscribe((content) => {
149
- listener(content as CoStream<T, Meta>);
180
+ listener(content as this);
150
181
  });
151
182
  }
152
183
 
153
- edit(
154
- changer: (editable: WriteableCoStream<T, Meta>) => void
155
- ): CoStream<T, Meta> {
184
+ edit(changer: (editable: WriteableCoStream<T, Meta>) => void): this {
156
185
  const editable = new WriteableCoStream<T, Meta>(this.core);
157
186
  changer(editable);
158
- return new CoStream(this.core);
187
+ return new CoStream(this.core) as this;
159
188
  }
160
189
  }
161
190
 
@@ -165,12 +194,14 @@ export class BinaryCoStream<
165
194
  Meta extends BinaryCoStreamMeta = { type: "binary" }
166
195
  >
167
196
  extends CoStream<BinaryStreamItem, Meta>
168
- implements ReadableCoValue
197
+ implements CoValue
169
198
  {
170
- id!: CoID<BinaryCoStream<Meta>>;
199
+ id!: CoID<this>;
171
200
 
172
- getBinaryChunks(allowUnfinished?: boolean):
173
- | (BinaryChunkInfo & { chunks: Uint8Array[]; finished: boolean })
201
+ getBinaryChunks(
202
+ allowUnfinished?: boolean
203
+ ):
204
+ | (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
174
205
  | undefined {
175
206
  // const before = performance.now();
176
207
  const items = this.getSingleStream();
@@ -226,31 +257,33 @@ export class BinaryCoStream<
226
257
  };
227
258
  }
228
259
 
229
- edit(
230
- changer: (editable: WriteableBinaryCoStream<Meta>) => void
231
- ): BinaryCoStream<Meta> {
260
+ edit(changer: (editable: WriteableBinaryCoStream<Meta>) => void): this {
232
261
  const editable = new WriteableBinaryCoStream<Meta>(this.core);
233
262
  changer(editable);
234
- return new BinaryCoStream(this.core);
263
+ return new BinaryCoStream(this.core) as this;
235
264
  }
236
265
  }
237
266
 
238
267
  export class WriteableCoStream<
239
- T extends JsonValue,
268
+ T extends JsonValue | CoValue,
240
269
  Meta extends JsonObject | null = null
241
270
  >
242
271
  extends CoStream<T, Meta>
243
- implements WriteableCoValue
272
+ implements CoValue
244
273
  {
245
274
  /** @internal */
246
- edit(
247
- _changer: (editable: WriteableCoStream<T, Meta>) => void
248
- ): CoStream<T, Meta> {
275
+ edit(_changer: (editable: WriteableCoStream<T, Meta>) => void): this {
249
276
  throw new Error("Already editing.");
250
277
  }
251
278
 
252
- push(item: T, privacy: "private" | "trusting" = "private") {
253
- this.core.makeTransaction([item], privacy);
279
+ push(
280
+ item: T extends CoValue ? T | CoID<T> : T,
281
+ privacy: "private" | "trusting" = "private"
282
+ ) {
283
+ this.core.makeTransaction(
284
+ [isCoValue(item) ? item.id : item],
285
+ privacy
286
+ );
254
287
  this.fillFromCoValue();
255
288
  }
256
289
  }
@@ -259,12 +292,10 @@ export class WriteableBinaryCoStream<
259
292
  Meta extends BinaryCoStreamMeta = { type: "binary" }
260
293
  >
261
294
  extends BinaryCoStream<Meta>
262
- implements WriteableCoValue
295
+ implements CoValue
263
296
  {
264
297
  /** @internal */
265
- edit(
266
- _changer: (editable: WriteableBinaryCoStream<Meta>) => void
267
- ): BinaryCoStream<Meta> {
298
+ edit(_changer: (editable: WriteableBinaryCoStream<Meta>) => void): this {
268
299
  throw new Error("Already editing.");
269
300
  }
270
301
 
@@ -274,7 +305,7 @@ export class WriteableBinaryCoStream<
274
305
  }
275
306
 
276
307
  startBinaryStream(
277
- settings: BinaryChunkInfo,
308
+ settings: BinaryStreamInfo,
278
309
  privacy: "private" | "trusting" = "private"
279
310
  ) {
280
311
  this.push(
@@ -1,15 +1,15 @@
1
1
  import { JsonObject } from '../jsonValue.js';
2
- import { CoID, ReadableCoValue } from '../coValue.js';
2
+ import { CoID, CoValue } from '../coValue.js';
3
3
  import { CoValueCore } from '../coValueCore.js';
4
4
  import { Group } from '../index.js';
5
5
 
6
- export class Static<T extends JsonObject> implements ReadableCoValue{
7
- id: CoID<Static<T>>;
6
+ export class Static<T extends JsonObject> implements CoValue{
7
+ id: CoID<this>;
8
8
  type = "static" as const;
9
9
  core: CoValueCore;
10
10
 
11
11
  constructor(core: CoValueCore) {
12
- this.id = core.id as CoID<Static<T>>;
12
+ this.id = core.id as CoID<this>;
13
13
  this.core = core;
14
14
  }
15
15
 
@@ -25,7 +25,7 @@ export class Static<T extends JsonObject> implements ReadableCoValue{
25
25
  throw new Error("Method not implemented.");
26
26
  }
27
27
 
28
- subscribe(_listener: (coMap: Static<T>) => void): () => void {
28
+ subscribe(_listener: (st: this) => void): () => void {
29
29
  throw new Error("Method not implemented.");
30
30
  }
31
31
  }