cojson 0.2.2 → 0.3.0-alpha.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 (85) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/dist/account.d.ts +8 -8
  3. package/dist/account.js +2 -2
  4. package/dist/account.js.map +1 -1
  5. package/dist/coValue.d.ts +22 -27
  6. package/dist/coValue.js +21 -0
  7. package/dist/coValue.js.map +1 -1
  8. package/dist/coValueCore.d.ts +7 -7
  9. package/dist/coValueCore.js +11 -14
  10. package/dist/coValueCore.js.map +1 -1
  11. package/dist/coValues/coList.d.ts +107 -42
  12. package/dist/coValues/coList.js +163 -72
  13. package/dist/coValues/coList.js.map +1 -1
  14. package/dist/coValues/coMap.d.ts +109 -50
  15. package/dist/coValues/coMap.js +161 -109
  16. package/dist/coValues/coMap.js.map +1 -1
  17. package/dist/coValues/coStream.d.ts +78 -33
  18. package/dist/coValues/coStream.js +134 -53
  19. package/dist/coValues/coStream.js.map +1 -1
  20. package/dist/crypto.d.ts +8 -3
  21. package/dist/crypto.js +6 -6
  22. package/dist/crypto.js.map +1 -1
  23. package/dist/group.d.ts +59 -23
  24. package/dist/group.js +83 -25
  25. package/dist/group.js.map +1 -1
  26. package/dist/index.d.ts +14 -11
  27. package/dist/index.js +8 -8
  28. package/dist/index.js.map +1 -1
  29. package/dist/{node.d.ts → localNode.d.ts} +23 -11
  30. package/dist/{node.js → localNode.js} +80 -42
  31. package/dist/localNode.js.map +1 -0
  32. package/dist/media.d.ts +1 -2
  33. package/dist/permissions.js +6 -3
  34. package/dist/permissions.js.map +1 -1
  35. package/dist/queriedCoValues/queriedCoList.d.ts +66 -0
  36. package/dist/queriedCoValues/queriedCoList.js +120 -0
  37. package/dist/queriedCoValues/queriedCoList.js.map +1 -0
  38. package/dist/queriedCoValues/queriedCoMap.d.ts +47 -0
  39. package/dist/queriedCoValues/queriedCoMap.js +83 -0
  40. package/dist/queriedCoValues/queriedCoMap.js.map +1 -0
  41. package/dist/queriedCoValues/queriedCoStream.d.ts +40 -0
  42. package/dist/queriedCoValues/queriedCoStream.js +72 -0
  43. package/dist/queriedCoValues/queriedCoStream.js.map +1 -0
  44. package/dist/queries.d.ts +31 -0
  45. package/dist/queries.js +77 -0
  46. package/dist/queries.js.map +1 -0
  47. package/dist/sync.d.ts +1 -1
  48. package/dist/sync.js +1 -1
  49. package/dist/sync.js.map +1 -1
  50. package/dist/{testUtils.d.ts → tests/testUtils.d.ts} +9 -9
  51. package/dist/{testUtils.js → tests/testUtils.js} +9 -7
  52. package/dist/tests/testUtils.js.map +1 -0
  53. package/package.json +2 -2
  54. package/src/account.ts +6 -6
  55. package/src/coValue.ts +65 -34
  56. package/src/coValueCore.ts +18 -22
  57. package/src/coValues/coList.ts +272 -122
  58. package/src/coValues/coMap.ts +349 -152
  59. package/src/coValues/coStream.ts +258 -94
  60. package/src/crypto.ts +37 -24
  61. package/src/group.ts +112 -46
  62. package/src/index.ts +42 -30
  63. package/src/{node.ts → localNode.ts} +117 -66
  64. package/src/media.ts +1 -2
  65. package/src/permissions.ts +15 -18
  66. package/src/queriedCoValues/queriedCoList.ts +248 -0
  67. package/src/queriedCoValues/queriedCoMap.ts +180 -0
  68. package/src/queriedCoValues/queriedCoStream.ts +125 -0
  69. package/src/queries.ts +142 -0
  70. package/src/sync.ts +2 -2
  71. package/src/{account.test.ts → tests/account.test.ts} +6 -9
  72. package/src/{coValue.test.ts → tests/coValue.test.ts} +120 -114
  73. package/src/{coValueCore.test.ts → tests/coValueCore.test.ts} +7 -7
  74. package/src/{crypto.test.ts → tests/crypto.test.ts} +19 -21
  75. package/src/{group.test.ts → tests/group.test.ts} +2 -2
  76. package/src/{permissions.test.ts → tests/permissions.test.ts} +260 -247
  77. package/src/tests/queries.test.ts +318 -0
  78. package/src/{sync.test.ts → tests/sync.test.ts} +39 -39
  79. package/src/{testUtils.ts → tests/testUtils.ts} +10 -8
  80. package/dist/coValues/static.d.ts +0 -14
  81. package/dist/coValues/static.js +0 -20
  82. package/dist/coValues/static.js.map +0 -1
  83. package/dist/node.js.map +0 -1
  84. package/dist/testUtils.js.map +0 -1
  85. package/src/coValues/static.ts +0 -31
