cojson 0.7.0-alpha.5 → 0.7.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 (113) hide show
  1. package/.eslintrc.cjs +3 -2
  2. package/.prettierrc.js +9 -0
  3. package/.turbo/turbo-build.log +3 -30
  4. package/.turbo/turbo-lint.log +4 -0
  5. package/.turbo/turbo-test.log +1106 -0
  6. package/CHANGELOG.md +104 -0
  7. package/README.md +3 -1
  8. package/dist/base64url.test.js +25 -0
  9. package/dist/base64url.test.js.map +1 -0
  10. package/dist/coValueCore.js +60 -37
  11. package/dist/coValueCore.js.map +1 -1
  12. package/dist/coValues/account.js +16 -15
  13. package/dist/coValues/account.js.map +1 -1
  14. package/dist/coValues/coList.js +1 -1
  15. package/dist/coValues/coList.js.map +1 -1
  16. package/dist/coValues/coMap.js +17 -8
  17. package/dist/coValues/coMap.js.map +1 -1
  18. package/dist/coValues/group.js +13 -14
  19. package/dist/coValues/group.js.map +1 -1
  20. package/dist/coreToCoValue.js.map +1 -1
  21. package/dist/crypto/PureJSCrypto.js +89 -0
  22. package/dist/crypto/PureJSCrypto.js.map +1 -0
  23. package/dist/crypto/WasmCrypto.js +127 -0
  24. package/dist/crypto/WasmCrypto.js.map +1 -0
  25. package/dist/crypto/crypto.js +151 -0
  26. package/dist/crypto/crypto.js.map +1 -0
  27. package/dist/ids.js +4 -2
  28. package/dist/ids.js.map +1 -1
  29. package/dist/index.js +6 -8
  30. package/dist/index.js.map +1 -1
  31. package/dist/jsonStringify.js.map +1 -1
  32. package/dist/localNode.js +41 -38
  33. package/dist/localNode.js.map +1 -1
  34. package/dist/permissions.js +6 -6
  35. package/dist/permissions.js.map +1 -1
  36. package/dist/storage/FileSystem.js +61 -0
  37. package/dist/storage/FileSystem.js.map +1 -0
  38. package/dist/storage/chunksAndKnownStates.js +97 -0
  39. package/dist/storage/chunksAndKnownStates.js.map +1 -0
  40. package/dist/storage/index.js +265 -0
  41. package/dist/storage/index.js.map +1 -0
  42. package/dist/sync.js +29 -25
  43. package/dist/sync.js.map +1 -1
  44. package/dist/tests/account.test.js +58 -0
  45. package/dist/tests/account.test.js.map +1 -0
  46. package/dist/tests/coList.test.js +76 -0
  47. package/dist/tests/coList.test.js.map +1 -0
  48. package/dist/tests/coMap.test.js +136 -0
  49. package/dist/tests/coMap.test.js.map +1 -0
  50. package/dist/tests/coStream.test.js +172 -0
  51. package/dist/tests/coStream.test.js.map +1 -0
  52. package/dist/tests/coValueCore.test.js +114 -0
  53. package/dist/tests/coValueCore.test.js.map +1 -0
  54. package/dist/tests/crypto.test.js +118 -0
  55. package/dist/tests/crypto.test.js.map +1 -0
  56. package/dist/tests/cryptoImpl.test.js +113 -0
  57. package/dist/tests/cryptoImpl.test.js.map +1 -0
  58. package/dist/tests/group.test.js +34 -0
  59. package/dist/tests/group.test.js.map +1 -0
  60. package/dist/tests/permissions.test.js +1060 -0
  61. package/dist/tests/permissions.test.js.map +1 -0
  62. package/dist/tests/sync.test.js +816 -0
  63. package/dist/tests/sync.test.js.map +1 -0
  64. package/dist/tests/testUtils.js +12 -11
  65. package/dist/tests/testUtils.js.map +1 -1
  66. package/dist/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  67. package/dist/typeUtils/isAccountID.js.map +1 -1
  68. package/dist/typeUtils/isCoValue.js.map +1 -1
  69. package/package.json +14 -27
  70. package/src/base64url.test.ts +6 -5
  71. package/src/coValue.ts +1 -1
  72. package/src/coValueCore.ts +179 -126
  73. package/src/coValues/account.ts +30 -32
  74. package/src/coValues/coList.ts +11 -11
  75. package/src/coValues/coMap.ts +27 -17
  76. package/src/coValues/coStream.ts +17 -17
  77. package/src/coValues/group.ts +93 -109
  78. package/src/coreToCoValue.ts +5 -2
  79. package/src/crypto/PureJSCrypto.ts +200 -0
  80. package/src/crypto/WasmCrypto.ts +259 -0
  81. package/src/crypto/crypto.ts +336 -0
  82. package/src/ids.ts +8 -7
  83. package/src/index.ts +24 -24
  84. package/src/jsonStringify.ts +6 -4
  85. package/src/jsonValue.ts +2 -2
  86. package/src/localNode.ts +103 -109
  87. package/src/media.ts +3 -3
  88. package/src/permissions.ts +19 -21
  89. package/src/storage/FileSystem.ts +152 -0
  90. package/src/storage/chunksAndKnownStates.ts +139 -0
  91. package/src/storage/index.ts +479 -0
  92. package/src/streamUtils.ts +12 -12
  93. package/src/sync.ts +79 -63
  94. package/src/tests/account.test.ts +15 -15
  95. package/src/tests/coList.test.ts +94 -0
  96. package/src/tests/coMap.test.ts +162 -0
  97. package/src/tests/coStream.test.ts +246 -0
  98. package/src/tests/coValueCore.test.ts +36 -37
  99. package/src/tests/crypto.test.ts +66 -72
  100. package/src/tests/cryptoImpl.test.ts +183 -0
  101. package/src/tests/group.test.ts +16 -17
  102. package/src/tests/permissions.test.ts +269 -283
  103. package/src/tests/sync.test.ts +122 -123
  104. package/src/tests/testUtils.ts +24 -21
  105. package/src/typeUtils/accountOrAgentIDfromSessionID.ts +1 -2
  106. package/src/typeUtils/expectGroup.ts +1 -1
  107. package/src/typeUtils/isAccountID.ts +0 -1
  108. package/src/typeUtils/isCoValue.ts +1 -2
  109. package/tsconfig.json +0 -1
  110. package/dist/crypto.js +0 -254
  111. package/dist/crypto.js.map +0 -1
  112. package/src/crypto.ts +0 -484
  113. package/src/tests/coValue.test.ts +0 -497
