cojson 0.6.7 → 0.7.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/.turbo/turbo-build.log +2 -2
  3. package/CHANGELOG.md +8 -2
  4. package/dist/coValue.js.map +1 -1
  5. package/dist/coValueCore.js.map +1 -1
  6. package/dist/coValues/account.js +5 -5
  7. package/dist/coValues/account.js.map +1 -1
  8. package/dist/coValues/coList.js +39 -58
  9. package/dist/coValues/coList.js.map +1 -1
  10. package/dist/coValues/coMap.js +20 -61
  11. package/dist/coValues/coMap.js.map +1 -1
  12. package/dist/coValues/coStream.js +14 -64
  13. package/dist/coValues/coStream.js.map +1 -1
  14. package/dist/coValues/group.js +57 -59
  15. package/dist/coValues/group.js.map +1 -1
  16. package/dist/coreToCoValue.js +17 -12
  17. package/dist/coreToCoValue.js.map +1 -1
  18. package/dist/ids.js +3 -0
  19. package/dist/ids.js.map +1 -1
  20. package/dist/index.js +9 -9
  21. package/dist/index.js.map +1 -1
  22. package/dist/localNode.js +54 -38
  23. package/dist/localNode.js.map +1 -1
  24. package/dist/permissions.js +2 -2
  25. package/dist/permissions.js.map +1 -1
  26. package/dist/tests/testUtils.js +6 -11
  27. package/dist/tests/testUtils.js.map +1 -1
  28. package/dist/typeUtils/expectGroup.js +2 -2
  29. package/dist/typeUtils/expectGroup.js.map +1 -1
  30. package/dist/typeUtils/isCoValue.js +8 -8
  31. package/dist/typeUtils/isCoValue.js.map +1 -1
  32. package/package.json +3 -4
  33. package/src/coValue.ts +21 -21
  34. package/src/coValueCore.ts +8 -8
  35. package/src/coValues/account.ts +15 -27
  36. package/src/coValues/coList.ts +58 -97
  37. package/src/coValues/coMap.ts +27 -129
  38. package/src/coValues/coStream.ts +31 -137
  39. package/src/coValues/group.ts +52 -46
  40. package/src/coreToCoValue.ts +16 -12
  41. package/src/ids.ts +4 -0
  42. package/src/index.ts +30 -38
  43. package/src/jsonValue.ts +1 -1
  44. package/src/localNode.ts +92 -79
  45. package/src/media.ts +4 -4
  46. package/src/permissions.ts +3 -3
  47. package/src/tests/account.test.ts +12 -12
  48. package/src/tests/coValue.test.ts +149 -182
  49. package/src/tests/coValueCore.test.ts +8 -3
  50. package/src/tests/crypto.test.ts +7 -0
  51. package/src/tests/group.test.ts +13 -6
  52. package/src/tests/permissions.test.ts +648 -840
  53. package/src/tests/sync.test.ts +44 -68
  54. package/src/tests/testUtils.ts +6 -11
  55. package/src/typeUtils/expectGroup.ts +4 -4
  56. package/src/typeUtils/isCoValue.ts +11 -11
package/src/index.ts CHANGED
@@ -6,15 +6,10 @@ import {
6
6
  } from "./coValueCore.js";
7
7
  import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
8
8
  import { LocalNode } from "./localNode.js";