@@ -9,7 +9,11 @@ import {
9
9
  newRandomKeySecret,
10
10
  seal,
11
11
  } from "./crypto.js";
12
- import { CoValueCore, CoValueHeader, newRandomSessionID } from "./coValueCore.js";
12
+ import {
13
+ CoValueCore,
14
+ CoValueHeader,
15
+ newRandomSessionID,
16
+ } from "./coValueCore.js";
13
17
  import {
14
18
  InviteSecret,
15
19
  Group,
@@ -19,9 +23,10 @@ import {
19
23
  } from "./group.js";
20
24
  import { Peer, SyncManager } from "./sync.js";
21
25
  import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
22
- import { CoID, CoValueImpl } from "./coValue.js";
26
+ import { CoID } from "./coValue.js";
27
+ import { Queried, query } from "./queries.js";
23
28
  import {
24
- Account,
29
+ AccountGroup,
25
30
  AccountMeta,
26
31
  accountHeaderForInitialAgentSecret,
27
32
  GeneralizedControlledAccount,
@@ -30,9 +35,9 @@ import {
30
35
  AccountID,
31
36
  Profile,
32
37
  AccountContent,
33
- AccountMap,
34
38
  } from "./account.js";
35
39
  import { CoMap } from "./coValues/coMap.js";
40
+ import { CoValue } from "./index.js";
36
41
 
37
42
  /** A `LocalNode` represents a local view of a set of loaded `CoValue`s, from the perspective of a particular account (or primitive cryptographic agent).
38
43
 
@@ -48,11 +53,14 @@ const { localNode } = useJazz();
48
53
  export class LocalNode {
49
54
  /** @internal */
50
55
  coValues: { [key: RawCoID]: CoValueState } = {};
51
- /** @internal */
56
+ /** @category 3. Low-level */
52
57
  account: GeneralizedControlledAccount;
58
+ /** @category 3. Low-level */
53
59
  currentSessionID: SessionID;
54
- sync = new SyncManager(this);
60
+ /** @category 3. Low-level */
61
+ syncManager = new SyncManager(this);
55
62
 
63
+ /** @category 3. Low-level */
56
64
  constructor(
57
65
  account: GeneralizedControlledAccount,
58
66
  currentSessionID: SessionID
@@ -61,6 +69,7 @@ export class LocalNode {
61
69
  this.currentSessionID = currentSessionID;
62
70
  }
63
71
 
72
+ /** @category 2. Node Creation */
64
73
  static withNewlyCreatedAccount(
65
74
  name: string,
66
75
  initialAgentSecret = newRandomAgentSecret()
@@ -91,6 +100,7 @@ export class LocalNode {
91
100
  };
92
101
  }
93
102
 
103
+ /** @category 2. Node Creation */
94
104
  static async withLoadedAccount(
95
105
  accountID: AccountID,
96
106
  accountSecret: AgentSecret,
@@ -105,7 +115,7 @@ export class LocalNode {
105
115
  const accountPromise = loadingNode.load(accountID);
106
116
 
107
117
  for (const peer of peersToLoadFrom) {
108
- loadingNode.sync.addPeer(peer);
118
+ loadingNode.syncManager.addPeer(peer);
109
119
  }
110
120
 
111
121
  const account = await accountPromise;
@@ -115,8 +125,8 @@ export class LocalNode {
115
125
  new ControlledAccount(accountSecret, account, loadingNode),
116
126
  sessionID
117
127
  );
118
- node.sync = loadingNode.sync;
119
- node.sync.local = node;
128
+ node.syncManager = loadingNode.syncManager;
129
+ node.syncManager.local = node;
120
130
 
121
131
  return node;
122
132
  }
@@ -126,7 +136,7 @@ export class LocalNode {
126
136
  const coValue = new CoValueCore(header, this);
127
137
  this.coValues[coValue.id] = { state: "loaded", coValue: coValue };
128
138
 
129
- void this.sync.syncCoValue(coValue);
139
+ void this.syncManager.syncCoValue(coValue);
130
140
 
131
141
  return coValue;
132
142
  }
@@ -139,7 +149,7 @@ export class LocalNode {
139
149
 
140
150
  this.coValues[id] = entry;
141
151
 
142
- this.sync.loadFromPeers(id);
152
+ this.syncManager.loadFromPeers(id);
143
153
  }
144
154
  if (entry.state === "loaded") {
145
155
  return Promise.resolve(entry.coValue);
@@ -151,28 +161,51 @@ export class LocalNode {
151
161
  * Loads a CoValue's content, syncing from peers as necessary and resolving the returned
152
162
  * promise once a first version has been loaded. See `coValue.subscribe()` and `node.useTelepathicData()`
153
163
  * for listening to subsequent updates to the CoValue.
164
+ *
165
+ * @category 3. Low-level
154
166
  */
155
- async load<T extends CoValueImpl>(id: CoID<T>): Promise<T> {
167
+ async load<T extends CoValue>(id: CoID<T>): Promise<T> {
156
168
  return (await this.loadCoValue(id)).getCurrentContent() as T;
157
169
  }
158
170
 
159
- /**
160
- * Loads a profile associated with an account. `Profile` is at least a `CoMap<{string: name}>`,
161
- * but might contain other, app-specific properties.
162
- */
163
- async loadProfile(id: AccountID): Promise<Profile> {
164
- const account = await this.load<AccountMap>(id);
165
- const profileID = account.get("profile");
171
+ /** @category 3. Low-level */
172
+ subscribe<T extends CoValue>(
173
+ id: CoID<T>,
174
+ callback: (update: T) => void
175
+ ): () => void {
176
+ let stopped = false;
177
+ let unsubscribe!: () => void;
166
178
 
167
- if (!profileID) {
168
- throw new Error(`Account ${id} has no profile`);
169
- }
170
- return (
171
- await this.loadCoValue(profileID)
172
- ).getCurrentContent() as Profile;
179
+ console.log("Subscribing to " + id);
180
+
181
+ this.load(id)
182
+ .then((coValue) => {
183
+ if (stopped) {
184
+ return;
185
+ }
186
+ unsubscribe = coValue.subscribe(callback);
187
+ })
188
+ .catch((e) => {
189
+ console.error("Error subscribing to ", id, e);
190
+ });
191
+
192
+ return () => {
193
+ console.log("Unsubscribing from " + id);
194
+ stopped = true;
195
+ unsubscribe?.();
196
+ };
197
+ }
198
+
199
+ /** @category 1. High-level */
200
+ query<T extends CoValue>(
201
+ id: CoID<T>,
202
+ callback: (update: Queried<T> | undefined) => void
203
+ ): () => void {
204
+ return query(id, this, callback);
173
205
  }
174
206
 
175
- async acceptInvite<T extends CoValueImpl>(
207
+ /** @category 1. High-level */
208
+ async acceptInvite<T extends CoValue>(
176
209
  groupOrOwnedValueID: CoID<T>,
177
210
  inviteSecret: InviteSecret
178
211
  ): Promise<void> {
@@ -204,10 +237,7 @@ export class LocalNode {
204
237
  }
205
238
  });
206
239
  setTimeout(
207
- () =>
208
- reject(
209
- new Error("Couldn't find invite before timeout")
210
- ),
240
+ () => reject(new Error("Couldn't find invite before timeout")),
211
241
  2000
212
242
  );
213
243
  });
@@ -224,7 +254,9 @@ export class LocalNode {
224
254
  (existingRole === "writer" && inviteRole === "reader") ||
225
255
  (existingRole === "reader" && inviteRole === "readerInvite")
226
256
  ) {
227
- console.debug("Not accepting invite that would replace or downgrade role");
257
+ console.debug(
258
+ "Not accepting invite that would replace or downgrade role"
259
+ );
228
260
  return;
229
261
  }
230
262
 
@@ -242,7 +274,8 @@ export class LocalNode {
242
274
  : "reader"
243
275
  );
244
276
 
245
- group.underlyingMap.core._sessions = groupAsInvite.underlyingMap.core.sessions;
277
+ group.underlyingMap.core._sessions =
278
+ groupAsInvite.underlyingMap.core.sessions;
246
279
  group.underlyingMap.core._cachedContent = undefined;
247
280
 
248
281
  for (const groupListener of group.underlyingMap.core.listeners) {
@@ -292,11 +325,12 @@ export class LocalNode {
292
325
  name: string,
293
326
  agentSecret = newRandomAgentSecret()
294
327
  ): ControlledAccount {
328
+ const accountAgentID = getAgentID(agentSecret);
295
329
  const account = this.createCoValue(
296
330
  accountHeaderForInitialAgentSecret(agentSecret)
297
331
  ).testWithDifferentAccount(
298
332
  new AnonymousControlledAccount(agentSecret),
299
- newRandomSessionID(getAgentID(agentSecret))
333
+ newRandomSessionID(accountAgentID)
300
334
  );
301
335
 
302
336
  const accountAsGroup = new Group(
@@ -304,22 +338,22 @@ export class LocalNode {
304
338
  account.node
305
339
  );
306
340
 
307
- accountAsGroup.underlyingMap.edit((editable) => {
308
- editable.set(getAgentID(agentSecret), "admin", "trusting");
341
+ accountAsGroup.underlyingMap.mutate((editable) => {
342
+ editable.set(accountAgentID, "admin", "trusting");
309
343
 
310
344
  const readKey = newRandomKeySecret();
311
345
 
312
346
  editable.set(
313
- `${readKey.id}_for_${getAgentID(agentSecret)}`,
314
- seal(
315
- readKey.secret,
316
- getAgentSealerSecret(agentSecret),
317
- getAgentSealerID(getAgentID(agentSecret)),
318
- {
347
+ `${readKey.id}_for_${accountAgentID}`,
348
+ seal({
349
+ message: readKey.secret,
350
+ from: getAgentSealerSecret(agentSecret),
351
+ to: getAgentSealerID(accountAgentID),
352
+ nOnceMaterial: {
319
353
  in: account.id,
320
354
  tx: account.nextTransactionID(),
321
- }
322
- ),
355
+ },
356
+ }),
323
357
  "trusting"
324
358
  );
325
359
 
@@ -332,28 +366,38 @@ export class LocalNode {
332
366
  account.node
333
367
  );
334
368
 
335
- const profile = accountAsGroup.createMap<Profile>({
336
- type: "profile",
337
- });
338
-
339
- profile.edit((editable) => {
340
- editable.set("name", name, "trusting");
341
- });
369
+ const profile = accountAsGroup.createMap<Profile>(
370
+ { name },
371
+ {
372
+ type: "profile",
373
+ },
374
+ "trusting"
375
+ );
342
376
 
343
- accountAsGroup.underlyingMap.edit((editable) => {
344
- editable.set("profile", profile.id, "trusting");
345
- });
377
+ accountAsGroup.underlyingMap.set("profile", profile.id, "trusting");
346
378
 
347
379
  const accountOnThisNode = this.expectCoValueLoaded(account.id);
348
380
 
349
- accountOnThisNode._sessions = {...accountAsGroup.underlyingMap.core.sessions};
381
+ accountOnThisNode._sessions = {
382
+ ...accountAsGroup.underlyingMap.core.sessions,
383
+ };
350
384
  accountOnThisNode._cachedContent = undefined;
351
385
 
386
+ const profileOnThisNode = this.createCoValue(profile.core.header);
387
+
388
+ profileOnThisNode._sessions = {
389
+ ...profile.core.sessions,
390
+ };
391
+ profileOnThisNode._cachedContent = undefined;
392
+
352
393
  return controlledAccount;
353
394
  }
354
395
 
355
396
  /** @internal */
356
- resolveAccountAgent(id: AccountID | AgentID, expectation?: string): AgentID {
397
+ resolveAccountAgent(
398
+ id: AccountID | AgentID,
399
+ expectation?: string
400
+ ): AgentID {
357
401
  if (isAgentID(id)) {
358
402
  return id;
359
403
  }
@@ -374,13 +418,16 @@ export class LocalNode {
374
418
  );
375
419
  }
376
420
 
377
- return new Account(
421
+ return new AccountGroup(
378
422
  coValue.getCurrentContent() as CoMap<GroupContent, AccountMeta>,
379
423
  this
380
424
  ).getCurrentAgentID();
381
425
  }
382
426
 
383
- /** Creates a new group (with the current account as the group's first admin). */
427
+ /**
428
+ * Creates a new group (with the current account as the group's first admin).
429
+ * @category 1. High-level
430
+ */
384
431
  createGroup(): Group {
385
432
  const groupCoValue = this.createCoValue({
386
433
  type: "comap",
@@ -391,22 +438,22 @@ export class LocalNode {
391
438
 
392
439
  let groupContent = expectGroupContent(groupCoValue.getCurrentContent());
393
440
 
394
- groupContent = groupContent.edit((editable) => {
441
+ groupContent = groupContent.mutate((editable) => {
395
442
  editable.set(this.account.id, "admin", "trusting");
396
443
 
397
444
  const readKey = newRandomKeySecret();
398
445
 
399
446
  editable.set(
400
447
  `${readKey.id}_for_${this.account.id}`,
401
- seal(
402
- readKey.secret,
403
- this.account.currentSealerSecret(),
404
- this.account.currentSealerID(),
405
- {
448
+ seal({
449
+ message: readKey.secret,
450
+ from: this.account.currentSealerSecret(),
451
+ to: this.account.currentSealerID(),
452
+ nOnceMaterial: {
406
453
  in: groupCoValue.id,
407
454
  tx: groupCoValue.nextTransactionID(),
408
- }
409
- ),
455
+ },
456
+ }),
410
457
  "trusting"
411
458
  );
412
459
 
@@ -443,7 +490,11 @@ export class LocalNode {
443
490
  continue;
444
491
  }
445
492
 
446
- const newCoValue = new CoValueCore(entry.coValue.header, newNode, {...entry.coValue.sessions});
493
+ const newCoValue = new CoValueCore(
494
+ entry.coValue.header,
495
+ newNode,
496
+ { ...entry.coValue.sessions }
497
+ );
447
498
 
448
499
  newNode.coValues[coValueID as RawCoID] = {
449
500
  state: "loaded",
package/src/media.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import { CoMap } from './coValues/coMap.js'
2
- import { CoID } from './coValue.js'
3
2
  import { BinaryCoStream } from './coValues/coStream.js'
4
3
 
5
4
  export type ImageDefinition = CoMap<{
6
5
  originalSize: [number, number];
7
6
  placeholderDataURL?: string;
8
- [res: `${number}x${number}`]: CoID<BinaryCoStream>;
7
+ [res: `${number}x${number}`]: BinaryCoStream;
9
8
  }>;
@@ -1,9 +1,7 @@
1
1
  import { CoID } from "./coValue.js";
2
2
  import { MapOpPayload } from "./coValues/coMap.js";
3
3
  import { JsonValue } from "./jsonValue.js";
4
- import {
5
- KeyID,
6
- } from "./crypto.js";
4
+ import { KeyID } from "./crypto.js";
7
5
  import {
8
6
  CoValueCore,
9
7
  Transaction,
@@ -11,11 +9,9 @@ import {
11
9
  accountOrAgentIDfromSessionID,
12
10
  } from "./coValueCore.js";
13
11
  import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
14
- import {
15
- AccountID,
16
- Profile,
17
- } from "./account.js";
12
+ import { AccountID, Profile } from "./account.js";
18
13
  import { parseJSON } from "./jsonStringify.js";
14
+ import { expectGroupContent } from "./group.js";
19
15
 
20
16
  export type PermissionsDef =
21
17
  | { type: "group"; initialAdmin: AccountID | AgentID }
@@ -77,7 +73,7 @@ export function determineValidTransactions(
77
73
  // console.log("before", { memberState, validTransactions });
78
74
  const transactor = accountOrAgentIDfromSessionID(sessionID);
79
75
 
80
- const changes = parseJSON(tx.changes)
76
+ const changes = parseJSON(tx.changes);
81
77
 
82
78
  const change = changes[0] as
83
79
  | MapOpPayload<AccountID | AgentID, Role>
@@ -193,12 +189,14 @@ export function determineValidTransactions(
193
189
 
194
190
  return validTransactions;
195
191
  } else if (coValue.header.ruleset.type === "ownedByGroup") {
196
- const groupContent = coValue.node
197
- .expectCoValueLoaded(
198
- coValue.header.ruleset.group,
199
- "Determining valid transaction in owned object but its group wasn't loaded"
200
- )
201
- .getCurrentContent();
192
+ const groupContent = expectGroupContent(
193
+ coValue.node
194
+ .expectCoValueLoaded(
195
+ coValue.header.ruleset.group,
196
+ "Determining valid transaction in owned object but its group wasn't loaded"
197
+ )
198
+ .getCurrentContent()
199
+ );
202
200
 
203
201
  if (groupContent.type !== "comap") {
204
202
  throw new Error("Group must be a map");
@@ -211,10 +209,9 @@ export function determineValidTransactions(
211
209
  );
212
210
  return sessionLog.transactions
213
211
  .filter((tx) => {
214
- const transactorRoleAtTxTime = groupContent.getAtTime(
215
- transactor,
216
- tx.madeAt
217
- );
212
+ const transactorRoleAtTxTime = groupContent
213
+ .atTime(tx.madeAt)
214
+ .get(transactor);
218
215
 
219
216
  return (
220
217
  transactorRoleAtTxTime === "admin" ||
@@ -0,0 +1,248 @@
1
+ import { CoList, MutableCoList } from "../coValues/coList.js";
2
+ import { CoValueCore } from "../coValueCore.js";
3
+ import { Group } from "../group.js";
4
+ import { isAccountID } from "../account.js";
5
+ import { AnyCoList, CoID, CoValue } from "../coValue.js";
6
+ import { TransactionID } from "../ids.js";
7
+ import { QueriedAccountAndProfile } from "./queriedCoMap.js";
8
+ import { ValueOrSubQueried, QueryContext } from "../queries.js";
9
+
10
+ export class QueriedCoList<L extends AnyCoList> extends Array<
11
+ ValueOrSubQueried<L["_item"]>
12
+ > {
13
+ coList!: L;
14
+ id!: CoID<L>;
15
+ type!: "colist";
16
+
17
+ /** @internal */
18
+ constructor(coList: L, queryContext: QueryContext) {
19
+ if (!(coList instanceof CoList)) {
20
+ // this might be called from an intrinsic, like map, trying to create an empty array
21
+ // passing `0` as the only parameter
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ return new Array(coList) as any;
24
+ }
25
+ super(
26
+ ...coList
27
+ .asArray()
28
+ .map(
29
+ (item) =>
30
+ queryContext.resolveValue(item) as ValueOrSubQueried<
31
+ L["_item"]
32
+ >
33
+ )
34
+ );
35
+
36
+ Object.defineProperties(this, {
37
+ coList: { value: coList },
38
+ id: { value: coList.id },
39
+ type: { value: "colist" },
40
+ edits: {
41
+ value: [...this.keys()].map((i) => {
42
+ const edit = coList.editAt(i)!;
43
+ return {
44
+ by:
45
+ edit.by && isAccountID(edit.by)
46
+ ? queryContext.resolveAccount(edit.by)
47
+ : undefined,
48
+ tx: edit.tx,
49
+ at: new Date(edit.at),
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ value: queryContext.resolveValue(edit.value) as any,
52
+ };
53
+ }),
54
+ },
55
+ deletions: {
56
+ value: coList.deletionEdits().map((deletion) => ({
57
+ by:
58
+ deletion.by && isAccountID(deletion.by)
59
+ ? queryContext.resolveAccount(deletion.by)
60
+ : undefined,
61
+ tx: deletion.tx,
62
+ at: new Date(deletion.at),
63
+ })),
64
+ },
65
+ });
66
+ }
67
+
68
+ get meta(): L["meta"] {
69
+ return this.coList.meta;
70
+ }
71
+
72
+ get group(): Group {
73
+ return this.coList.group;
74
+ }
75
+
76
+ get core(): CoValueCore {
77
+ return this.coList.core;
78
+ }
79
+
80
+ append(
81
+ item: L["_item"] extends CoValue
82
+ ? L["_item"] | CoID<L["_item"]>
83
+ : L["_item"],
84
+ after?: number,
85
+ privacy?: "private" | "trusting"
86
+ ): L {
87
+ return this.coList.append(item, after, privacy);
88
+ }
89
+
90
+ prepend(
91
+ item: L["_item"] extends CoValue
92
+ ? L["_item"] | CoID<L["_item"]>
93
+ : L["_item"],
94
+ before?: number,
95
+ privacy?: "private" | "trusting"
96
+ ): L {
97
+ return this.coList.prepend(item, before, privacy);
98
+ }
99
+
100
+ delete(at: number, privacy: "private" | "trusting"): L {
101
+ return this.coList.delete(at, privacy);
102
+ }
103
+
104
+ mutate(
105
+ mutator: (mutable: MutableCoList<L["_item"], L["meta"]>) => void
106
+ ): L {
107
+ return this.coList.mutate(mutator);
108
+ }
109
+
110
+ edits!: {
111
+ by?: QueriedAccountAndProfile;
112
+ tx: TransactionID;
113
+ at: Date;
114
+ value: L["_item"] extends CoValue
115
+ ? CoID<L["_item"]>
116
+ : Exclude<L["_item"], CoValue>;
117
+ }[];
118
+
119
+ deletions!: {
120
+ by?: QueriedAccountAndProfile;
121
+ tx: TransactionID;
122
+ at: Date;
123
+ }[];
124
+
125
+ /** @internal */
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ static isArray(arg: any): arg is any[] {
128
+ return Array.isArray(arg);
129
+ }
130
+
131
+ /** @internal */
132
+ static from<T>(arrayLike: ArrayLike<T>): T[];
133
+ /** @internal */
134
+ static from<T, U>(
135
+ arrayLike: ArrayLike<T>,
136
+ mapfn: (v: T, k: number) => U,
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ thisArg?: any
139
+ ): U[];
140
+ /** @internal */
141
+ static from<T>(iterable: Iterable<T> | ArrayLike<T>): T[];
142
+ /** @internal */
143
+ static from<T, U>(
144
+ iterable: Iterable<T> | ArrayLike<T>,
145
+ mapfn: (v: T, k: number) => U,
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
+ thisArg?: any
148
+ ): U[];
149
+ /** @internal */
150
+ static from<T, U>(
151
+ _iterable: unknown,
152
+ _mapfn?: unknown,
153
+ _thisArg?: unknown
154
+ ): T[] | U[] | T[] | U[] {
155
+ throw new Error("Array method 'from' not supported on QueriedCoList");
156
+ }
157
+
158
+ /** @internal */
159
+ static of<T>(..._items: T[]): T[] {
160
+ throw new Error("Array method 'of' not supported on QueriedCoList");
161
+ }
162
+
163
+ /** @internal */
164
+ pop(): ValueOrSubQueried<L["_item"]> | undefined {
165
+ throw new Error("Array method 'pop' not supported on QueriedCoList");
166
+ }
167
+
168
+ /** @internal */
169
+ push(..._items: ValueOrSubQueried<L["_item"]>[]): number {
170
+ throw new Error("Array method 'push' not supported on QueriedCoList");
171
+ }
172
+
173
+ /** @internal */
174
+ concat(
175
+ ..._items: ConcatArray<ValueOrSubQueried<L["_item"]>>[]
176
+ ): ValueOrSubQueried<L["_item"]>[];
177
+ /** @internal */
178
+ concat(
179
+ ..._items: (
180
+ | ValueOrSubQueried<L["_item"]>
181
+ | ConcatArray<ValueOrSubQueried<L["_item"]>>
182
+ )[]
183
+ ): ValueOrSubQueried<L["_item"]>[];
184
+ /** @internal */
185
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ concat(..._items: any[]): ValueOrSubQueried<L["_item"]>[] {
187
+ throw new Error("Array method 'concat' not supported on QueriedCoList");
188
+ }
189
+
190
+ /** @internal */
191
+ reverse(): ValueOrSubQueried<L["_item"]>[] {
192
+ throw new Error(
193
+ "Array method 'reverse' not supported on QueriedCoList"
194
+ );
195
+ }
196
+
197
+ /** @internal */
198
+ shift(): ValueOrSubQueried<L["_item"]> | undefined {
199
+ throw new Error("Array method 'shift' not supported on QueriedCoList");
200
+ }
201
+
202
+ /** @internal */
203
+ sort(
204
+ _compareFn?:
205
+ | ((
206
+ a: ValueOrSubQueried<L["_item"]>,
207
+ b: ValueOrSubQueried<L["_item"]>
208
+ ) => number)
209
+ | undefined
210
+ ): this {
211
+ throw new Error("Array method 'sort' not supported on QueriedCoList");
212
+ }
213
+
214
+ /** @internal */
215
+ splice(
216
+ _start: number,
217
+ _deleteCount?: number | undefined
218
+ ): ValueOrSubQueried<L["_item"]>[] {
219
+ throw new Error("Array method 'splice' not supported on QueriedCoList");
220
+ }
221
+
222
+ /** @internal */
223
+ unshift(..._items: ValueOrSubQueried<L["_item"]>[]): number {
224
+ throw new Error(
225
+ "Array method 'unshift' not supported on QueriedCoList"
226
+ );
227
+ }
228
+
229
+ /** @internal */
230
+ fill(
231
+ _value: ValueOrSubQueried<L["_item"]>,
232
+ _start?: number | undefined,
233
+ _end?: number | undefined
234
+ ): this {
235
+ throw new Error("Array method 'fill' not supported on QueriedCoList");
236
+ }
237
+
238
+ /** @internal */
239
+ copyWithin(
240
+ _target: number,
241
+ _start: number,
242
+ _end?: number | undefined
243
+ ): this {
244
+ throw new Error(
245
+ "Array method 'copyWithin' not supported on QueriedCoList"
246
+ );
247
+ }
248
+ }