package/src/localNode.ts CHANGED
@@ -1,14 +1,4 @@
1
- import {
2
- AgentSecret,
3
- agentSecretFromSecretSeed,
4
- createdNowUnique,
5
- getAgentID,
6
- getAgentSealerID,
7
- getAgentSealerSecret,
8
- newRandomAgentSecret,
9
- newRandomKeySecret,
10
- seal,
11
- } from "./crypto.js";
1
+ import { AgentSecret, CryptoProvider } from "./crypto/crypto.js";
12
2
  import {
13
3
  CoValueCore,
14
4
  CoValueHeader,
@@ -33,8 +23,7 @@ import {
33
23
  RawProfile,
34
24
  RawAccountMigration,
35
25
  } from "./coValues/account.js";
36
- import { RawCoMap } from "./coValues/coMap.js";
37
- import { RawCoValue } from "./index.js";
26
+ import { Profile, RawCoValue } from "./index.js";
38
27
  import { expectGroup } from "./typeUtils/expectGroup.js";
39
28
 
40
29
  /** A `LocalNode` represents a local view of a set of loaded `CoValue`s, from the perspective of a particular account (or primitive cryptographic agent).
@@ -49,6 +38,8 @@ const { localNode } = useJazz();
49
38
  ```
50
39
  */
51
40
  export class LocalNode {
41
+ /** @internal */
42
+ crypto: CryptoProvider;
52
43
  /** @internal */
53
44
  coValues: { [key: RawCoID]: CoValueState } = {};
54
45
  /** @category 3. Low-level */
@@ -61,24 +52,28 @@ export class LocalNode {
61
52
  /** @category 3. Low-level */
62
53
  constructor(
63
54
  account: ControlledAccountOrAgent,
64
- currentSessionID: SessionID
55
+ currentSessionID: SessionID,
56
+ crypto: CryptoProvider,
65
57
  ) {
66
58
  this.account = account;
67
59
  this.currentSessionID = currentSessionID;
60
+ this.crypto = crypto;
68
61
  }
69
62
 
70
63
  /** @category 2. Node Creation */
71
64
  static async withNewlyCreatedAccount<
72
- Meta extends AccountMeta = AccountMeta
65
+ Meta extends AccountMeta = AccountMeta,
73
66
  >({
74
- name,
67
+ creationProps,
75
68
  peersToLoadFrom,
76
69
  migration,
77
- initialAgentSecret = newRandomAgentSecret(),
70
+ crypto,
71
+ initialAgentSecret = crypto.newRandomAgentSecret(),
78
72
  }: {
79
- name: string;
73
+ creationProps: { name: string };
80
74
  peersToLoadFrom?: Peer[];
81
75
  migration?: RawAccountMigration<Meta>;
76
+ crypto: CryptoProvider;
82
77
  initialAgentSecret?: AgentSecret;
83
78
  }): Promise<{
84
79
  node: LocalNode;
@@ -86,27 +81,23 @@ export class LocalNode {
86
81
  accountSecret: AgentSecret;
87
82
  sessionID: SessionID;
88
83
  }> {
89
- const throwawayAgent = newRandomAgentSecret();
84
+ const throwawayAgent = crypto.newRandomAgentSecret();
90
85
  const setupNode = new LocalNode(
91
- new ControlledAgent(throwawayAgent),
92
- newRandomSessionID(getAgentID(throwawayAgent))
86
+ new ControlledAgent(throwawayAgent, crypto),
87
+ newRandomSessionID(crypto.getAgentID(throwawayAgent)),
88
+ crypto,
93
89
  );
94
90
 
95
- const account = setupNode.createAccount(name, initialAgentSecret);
91
+ const account = setupNode.createAccount(initialAgentSecret);
96
92
 
97
93
  const nodeWithAccount = account.core.node.testWithDifferentAccount(
98
94
  account,
99
- newRandomSessionID(account.id)
95
+ newRandomSessionID(account.id),
100
96
  );
101
97
 
102
98
  const accountOnNodeWithAccount =
103
99
  nodeWithAccount.account as RawControlledAccount<Meta>;
104
100
 
105
- const profile = nodeWithAccount.expectProfileLoaded(
106
- accountOnNodeWithAccount.id,
107
- "After creating account"
108
- );
109
-
110
101
  if (peersToLoadFrom) {
111
102
  for (const peer of peersToLoadFrom) {
112
103
  nodeWithAccount.syncManager.addPeer(peer);
@@ -114,29 +105,44 @@ export class LocalNode {
114
105
  }
115
106
 
116
107
  if (migration) {
117
- await migration(accountOnNodeWithAccount, profile, nodeWithAccount);
108
+ await migration(
109
+ accountOnNodeWithAccount,
110
+ nodeWithAccount,
111
+ creationProps,
112
+ );
113
+ } else {
114
+ const profileGroup = accountOnNodeWithAccount.createGroup();
115
+ profileGroup.addMember("everyone", "reader");
116
+ const profile = profileGroup.createMap<Profile>({
117
+ name: creationProps.name,
118
+ });
119
+ accountOnNodeWithAccount.set("profile", profile.id, "trusting");
118
120
  }
119
121
 
120
122
  const controlledAccount = new RawControlledAccount(
121
123
  accountOnNodeWithAccount.core,
122
- accountOnNodeWithAccount.agentSecret
124
+ accountOnNodeWithAccount.agentSecret,
123
125
  );
124
126
 
125
- nodeWithAccount.account = controlledAccount
127
+ nodeWithAccount.account = controlledAccount;
126
128
  nodeWithAccount.coValues[controlledAccount.id] = {
127
129
  state: "loaded",
128
130
  coValue: controlledAccount.core,
129
131
  };
130
132
  controlledAccount.core._cachedContent = undefined;
131
133
 
134
+ if (!controlledAccount.get("profile")) {
135
+ throw new Error("Must set account profile in initial migration");
136
+ }
137
+
132
138
  // we shouldn't need this, but it fixes account data not syncing for new accounts
133
139
  function syncAllCoValuesAfterCreateAccount() {
134
140
  for (const coValueEntry of Object.values(
135
- nodeWithAccount.coValues
141
+ nodeWithAccount.coValues,
136
142
  )) {
137
143
  if (coValueEntry.state === "loaded") {
138
144
  void nodeWithAccount.syncManager.syncCoValue(
139
- coValueEntry.coValue
145
+ coValueEntry.coValue,
140
146
  );
141
147
  }
142
148
  }
@@ -160,17 +166,20 @@ export class LocalNode {
160
166
  accountSecret,
161
167
  sessionID,
162
168
  peersToLoadFrom,
169
+ crypto,
163
170
  migration,
164
171
  }: {
165
172
  accountID: AccountID;
166
173
  accountSecret: AgentSecret;
167
- sessionID: SessionID;
174
+ sessionID: SessionID | undefined;
168
175
  peersToLoadFrom: Peer[];
176
+ crypto: CryptoProvider;
169
177
  migration?: RawAccountMigration<Meta>;
170
178
  }): Promise<LocalNode> {
171
179
  const loadingNode = new LocalNode(
172
- new ControlledAgent(accountSecret),
173
- newRandomSessionID(accountID)
180
+ new ControlledAgent(accountSecret, crypto),
181
+ newRandomSessionID(accountID),
182
+ crypto,
174
183
  );
175
184
 
176
185
  for (const peer of peersToLoadFrom) {
@@ -187,13 +196,13 @@ export class LocalNode {
187
196
 
188
197
  const controlledAccount = new RawControlledAccount(
189
198
  account.core,
190
- accountSecret
199
+ accountSecret,
191
200
  );
192
201
 
193
202
  // since this is all synchronous, we can just swap out nodes for the SyncManager
194
203
  const node = loadingNode.testWithDifferentAccount(
195
204
  controlledAccount,
196
- sessionID
205
+ sessionID || newRandomSessionID(accountID),
197
206
  );
198
207
  node.syncManager = loadingNode.syncManager;
199
208
  node.syncManager.local = node;
@@ -218,12 +227,11 @@ export class LocalNode {
218
227
  if (migration) {
219
228
  await migration(
220
229
  controlledAccount as RawControlledAccount<Meta>,
221
- profile,
222
- node
230
+ node,
223
231
  );
224
232
  node.account = new RawControlledAccount(
225
233
  controlledAccount.core,
226
- controlledAccount.agentSecret
234
+ controlledAccount.agentSecret,
227
235
  );
228
236
  }
229
237
 
@@ -247,14 +255,14 @@ export class LocalNode {
247
255
  dontLoadFrom?: PeerID;
248
256
  dontWaitFor?: PeerID;
249
257
  onProgress?: (progress: number) => void;
250
- } = {}
258
+ } = {},
251
259
  ): Promise<CoValueCore | "unavailable"> {
252
260
  let entry = this.coValues[id];
253
261
  if (!entry) {
254
262
  const peersToWaitFor = new Set(
255
263
  Object.values(this.syncManager.peers)
256
264
  .filter((peer) => peer.role === "server")
257
- .map((peer) => peer.id)
265
+ .map((peer) => peer.id),
258
266
  );
259
267
  if (options.dontWaitFor) peersToWaitFor.delete(options.dontWaitFor);
260
268
  entry = newLoadingState(peersToWaitFor, options.onProgress);
@@ -268,7 +276,7 @@ export class LocalNode {
268
276
  "Error loading from peers",
269
277
  id,
270
278
 
271
- e
279
+ e,
272
280
  );
273
281
  });
274
282
  }
@@ -287,7 +295,7 @@ export class LocalNode {
287
295
  */
288
296
  async load<T extends RawCoValue>(
289
297
  id: CoID<T>,
290
- onProgress?: (progress: number) => void
298
+ onProgress?: (progress: number) => void,
291
299
  ): Promise<T | "unavailable"> {
292
300
  const core = await this.loadCoValueCore(id, { onProgress });
293
301
 
@@ -312,7 +320,7 @@ export class LocalNode {
312
320
  /** @category 3. Low-level */
313
321
  subscribe<T extends RawCoValue>(
314
322
  id: CoID<T>,
315
- callback: (update: T | "unavailable") => void
323
+ callback: (update: T | "unavailable") => void,
316
324
  ): () => void {
317
325
  let stopped = false;
318
326
  let unsubscribe!: () => void;
@@ -344,20 +352,20 @@ export class LocalNode {
344
352
  /** @deprecated Use Account.acceptInvite instead */
345
353
  async acceptInvite<T extends RawCoValue>(
346
354
  groupOrOwnedValueID: CoID<T>,
347
- inviteSecret: InviteSecret
355
+ inviteSecret: InviteSecret,
348
356
  ): Promise<void> {
349
357
  const groupOrOwnedValue = await this.load(groupOrOwnedValueID);
350
358
 
351
359
  if (groupOrOwnedValue === "unavailable") {
352
360
  throw new Error(
353
- "Trying to accept invite: Group/owned value unavailable from all peers"
361
+ "Trying to accept invite: Group/owned value unavailable from all peers",
354
362
  );
355
363
  }
356
364
 
357
365
  if (groupOrOwnedValue.core.header.ruleset.type === "ownedByGroup") {
358
366
  return this.acceptInvite(
359
367
  groupOrOwnedValue.core.header.ruleset.group as CoID<RawGroup>,
360
- inviteSecret
368
+ inviteSecret,
361
369
  );
362
370
  } else if (groupOrOwnedValue.core.header.ruleset.type !== "group") {
363
371
  throw new Error("Can only accept invites to groups");
@@ -365,10 +373,10 @@ export class LocalNode {
365
373
 
366
374
  const group = expectGroup(groupOrOwnedValue);
367
375
 
368
- const inviteAgentSecret = agentSecretFromSecretSeed(
369
- secretSeedFromInviteSecret(inviteSecret)
376
+ const inviteAgentSecret = this.crypto.agentSecretFromSecretSeed(
377
+ secretSeedFromInviteSecret(inviteSecret),
370
378
  );
371
- const inviteAgentID = getAgentID(inviteAgentSecret);
379
+ const inviteAgentID = this.crypto.getAgentID(inviteAgentSecret);
372
380
 
373
381
  const inviteRole = await new Promise((resolve, reject) => {
374
382
  group.subscribe((groupUpdate) => {
@@ -379,7 +387,7 @@ export class LocalNode {
379
387
  });
380
388
  setTimeout(
381
389
  () => reject(new Error("Couldn't find invite before timeout")),
382
- 2000
390
+ 2000,
383
391
  );
384
392
  });
385
393
 
@@ -396,7 +404,7 @@ export class LocalNode {
396
404
  (existingRole === "reader" && inviteRole === "readerInvite")
397
405
  ) {
398
406
  console.debug(
399
- "Not accepting invite that would replace or downgrade role"
407
+ "Not accepting invite that would replace or downgrade role",
400
408
  );
401
409
  return;
402
410
  }
@@ -404,10 +412,10 @@ export class LocalNode {
404
412
  const groupAsInvite = expectGroup(
405
413
  group.core
406
414
  .testWithDifferentAccount(
407
- new ControlledAgent(inviteAgentSecret),
408
- newRandomSessionID(inviteAgentID)
415
+ new ControlledAgent(inviteAgentSecret, this.crypto),
416
+ newRandomSessionID(inviteAgentID),
409
417
  )
410
- .getCurrentContent()
418
+ .getCurrentContent(),
411
419
  );
412
420
 
413
421
  groupAsInvite.addMemberInternal(
@@ -415,8 +423,8 @@ export class LocalNode {
415
423
  inviteRole === "adminInvite"
416
424
  ? "admin"
417
425
  : inviteRole === "writerInvite"
418
- ? "writer"
419
- : "reader"
426
+ ? "writer"
427
+ : "reader",
420
428
  );
421
429
 
422
430
  group.core._sessionLogs = groupAsInvite.core.sessionLogs;
@@ -432,14 +440,14 @@ export class LocalNode {
432
440
  const entry = this.coValues[id];
433
441
  if (!entry) {
434
442
  throw new Error(
435
- `${expectation ? expectation + ": " : ""}Unknown CoValue ${id}`
443
+ `${expectation ? expectation + ": " : ""}Unknown CoValue ${id}`,
436
444
  );
437
445
  }
438
446
  if (entry.state === "loading") {
439
447
  throw new Error(
440
448
  `${
441
449
  expectation ? expectation + ": " : ""
442
- }CoValue ${id} not yet loaded`
450
+ }CoValue ${id} not yet loaded`,
443
451
  );
444
452
  }
445
453
  return entry.coValue;
@@ -449,44 +457,45 @@ export class LocalNode {
449
457
  expectProfileLoaded(id: AccountID, expectation?: string): RawProfile {
450
458
  const account = this.expectCoValueLoaded(id, expectation);
451
459
  const profileID = expectGroup(account.getCurrentContent()).get(
452
- "profile"
460
+ "profile",
453
461
  );
454
462
  if (!profileID) {
455
463
  throw new Error(
456
464
  `${
457
465
  expectation ? expectation + ": " : ""
458
- }Account ${id} has no profile`
466
+ }Account ${id} has no profile`,
459
467
  );
460
468
  }
461
469
  return this.expectCoValueLoaded(
462
470
  profileID,
463
- expectation
471
+ expectation,
464
472
  ).getCurrentContent() as RawProfile;
465
473
  }
466
474
 
467
475
  /** @internal */
468
476
  createAccount(
469
- name: string,
470
- agentSecret = newRandomAgentSecret()
477
+ agentSecret = this.crypto.newRandomAgentSecret(),
471
478
  ): RawControlledAccount {
472
- const accountAgentID = getAgentID(agentSecret);
473
- let account = expectGroup(
474
- this.createCoValue(accountHeaderForInitialAgentSecret(agentSecret))
479
+ const accountAgentID = this.crypto.getAgentID(agentSecret);
480
+ const account = expectGroup(
481
+ this.createCoValue(
482
+ accountHeaderForInitialAgentSecret(agentSecret, this.crypto),
483
+ )
475
484
  .testWithDifferentAccount(
476
- new ControlledAgent(agentSecret),
477
- newRandomSessionID(accountAgentID)
485
+ new ControlledAgent(agentSecret, this.crypto),
486
+ newRandomSessionID(accountAgentID),
478
487
  )
479
- .getCurrentContent()
488
+ .getCurrentContent(),
480
489
  );
481
490
 
482
491
  account.set(accountAgentID, "admin", "trusting");
483
492
 
484
- const readKey = newRandomKeySecret();
493
+ const readKey = this.crypto.newRandomKeySecret();
485
494
 
486
- const sealed = seal({
495
+ const sealed = this.crypto.seal({
487
496
  message: readKey.secret,
488
- from: getAgentSealerSecret(agentSecret),
489
- to: getAgentSealerID(accountAgentID),
497
+ from: this.crypto.getAgentSealerSecret(agentSecret),
498
+ to: this.crypto.getAgentSealerID(accountAgentID),
490
499
  nOnceMaterial: {
491
500
  in: account.id,
492
501
  tx: account.core.nextTransactionID(),
@@ -497,34 +506,19 @@ export class LocalNode {
497
506
 
498
507
  account.set("readKey", readKey.id, "trusting");
499
508
 
500
- const profile = account.createMap<RawProfile>(
501
- { name },
502
- {
503
- type: "profile",
504
- },
505
- "trusting"
506
- );
507
-
508
- account.set("profile", profile.id, "trusting");
509
-
510
509
  const accountOnThisNode = this.expectCoValueLoaded(account.id);
511
510
 
512
511
  accountOnThisNode._sessionLogs = new Map(account.core.sessionLogs);
513
512
 
514
513
  accountOnThisNode._cachedContent = undefined;
515
514
 
516
- const profileOnThisNode = this.createCoValue(profile.core.header);
517
-
518
- profileOnThisNode._sessionLogs = new Map(profile.core.sessionLogs);
519
- profileOnThisNode._cachedContent = undefined;
520
-
521
515
  return new RawControlledAccount(accountOnThisNode, agentSecret);
522
516
  }
523
517
 
524
518
  /** @internal */
525
519
  resolveAccountAgent(
526
520
  id: AccountID | AgentID,
527
- expectation?: string
521
+ expectation?: string,
528
522
  ): AgentID {
529
523
  if (isAgentID(id)) {
530
524
  return id;
@@ -542,16 +536,16 @@ export class LocalNode {
542
536
  throw new Error(
543
537
  `${
544
538
  expectation ? expectation + ": " : ""
545
- }CoValue ${id} is not an account`
539
+ }CoValue ${id} is not an account`,
546
540
  );
547
541
  }
548
542
 
549
- return new RawAccount(coValue).currentAgentID();
543
+ return (coValue.getCurrentContent() as RawAccount).currentAgentID();
550
544
  }
551
545
 
552
546
  async resolveAccountAgentAsync(
553
547
  id: AccountID | AgentID,
554
- expectation?: string
548
+ expectation?: string,
555
549
  ): Promise<AgentID> {
556
550
  if (isAgentID(id)) {
557
551
  return id;
@@ -563,7 +557,7 @@ export class LocalNode {
563
557
  throw new Error(
564
558
  `${
565
559
  expectation ? expectation + ": " : ""
566
- }Account ${id} is unavailable from all peers`
560
+ }Account ${id} is unavailable from all peers`,
567
561
  );
568
562
  }
569
563
 
@@ -577,11 +571,11 @@ export class LocalNode {
577
571
  throw new Error(
578
572
  `${
579
573
  expectation ? expectation + ": " : ""
580
- }CoValue ${id} is not an account`
574
+ }CoValue ${id} is not an account`,
581
575
  );
582
576
  }
583
577
 
584
- return new RawAccount(coValue).currentAgentID();
578
+ return (coValue.getCurrentContent() as RawAccount).currentAgentID();
585
579
  }
586
580
 
587
581
  /**
@@ -592,18 +586,18 @@ export class LocalNode {
592
586
  type: "comap",
593
587
  ruleset: { type: "group", initialAdmin: this.account.id },
594
588
  meta: null,
595
- ...createdNowUnique(),
589
+ ...this.crypto.createdNowUnique(),
596
590
  });
597
591
 
598
- let group = expectGroup(groupCoValue.getCurrentContent());
592
+ const group = expectGroup(groupCoValue.getCurrentContent());
599
593
 
600
594
  group.set(this.account.id, "admin", "trusting");
601
595
 
602
- const readKey = newRandomKeySecret();
596
+ const readKey = this.crypto.newRandomKeySecret();
603
597
 
604
598
  group.set(
605
599
  `${readKey.id}_for_${this.account.id}`,
606
- seal({
600
+ this.crypto.seal({
607
601
  message: readKey.secret,
608
602
  from: this.account.currentSealerSecret(),
609
603
  to: this.account.currentSealerID(),
@@ -612,7 +606,7 @@ export class LocalNode {
612
606
  tx: groupCoValue.nextTransactionID(),
613
607
  },
614
608
  }),
615
- "trusting"
609
+ "trusting",
616
610
  );
617
611
 
618
612
  group.set("readKey", readKey.id, "trusting");
@@ -623,9 +617,9 @@ export class LocalNode {
623
617
  /** @internal */
624
618
  testWithDifferentAccount(
625
619
  account: ControlledAccountOrAgent,
626
- currentSessionID: SessionID
620
+ currentSessionID: SessionID,
627
621
  ): LocalNode {
628
- const newNode = new LocalNode(account, currentSessionID);
622
+ const newNode = new LocalNode(account, currentSessionID, this.crypto);
629
623
 
630
624
  const coValuesToCopy = Object.entries(this.coValues);
631
625
 
@@ -650,7 +644,7 @@ export class LocalNode {
650
644
  const newCoValue = new CoValueCore(
651
645
  entry.coValue.header,
652
646
  newNode,
653
- new Map(entry.coValue.sessionLogs)
647
+ new Map(entry.coValue.sessionLogs),
654
648
  );
655
649
 
656
650
  newNode.coValues[coValueID as RawCoID] = {
@@ -666,7 +660,7 @@ export class LocalNode {
666
660
  // To make sure that when we edit the account, we're modifying the correct sessions
667
661
  const accountInNode = new RawControlledAccount(
668
662
  newNode.expectCoValueLoaded(account.id),
669
- account.agentSecret
663
+ account.agentSecret,
670
664
  );
671
665
  if (accountInNode.core.node !== newNode) {
672
666
  throw new Error("Account's node is not the new node");
@@ -705,7 +699,7 @@ type CoValueState =
705
699
  /** @internal */
706
700
  export function newLoadingState(
707
701
  currentPeerIds: Set<PeerID>,
708
- onProgress?: (progress: number) => void
702
+ onProgress?: (progress: number) => void,
709
703
  ): CoValueState {
710
704
  let resolve: (coValue: CoValueCore | "unavailable") => void;
711
705
 
@@ -725,7 +719,7 @@ export function newLoadingState(
725
719
  resolve = r;
726
720
  });
727
721
  return [id, { type: "waiting", done, resolve: resolve! }];
728
- })
722
+ }),
729
723
  ),
730
724
  };
731
725
  }
package/src/media.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { RawCoMap } from './coValues/coMap.js'
2
- import { RawBinaryCoStream } from './coValues/coStream.js'
1
+ import { RawCoMap } from "./coValues/coMap.js";
2
+ import { RawBinaryCoStream } from "./coValues/coStream.js";
3
3
 
4
4
  export type ImageDefinition = RawCoMap<{
5
5
  originalSize: [number, number];
6
6
  placeholderDataURL?: string;
7
7
  [res: `${number}x${number}`]: RawBinaryCoStream["id"];
8
- }>;
8
+ }>;
@@ -1,7 +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 { KeyID } from "./crypto.js";
4
+ import { KeyID } from "./crypto/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";
@@ -25,7 +25,7 @@ export type Role =
25
25
  | "readerInvite";
26
26
 
27
27
  export function determineValidTransactions(
28
- coValue: CoValueCore
28
+ coValue: CoValueCore,
29
29
  ): { txID: TransactionID; tx: Transaction }[] {
30
30
  if (coValue.header.ruleset.type === "group") {
31
31
  const allTransactionsSorted = [
@@ -73,7 +73,7 @@ export function determineValidTransactions(
73
73
  continue;
74
74
  } else {
75
75
  console.warn(
76
- "Only admins can make private transactions in groups"
76
+ "Only admins can make private transactions in groups",
77
77
  );
78
78
  continue;
79
79
  }
@@ -92,8 +92,8 @@ export function determineValidTransactions(
92
92
  JSON.stringify(tx.changes, (k, v) =>
93
93
  k === "changes" || k === "encryptedChanges"
94
94
  ? v.slice(0, 20) + "..."
95
- : v
96
- )
95
+ : v,
96
+ ),
97
97
  );
98
98
  continue;
99
99
  }
@@ -173,7 +173,7 @@ export function determineValidTransactions(
173
173
  )
174
174
  ) {
175
175
  console.warn(
176
- "Everyone can only be set to reader, writer or revoked"
176
+ "Everyone can only be set to reader, writer or revoked",
177
177
  );
178
178
  continue;
179
179
  }
@@ -212,7 +212,7 @@ export function determineValidTransactions(
212
212
  }
213
213
  } else {
214
214
  console.warn(
215
- "Group transaction must be made by current admin or invite"
215
+ "Group transaction must be made by current admin or invite",
216
216
  );
217
217
  continue;
218
218
  }
@@ -230,9 +230,9 @@ export function determineValidTransactions(
230
230
  coValue.node
231
231
  .expectCoValueLoaded(
232
232
  coValue.header.ruleset.group,
233
- "Determining valid transaction in owned object but its group wasn't loaded"
233
+ "Determining valid transaction in owned object but its group wasn't loaded",
234
234
  )
235
- .getCurrentContent()
235
+ .getCurrentContent(),
236
236
  );
237
237
 
238
238
  if (groupContent.type !== "comap") {
@@ -264,7 +264,7 @@ export function determineValidTransactions(
264
264
  txID: { sessionID: sessionID, txIndex },
265
265
  tx,
266
266
  }));
267
- }
267
+ },
268
268
  );
269
269
  } else if (coValue.header.ruleset.type === "unsafeAllowAll") {
270
270
  return [...coValue.sessionLogs.entries()].flatMap(
@@ -273,28 +273,26 @@ export function determineValidTransactions(
273
273
  txID: { sessionID: sessionID, txIndex },
274
274
  tx,
275
275
  }));
276
- }
276
+ },
277
277
  );
278
278
  } else {
279
279
  throw new Error(
280
280
  "Unknown ruleset type " +
281
- (coValue.header.ruleset as { type: string }).type
281
+ (coValue.header.ruleset as { type: string }).type,
282
282
  );
283
283
  }
284
284
  }
285
285
 
286
- export function isKeyForKeyField(
287
- field: string
288
- ): field is `${KeyID}_for_${KeyID}` {
289
- return field.startsWith("key_") && field.includes("_for_key");
286
+ export function isKeyForKeyField(co: string): co is `${KeyID}_for_${KeyID}` {
287
+ return co.startsWith("key_") && co.includes("_for_key");
290
288
  }
291
289
 
292
290
  export function isKeyForAccountField(
293
- field: string
294
- ): field is `${KeyID}_for_${AccountID | AgentID}` {
291
+ co: string,
292
+ ): co is `${KeyID}_for_${AccountID | AgentID}` {
295
293
  return (
296
- (field.startsWith("key_") &&
297
- (field.includes("_for_sealer") || field.includes("_for_co"))) ||
298
- field.includes("_for_everyone")
294
+ (co.startsWith("key_") &&
295
+ (co.includes("_for_sealer") || co.includes("_for_co"))) ||
296
+ co.includes("_for_everyone")
299
297
  );
300
298
  }