9
- import type { CoValue } from "./coValue.js";
10
- import { CoMap, MutableCoMap } from "./coValues/coMap.js";
11
- import { CoList, MutableCoList } from "./coValues/coList.js";
12
- import {
13
- CoStream,
14
- MutableCoStream,
15
- BinaryCoStream,
16
- MutableBinaryCoStream,
17
- } from "./coValues/coStream.js";
9
+ import type { RawCoValue } from "./coValue.js";
10
+ import { RawCoMap } from "./coValues/coMap.js";
11
+ import { RawCoList } from "./coValues/coList.js";
12
+ import { RawCoStream, RawBinaryCoStream } from "./coValues/coStream.js";
18
13
  import {
19
14
  agentSecretFromBytes,
20
15
  agentSecretToBytes,
@@ -27,22 +22,23 @@ import {
27
22
  cryptoReady,
28
23
  } from "./crypto.js";
29
24
  import { connectedPeers } from "./streamUtils.js";
30
- import {
31
- ControlledAgent,
32
- ControlledAccount,
33
- } from "./coValues/account.js";
25
+ import { ControlledAgent, RawControlledAccount } from "./coValues/account.js";
34
26
  import type { Role } from "./permissions.js";
35
- import { rawCoIDtoBytes, rawCoIDfromBytes } from "./ids.js";
36
- import { Group, EVERYONE } from "./coValues/group.js";
27
+ import { rawCoIDtoBytes, rawCoIDfromBytes, isRawCoID } from "./ids.js";
28
+ import { RawGroup, EVERYONE } from "./coValues/group.js";
37
29
  import type { Everyone } from "./coValues/group.js";
38
30
  import { base64URLtoBytes, bytesToBase64url } from "./base64url.js";
39
31
  import { parseJSON } from "./jsonStringify.js";
40
- import { Account, Profile, accountHeaderForInitialAgentSecret } from "./coValues/account.js";
32
+ import {
33
+ RawAccount,
34
+ RawProfile,
35
+ accountHeaderForInitialAgentSecret,
36
+ } from "./coValues/account.js";
41
37
  import { expectGroup } from "./typeUtils/expectGroup.js";
42
38
  import { isAccountID } from "./typeUtils/isAccountID.js";
43
39
 
44
40
  import type { SessionID, AgentID } from "./ids.js";
45
- import type { CoID, AnyCoValue } from "./coValue.js";
41
+ import type { CoID, AnyRawCoValue } from "./coValue.js";
46
42
  import type {
47
43
  BinaryStreamInfo,
48
44
  BinaryCoStreamMeta,
@@ -53,13 +49,13 @@ import type { AgentSecret } from "./crypto.js";
53
49
  import type {
54
50
  AccountID,
55
51
  AccountMeta,
56
- AccountMigration,
52
+ RawAccountMigration,
57
53
  ProfileMeta,
58
54
  } from "./coValues/account.js";
59
55
  import type { InviteSecret } from "./coValues/group.js";
60
56
  import type * as Media from "./media.js";
61
57
 
62
- type Value = JsonValue | AnyCoValue;
58
+ type Value = JsonValue | AnyRawCoValue;
63
59
 
64
60
  /** @hidden */
65
61
  export const cojsonInternals = {
@@ -82,37 +78,33 @@ export const cojsonInternals = {
82
78
  accountOrAgentIDfromSessionID,
83
79
  isAccountID,
84
80
  accountHeaderForInitialAgentSecret,
85
- idforHeader
81
+ idforHeader,
86
82
  };
87
83
 
88
84
  export {
89
85
  LocalNode,
90
- Group,
86
+ RawGroup,
91
87
  Role,
92
88
  EVERYONE,
93
89
  Everyone,
94
- CoMap,
95
- MutableCoMap,
96
- CoList,
97
- MutableCoList,
98
- CoStream,
99
- MutableCoStream,
100
- BinaryCoStream,
101
- MutableBinaryCoStream,
102
- CoValue,
90
+ RawCoMap,
91
+ RawCoList,
92
+ RawCoStream,
93
+ RawBinaryCoStream,
94
+ RawCoValue,
103
95
  CoID,
104
- AnyCoValue,
105
- Account,
96
+ AnyRawCoValue,
97
+ RawAccount,
106
98
  AccountID,
107
99
  AccountMeta,
108
- AccountMigration,
109
- Profile,
100
+ RawAccountMigration,
101
+ RawProfile as Profile,
110
102
  ProfileMeta,
111
103
  SessionID,
112
104
  Media,
113
105
  CoValueCore,
114
106
  ControlledAgent,
115
- ControlledAccount,
107
+ RawControlledAccount,
116
108
  cryptoReady as cojsonReady,
117
109
  MAX_RECOMMENDED_TX_SIZE,
118
110
  JsonValue,
@@ -123,11 +115,10 @@ export {
123
115
  AgentSecret,
124
116
  InviteSecret,
125
117
  SyncMessage,
118
+ isRawCoID
126
119
  };
127
120
 
128
- export type {
129
- Value,
130
- }
121
+ export type { Value };
131
122
 
132
123
  // eslint-disable-next-line @typescript-eslint/no-namespace
133
124
  export namespace CojsonInternalTypes {
@@ -145,4 +136,5 @@ export namespace CojsonInternalTypes {
145
136
  export type ProfileMeta = import("./coValues/account.js").ProfileMeta;
146
137
  export type SealerSecret = import("./crypto.js").SealerSecret;
147
138
  export type SignerSecret = import("./crypto.js").SignerSecret;
139
+ export type JsonObject = import("./jsonValue.js").JsonObject;
148
140
  }
package/src/jsonValue.ts CHANGED
@@ -2,5 +2,5 @@ import { RawCoID } from './ids.js';
2
2
 
3
3
  export type JsonAtom = string | number | boolean | null;
4
4
  export type JsonValue = JsonAtom | JsonArray | JsonObject | RawCoID;
5
- export type JsonArray = JsonValue[];
5
+ export type JsonArray = JsonValue[] | readonly JsonValue[];
6
6
  export type JsonObject = { [key: string]: JsonValue | undefined; };
package/src/localNode.ts CHANGED
@@ -16,25 +16,25 @@ import {
16
16
  } from "./coValueCore.js";
17
17
  import {
18
18
  InviteSecret,
19
- Group,
19
+ RawGroup,
20
20
  secretSeedFromInviteSecret,
21
21
  } from "./coValues/group.js";
22
22
  import { Peer, PeerID, SyncManager } from "./sync.js";
23
23
  import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
24
24
  import { CoID } from "./coValue.js";
25
25
  import {
26
- Account,
26
+ RawAccount,
27
27
  AccountMeta,
28
28
  accountHeaderForInitialAgentSecret,
29
29
  ControlledAccountOrAgent,
30
- ControlledAccount,
30
+ RawControlledAccount,
31
31
  ControlledAgent,
32
32
  AccountID,
33
- Profile,
34
- AccountMigration,
33
+ RawProfile,
34
+ RawAccountMigration,
35
35
  } from "./coValues/account.js";
36
- import { CoMap } from "./coValues/coMap.js";
37
- import { CoValue } from "./index.js";
36
+ import { RawCoMap } from "./coValues/coMap.js";
37
+ import { RawCoValue } from "./index.js";
38
38
  import { expectGroup } from "./typeUtils/expectGroup.js";
39
39
 
40
40
  /** A `LocalNode` represents a local view of a set of loaded `CoValue`s, from the perspective of a particular account (or primitive cryptographic agent).
@@ -69,8 +69,6 @@ export class LocalNode {
69
69
 
70
70
  /** @category 2. Node Creation */
71
71
  static async withNewlyCreatedAccount<
72
- P extends Profile = Profile,
73
- R extends CoMap = CoMap,
74
72
  Meta extends AccountMeta = AccountMeta
75
73
  >({
76
74
  name,
@@ -80,7 +78,7 @@ export class LocalNode {
80
78
  }: {
81
79
  name: string;
82
80
  peersToLoadFrom?: Peer[];
83
- migration?: AccountMigration<P, R, Meta>;
81
+ migration?: RawAccountMigration<Meta>;
84
82
  initialAgentSecret?: AgentSecret;
85
83
  }): Promise<{
86
84
  node: LocalNode;
@@ -102,7 +100,7 @@ export class LocalNode {
102
100
  );
103
101
 
104
102
  const accountOnNodeWithAccount =
105
- nodeWithAccount.account as ControlledAccount<P, R, Meta>;
103
+ nodeWithAccount.account as RawControlledAccount<Meta>;
106
104
 
107
105
  const profile = nodeWithAccount.expectProfileLoaded(
108
106
  accountOnNodeWithAccount.id,
@@ -116,19 +114,30 @@ export class LocalNode {
116
114
  }
117
115
 
118
116
  if (migration) {
119
- await migration(accountOnNodeWithAccount, profile as P, nodeWithAccount);
117
+ await migration(accountOnNodeWithAccount, profile, nodeWithAccount);
120
118
  }
121
119
 
122
- nodeWithAccount.account = new ControlledAccount(
120
+ const controlledAccount = new RawControlledAccount(
123
121
  accountOnNodeWithAccount.core,
124
122
  accountOnNodeWithAccount.agentSecret
125
123
  );
126
124
 
125
+ nodeWithAccount.account = controlledAccount
126
+ nodeWithAccount.coValues[controlledAccount.id] = {
127
+ state: "loaded",
128
+ coValue: controlledAccount.core,
129
+ };
130
+ controlledAccount.core._cachedContent = undefined;
131
+
127
132
  // we shouldn't need this, but it fixes account data not syncing for new accounts
128
133
  function syncAllCoValuesAfterCreateAccount() {
129
- for (const coValueEntry of Object.values(nodeWithAccount.coValues)) {
134
+ for (const coValueEntry of Object.values(
135
+ nodeWithAccount.coValues
136
+ )) {
130
137
  if (coValueEntry.state === "loaded") {
131
- void nodeWithAccount.syncManager.syncCoValue(coValueEntry.coValue);
138
+ void nodeWithAccount.syncManager.syncCoValue(
139
+ coValueEntry.coValue
140
+ );
132
141
  }
133
142
  }
134
143
  }
@@ -146,11 +155,7 @@ export class LocalNode {
146
155
  }
147
156
 
148
157
  /** @category 2. Node Creation */
149
- static async withLoadedAccount<
150
- P extends Profile = Profile,
151
- R extends CoMap = CoMap,
152
- Meta extends AccountMeta = AccountMeta
153
- >({
158
+ static async withLoadedAccount<Meta extends AccountMeta = AccountMeta>({
154
159
  accountID,
155
160
  accountSecret,
156
161
  sessionID,
@@ -161,7 +166,7 @@ export class LocalNode {
161
166
  accountSecret: AgentSecret;
162
167
  sessionID: SessionID;
163
168
  peersToLoadFrom: Peer[];
164
- migration?: AccountMigration<P, R, Meta>;
169
+ migration?: RawAccountMigration<Meta>;
165
170
  }): Promise<LocalNode> {
166
171
  const loadingNode = new LocalNode(
167
172
  new ControlledAgent(accountSecret),
@@ -180,7 +185,7 @@ export class LocalNode {
180
185
  throw new Error("Account unavailable from all peers");
181
186
  }
182
187
 
183
- const controlledAccount = new ControlledAccount(
188
+ const controlledAccount = new RawControlledAccount(
184
189
  account.core,
185
190
  accountSecret
186
191
  );
@@ -198,6 +203,7 @@ export class LocalNode {
198
203
  state: "loaded",
199
204
  coValue: controlledAccount.core,
200
205
  };
206
+ controlledAccount.core._cachedContent = undefined;
201
207
 
202
208
  const profileID = account.get("profile");
203
209
  if (!profileID) {
@@ -205,13 +211,17 @@ export class LocalNode {
205
211
  }
206
212
  const profile = await node.load(profileID);
207
213
 
214
+ if (profile === "unavailable") {
215
+ throw new Error("Profile unavailable from all peers");
216
+ }
217
+
208
218
  if (migration) {
209
219
  await migration(
210
- controlledAccount as ControlledAccount<P, R, Meta>,
211
- profile as P,
220
+ controlledAccount as RawControlledAccount<Meta>,
221
+ profile,
212
222
  node
213
223
  );
214
- node.account = new ControlledAccount(
224
+ node.account = new RawControlledAccount(
215
225
  controlledAccount.core,
216
226
  controlledAccount.agentSecret
217
227
  );
@@ -275,7 +285,7 @@ export class LocalNode {
275
285
  *
276
286
  * @category 3. Low-level
277
287
  */
278
- async load<T extends CoValue>(
288
+ async load<T extends RawCoValue>(
279
289
  id: CoID<T>,
280
290
  onProgress?: (progress: number) => void
281
291
  ): Promise<T | "unavailable"> {
@@ -288,8 +298,19 @@ export class LocalNode {
288
298
  return core.getCurrentContent() as T;
289
299
  }
290
300
 
301
+ getLoaded<T extends RawCoValue>(id: CoID<T>): T | undefined {
302
+ const entry = this.coValues[id];
303
+ if (!entry) {
304
+ return undefined;
305
+ }
306
+ if (entry.state === "loaded") {
307
+ return entry.coValue.getCurrentContent() as T;
308
+ }
309
+ return undefined;
310
+ }
311
+
291
312
  /** @category 3. Low-level */
292
- subscribe<T extends CoValue>(
313
+ subscribe<T extends RawCoValue>(
293
314
  id: CoID<T>,
294
315
  callback: (update: T | "unavailable") => void
295
316
  ): () => void {
@@ -321,7 +342,7 @@ export class LocalNode {
321
342
  }
322
343
 
323
344
  /** @deprecated Use Account.acceptInvite instead */
324
- async acceptInvite<T extends CoValue>(
345
+ async acceptInvite<T extends RawCoValue>(
325
346
  groupOrOwnedValueID: CoID<T>,
326
347
  inviteSecret: InviteSecret
327
348
  ): Promise<void> {
@@ -335,7 +356,7 @@ export class LocalNode {
335
356
 
336
357
  if (groupOrOwnedValue.core.header.ruleset.type === "ownedByGroup") {
337
358
  return this.acceptInvite(
338
- groupOrOwnedValue.core.header.ruleset.group as CoID<Group>,
359
+ groupOrOwnedValue.core.header.ruleset.group as CoID<RawGroup>,
339
360
  inviteSecret
340
361
  );
341
362
  } else if (groupOrOwnedValue.core.header.ruleset.type !== "group") {
@@ -425,7 +446,7 @@ export class LocalNode {
425
446
  }
426
447
 
427
448
  /** @internal */
428
- expectProfileLoaded(id: AccountID, expectation?: string): Profile {
449
+ expectProfileLoaded(id: AccountID, expectation?: string): RawProfile {
429
450
  const account = this.expectCoValueLoaded(id, expectation);
430
451
  const profileID = expectGroup(account.getCurrentContent()).get(
431
452
  "profile"
@@ -440,14 +461,14 @@ export class LocalNode {
440
461
  return this.expectCoValueLoaded(
441
462
  profileID,
442
463
  expectation
443
- ).getCurrentContent() as Profile;
464
+ ).getCurrentContent() as RawProfile;
444
465
  }
445
466
 
446
467
  /** @internal */
447
468
  createAccount(
448
469
  name: string,
449
470
  agentSecret = newRandomAgentSecret()
450
- ): ControlledAccount {
471
+ ): RawControlledAccount {
451
472
  const accountAgentID = getAgentID(agentSecret);
452
473
  let account = expectGroup(
453
474
  this.createCoValue(accountHeaderForInitialAgentSecret(agentSecret))
@@ -458,31 +479,25 @@ export class LocalNode {
458
479
  .getCurrentContent()
459
480
  );
460
481
 
461
- account = account.mutate((editable) => {
462
- editable.set(accountAgentID, "admin", "trusting");
482
+ account.set(accountAgentID, "admin", "trusting");
463
483
 
464
- const readKey = newRandomKeySecret();
484
+ const readKey = newRandomKeySecret();
465
485
 
466
- const sealed = seal({
467
- message: readKey.secret,
468
- from: getAgentSealerSecret(agentSecret),
469
- to: getAgentSealerID(accountAgentID),
470
- nOnceMaterial: {
471
- in: account.id,
472
- tx: account.core.nextTransactionID(),
473
- },
474
- });
486
+ const sealed = seal({
487
+ message: readKey.secret,
488
+ from: getAgentSealerSecret(agentSecret),
489
+ to: getAgentSealerID(accountAgentID),
490
+ nOnceMaterial: {
491
+ in: account.id,
492
+ tx: account.core.nextTransactionID(),
493
+ },
494
+ });
475
495
 
476
- editable.set(
477
- `${readKey.id}_for_${accountAgentID}`,
478
- sealed,
479
- "trusting"
480
- );
496
+ account.set(`${readKey.id}_for_${accountAgentID}`, sealed, "trusting");
481
497
 
482
- editable.set("readKey", readKey.id, "trusting");
483
- });
498
+ account.set("readKey", readKey.id, "trusting");
484
499
 
485
- const profile = account.createMap<Profile>(
500
+ const profile = account.createMap<RawProfile>(
486
501
  { name },
487
502
  {
488
503
  type: "profile",
@@ -490,7 +505,7 @@ export class LocalNode {
490
505
  "trusting"
491
506
  );
492
507
 
493
- account = account.set("profile", profile.id, "trusting");
508
+ account.set("profile", profile.id, "trusting");
494
509
 
495
510
  const accountOnThisNode = this.expectCoValueLoaded(account.id);
496
511
 
@@ -503,7 +518,7 @@ export class LocalNode {
503
518
  profileOnThisNode._sessionLogs = new Map(profile.core.sessionLogs);
504
519
  profileOnThisNode._cachedContent = undefined;
505
520
 
506
- return new ControlledAccount(accountOnThisNode, agentSecret);
521
+ return new RawControlledAccount(accountOnThisNode, agentSecret);
507
522
  }
508
523
 
509
524
  /** @internal */
@@ -531,7 +546,7 @@ export class LocalNode {
531
546
  );
532
547
  }
533
548
 
534
- return new Account(coValue).currentAgentID();
549
+ return new RawAccount(coValue).currentAgentID();
535
550
  }
536
551
 
537
552
  async resolveAccountAgentAsync(
@@ -566,13 +581,13 @@ export class LocalNode {
566
581
  );
567
582
  }
568
583
 
569
- return new Account(coValue).currentAgentID();
584
+ return new RawAccount(coValue).currentAgentID();
570
585
  }
571
586
 
572
587
  /**
573
588
  * @deprecated use Account.createGroup() instead
574
589
  */
575
- createGroup(): Group {
590
+ createGroup(): RawGroup {
576
591
  const groupCoValue = this.createCoValue({
577
592
  type: "comap",
578
593
  ruleset: { type: "group", initialAdmin: this.account.id },
@@ -582,27 +597,25 @@ export class LocalNode {
582
597
 
583
598
  let group = expectGroup(groupCoValue.getCurrentContent());
584
599
 
585
- group = group.mutate((editable) => {
586
- editable.set(this.account.id, "admin", "trusting");
587
-
588
- const readKey = newRandomKeySecret();
589
-
590
- editable.set(
591
- `${readKey.id}_for_${this.account.id}`,
592
- seal({
593
- message: readKey.secret,
594
- from: this.account.currentSealerSecret(),
595
- to: this.account.currentSealerID(),
596
- nOnceMaterial: {
597
- in: groupCoValue.id,
598
- tx: groupCoValue.nextTransactionID(),
599
- },
600
- }),
601
- "trusting"
602
- );
600
+ group.set(this.account.id, "admin", "trusting");
603
601
 
604
- editable.set("readKey", readKey.id, "trusting");
605
- });
602
+ const readKey = newRandomKeySecret();
603
+
604
+ group.set(
605
+ `${readKey.id}_for_${this.account.id}`,
606
+ seal({
607
+ message: readKey.secret,
608
+ from: this.account.currentSealerSecret(),
609
+ to: this.account.currentSealerID(),
610
+ nOnceMaterial: {
611
+ in: groupCoValue.id,
612
+ tx: groupCoValue.nextTransactionID(),
613
+ },
614
+ }),
615
+ "trusting"
616
+ );
617
+
618
+ group.set("readKey", readKey.id, "trusting");
606
619
 
607
620
  return group;
608
621
  }
@@ -649,9 +662,9 @@ export class LocalNode {
649
662
  }
650
663
  }
651
664
 
652
- if (account instanceof ControlledAccount) {
665
+ if (account instanceof RawControlledAccount) {
653
666
  // To make sure that when we edit the account, we're modifying the correct sessions
654
- const accountInNode = new ControlledAccount(
667
+ const accountInNode = new RawControlledAccount(
655
668
  newNode.expectCoValueLoaded(account.id),
656
669
  account.agentSecret
657
670
  );
package/src/media.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { CoMap } from './coValues/coMap.js'
2
- import { BinaryCoStream } from './coValues/coStream.js'
1
+ import { RawCoMap } from './coValues/coMap.js'
2
+ import { RawBinaryCoStream } from './coValues/coStream.js'
3
3
 
4
- export type ImageDefinition = CoMap<{
4
+ export type ImageDefinition = RawCoMap<{
5
5
  originalSize: [number, number];
6
6
  placeholderDataURL?: string;
7
- [res: `${number}x${number}`]: BinaryCoStream["id"];
7
+ [res: `${number}x${number}`]: RawBinaryCoStream["id"];
8
8
  }>;
@@ -5,7 +5,7 @@ import { KeyID } from "./crypto.js";
5
5
  import { CoValueCore, Transaction } from "./coValueCore.js";
6
6
  import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
7
7
  import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
8
- import { Account, AccountID, Profile } from "./coValues/account.js";
8
+ import { RawAccount, AccountID, RawProfile } from "./coValues/account.js";
9
9
  import { parseJSON } from "./jsonStringify.js";
10
10
  import { EVERYONE, Everyone } from "./coValues/group.js";
11
11
  import { expectGroup } from "./typeUtils/expectGroup.js";
@@ -101,7 +101,7 @@ export function determineValidTransactions(
101
101
  const change = changes[0] as
102
102
  | MapOpPayload<AccountID | AgentID | Everyone, Role>
103
103
  | MapOpPayload<"readKey", JsonValue>
104
- | MapOpPayload<"profile", CoID<Profile>>;
104
+ | MapOpPayload<"profile", CoID<RawProfile>>;
105
105
  if (changes.length !== 1) {
106
106
  console.warn("Group transaction must have exactly one change");
107
107
  continue;
@@ -248,7 +248,7 @@ export function determineValidTransactions(
248
248
  const groupAtTime = groupContent.atTime(tx.madeAt);
249
249
  const effectiveTransactor =
250
250
  transactor === groupContent.id &&
251
- groupAtTime instanceof Account
251
+ groupAtTime instanceof RawAccount
252
252
  ? groupAtTime.currentAgentID()
253
253
  : transactor;
254
254
  const transactorRoleAtTxTime =
@@ -1,8 +1,15 @@
1
+ import { expect, test, beforeEach } from "vitest";
1
2
  import { newRandomSessionID } from "../coValueCore.js";
2
3
  import { cojsonReady } from "../index.js";
3
4
  import { LocalNode } from "../localNode.js";
4
5
  import { connectedPeers } from "../streamUtils.js";
5
6
 
7
+ import { webcrypto } from "node:crypto";
8
+ if (!("crypto" in globalThis)) {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ (globalThis as any).crypto = webcrypto;
11
+ }
12
+
6
13
  beforeEach(async () => {
7
14
  await cojsonReady;
8
15
  });
@@ -29,14 +36,9 @@ test("A node with an account can create groups and and objects within them", asy
29
36
  const group = await node.createGroup();
30
37
  expect(group).not.toBeNull();
31
38
 
32
- let map = group.createMap();
33
- map = map.edit((edit) => {
34
- edit.set("foo", "bar", "private");
35
- expect(edit.get("foo")).toEqual("bar");
36
- });
37
-
39
+ const map = group.createMap();
40
+ map.set("foo", "bar", "private");
38
41
  expect(map.get("foo")).toEqual("bar");
39
-
40
42
  expect(map.lastEditAt("foo")?.by).toEqual(accountID);
41
43
  });
42
44
 
@@ -47,11 +49,9 @@ test("Can create account with one node, and then load it on another", async () =
47
49
  const group = await node.createGroup();
48
50
  expect(group).not.toBeNull();
49
51
 
50
- let map = group.createMap();
51
- map = map.edit((edit) => {
52
- edit.set("foo", "bar", "private");
53
- expect(edit.get("foo")).toEqual("bar");
54
- });
52
+ const map = group.createMap();
53
+ map.set("foo", "bar", "private");
54
+ expect(map.get("foo")).toEqual("bar");
55
55
 
56
56
  const [node1asPeer, node2asPeer] = connectedPeers("node1", "node2", {
57
57
  trace: true,