cojson 0.7.35-guest-auth.5 → 0.7.35

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/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +3 -8
  3. package/dist/PeerState.js +58 -0
  4. package/dist/PeerState.js.map +1 -0
  5. package/dist/PriorityBasedMessageQueue.js +51 -0
  6. package/dist/PriorityBasedMessageQueue.js.map +1 -0
  7. package/dist/base64url.js.map +1 -1
  8. package/dist/coValue.js.map +1 -1
  9. package/dist/coValueCore.js +9 -0
  10. package/dist/coValueCore.js.map +1 -1
  11. package/dist/coValues/account.js +3 -2
  12. package/dist/coValues/account.js.map +1 -1
  13. package/dist/coValues/coList.js.map +1 -1
  14. package/dist/coValues/coMap.js.map +1 -1
  15. package/dist/coValues/coStream.js +14 -15
  16. package/dist/coValues/coStream.js.map +1 -1
  17. package/dist/coValues/group.js +8 -8
  18. package/dist/coValues/group.js.map +1 -1
  19. package/dist/coreToCoValue.js.map +1 -1
  20. package/dist/crypto/PureJSCrypto.js.map +1 -1
  21. package/dist/crypto/WasmCrypto.js.map +1 -1
  22. package/dist/crypto/crypto.js +0 -3
  23. package/dist/crypto/crypto.js.map +1 -1
  24. package/dist/index.js +4 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/jsonStringify.js.map +1 -1
  27. package/dist/localNode.js +9 -9
  28. package/dist/localNode.js.map +1 -1
  29. package/dist/permissions.js.map +1 -1
  30. package/dist/priority.js +31 -0
  31. package/dist/priority.js.map +1 -0
  32. package/dist/storage/FileSystem.js.map +1 -1
  33. package/dist/storage/chunksAndKnownStates.js +2 -0
  34. package/dist/storage/chunksAndKnownStates.js.map +1 -1
  35. package/dist/storage/index.js.map +1 -1
  36. package/dist/streamUtils.js.map +1 -1
  37. package/dist/sync.js +7 -18
  38. package/dist/sync.js.map +1 -1
  39. package/dist/tests/PeerState.test.js +80 -0
  40. package/dist/tests/PeerState.test.js.map +1 -0
  41. package/dist/tests/PriorityBasedMessageQueue.test.js +97 -0
  42. package/dist/tests/PriorityBasedMessageQueue.test.js.map +1 -0
  43. package/dist/tests/account.test.js +2 -1
  44. package/dist/tests/account.test.js.map +1 -1
  45. package/dist/tests/coMap.test.js.map +1 -1
  46. package/dist/tests/coStream.test.js +34 -1
  47. package/dist/tests/coStream.test.js.map +1 -1
  48. package/dist/tests/permissions.test.js +42 -41
  49. package/dist/tests/permissions.test.js.map +1 -1
  50. package/dist/tests/priority.test.js +61 -0
  51. package/dist/tests/priority.test.js.map +1 -0
  52. package/dist/tests/sync.test.js +328 -16
  53. package/dist/tests/sync.test.js.map +1 -1
  54. package/dist/tests/testUtils.js +2 -1
  55. package/dist/tests/testUtils.js.map +1 -1
  56. package/dist/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  57. package/dist/typeUtils/expectGroup.js.map +1 -1
  58. package/dist/typeUtils/isAccountID.js.map +1 -1
  59. package/package.json +3 -3
  60. package/src/PeerState.ts +74 -0
  61. package/src/PriorityBasedMessageQueue.ts +77 -0
  62. package/src/coValueCore.ts +18 -7
  63. package/src/coValues/account.ts +6 -5
  64. package/src/coValues/coList.ts +4 -4
  65. package/src/coValues/coMap.ts +3 -3
  66. package/src/coValues/coStream.ts +29 -26
  67. package/src/coValues/group.ts +11 -15
  68. package/src/crypto/crypto.ts +0 -5
  69. package/src/ids.ts +2 -2
  70. package/src/index.ts +7 -5
  71. package/src/localNode.ts +18 -18
  72. package/src/permissions.ts +5 -5
  73. package/src/priority.ts +39 -0
  74. package/src/storage/chunksAndKnownStates.ts +2 -0
  75. package/src/sync.ts +19 -34
  76. package/src/tests/PeerState.test.ts +92 -0
  77. package/src/tests/PriorityBasedMessageQueue.test.ts +111 -0
  78. package/src/tests/account.test.ts +2 -1
  79. package/src/tests/coStream.test.ts +58 -1
  80. package/src/tests/permissions.test.ts +42 -41
  81. package/src/tests/priority.test.ts +75 -0
  82. package/src/tests/sync.test.ts +491 -28
  83. package/src/tests/testUtils.ts +2 -1
  84. package/src/typeUtils/accountOrAgentIDfromSessionID.ts +3 -3
  85. package/src/typeUtils/isAccountID.ts +2 -2
@@ -7,7 +7,7 @@ import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfrom
7
7
  import { RawGroup } from "./group.js";
8
8
  import { AgentID, SessionID, TransactionID } from "../ids.js";
9
9
  import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
10
- import { RawAccountID } from "./account.js";
10
+ import { AccountID } from "./account.js";
11
11
 
12
12
  export type BinaryStreamInfo = {
13
13
  mimeType: string;
@@ -96,22 +96,27 @@ export class RawCoStreamView<
96
96
  }
97
97
 
98
98
  getSingleStream(): Item[] | undefined {
99
- if (Object.keys(this.items).length === 0) {
99
+ const streams = Object.values(this.items);
100
+ const firstStream = streams[0];
101
+
102
+ if (!firstStream) {
100
103
  return undefined;
101
- } else if (Object.keys(this.items).length !== 1) {
104
+ }
105
+
106
+ if (streams.length > 1) {
102
107
  throw new Error(
103
108
  "CoStream.getSingleStream() can only be called when there is exactly one stream",
104
109
  );
105
110
  }
106
111
 
107
- return Object.values(this.items)[0]?.map((item) => item.value);
112
+ return firstStream.map((item) => item.value);
108
113
  }
109
114
 
110
115
  sessions(): SessionID[] {
111
116
  return Object.keys(this.items) as SessionID[];
112
117
  }
113
118
 
114
- accounts(): Set<RawAccountID> {
119
+ accounts(): Set<AccountID> {
115
120
  return new Set(
116
121
  this.sessions()
117
122
  .map(accountOrAgentIDfromSessionID)
@@ -124,7 +129,7 @@ export class RawCoStreamView<
124
129
  n: number,
125
130
  ):
126
131
  | {
127
- by: RawAccountID | AgentID;
132
+ by: AccountID | AgentID;
128
133
  tx: TransactionID;
129
134
  at: Date;
130
135
  value: Item;
@@ -146,7 +151,7 @@ export class RawCoStreamView<
146
151
 
147
152
  lastItemIn(sessionID: SessionID):
148
153
  | {
149
- by: RawAccountID | AgentID;
154
+ by: AccountID | AgentID;
150
155
  tx: TransactionID;
151
156
  at: Date;
152
157
  value: Item;
@@ -170,9 +175,9 @@ export class RawCoStreamView<
170
175
  }
171
176
  }
172
177
 
173
- lastItemBy(account: RawAccountID | AgentID):
178
+ lastItemBy(account: AccountID | AgentID):
174
179
  | {
175
- by: RawAccountID | AgentID;
180
+ by: AccountID | AgentID;
176
181
  tx: TransactionID;
177
182
  at: Date;
178
183
  value: Item;
@@ -180,7 +185,7 @@ export class RawCoStreamView<
180
185
  | undefined {
181
186
  let latestItem:
182
187
  | {
183
- by: RawAccountID | AgentID;
188
+ by: AccountID | AgentID;
184
189
  tx: TransactionID;
185
190
  at: Date;
186
191
  value: Item;
@@ -205,7 +210,7 @@ export class RawCoStreamView<
205
210
  return latestItem;
206
211
  }
207
212
 
208
- *itemsBy(account: RawAccountID | AgentID) {
213
+ *itemsBy(account: AccountID | AgentID) {
209
214
  // TODO: this can be made more lazy without a huge collect and sort
210
215
  const items = [
211
216
  ...Object.keys(this.items).flatMap((sessionID) =>
@@ -264,14 +269,26 @@ export class RawBinaryCoStreamView<
264
269
  extends RawCoStreamView<BinaryStreamItem, Meta>
265
270
  implements RawCoValue
266
271
  {
272
+ isBinaryStreamEnded() {
273
+ const items = this.getSingleStream();
274
+
275
+ if (!items || items.length === 0) {
276
+ return false;
277
+ }
278
+
279
+ const lastItem = items[items.length - 1];
280
+
281
+ return lastItem?.type === "end";
282
+ }
283
+
267
284
  getBinaryChunks(
268
285
  allowUnfinished?: boolean,
269
286
  ):
270
287
  | (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
271
288
  | undefined {
272
- // const before = performance.now();
273
289
  const items = this.getSingleStream();
274
290
 
291
+ // No active streams
275
292
  if (!items) return;
276
293
 
277
294
  const start = items[0];
@@ -288,9 +305,6 @@ export class RawBinaryCoStreamView<
288
305
  const chunks: Uint8Array[] = [];
289
306
 
290
307
  let finished = false;
291
- // let totalLength = 0;
292
-
293
- let lastProgressUpdate = Date.now();
294
308
 
295
309
  for (const item of items.slice(1)) {
296
310
  if (item.type === "end") {
@@ -306,20 +320,9 @@ export class RawBinaryCoStreamView<
306
320
  const chunk = base64URLtoBytes(
307
321
  item.chunk.slice(binary_U_prefixLength),
308
322
  );
309
- // totalLength += chunk.length;
310
323
  chunks.push(chunk);
311
-
312
- if (Date.now() - lastProgressUpdate > 100) {
313
- lastProgressUpdate = Date.now();
314
- }
315
324
  }
316
325
 
317
- // const after = performance.now();
318
- // console.log(
319
- // "getBinaryChunks bandwidth in MB/s",
320
- // (1000 * totalLength) / (after - before) / (1024 * 1024)
321
- // );
322
-
323
326
  return {
324
327
  mimeType: start.mimeType,
325
328
  fileName: start.fileName,
@@ -5,10 +5,9 @@ import { JsonObject } from "../jsonValue.js";
5
5
  import { RawBinaryCoStream, RawCoStream } from "./coStream.js";
6
6
  import { Encrypted, KeyID, KeySecret, Sealed } from "../crypto/crypto.js";
7
7
  import { AgentID, isAgentID } from "../ids.js";
8
- import { RawAccount, RawAccountID, ControlledAccountOrAgent } from "./account.js";
8
+ import { RawAccount, AccountID, ControlledAccountOrAgent } from "./account.js";
9
9
  import { Role } from "../permissions.js";
10
10
  import { base58 } from "@scure/base";
11
- import { CoValueUniqueness } from "../coValueCore.js";
12
11
 
13
12
  export const EVERYONE = "everyone" as const;
14
13
  export type Everyone = "everyone";
@@ -16,10 +15,10 @@ export type Everyone = "everyone";
16
15
  export type GroupShape = {
17
16
  profile: CoID<RawCoMap> | null;
18
17
  root: CoID<RawCoMap> | null;
19
- [key: RawAccountID | AgentID]: Role;
18
+ [key: AccountID | AgentID]: Role;
20
19
  [EVERYONE]?: Role;
21
20
  readKey?: KeyID;
22
- [revelationFor: `${KeyID}_for_${RawAccountID | AgentID}`]: Sealed<KeySecret>;
21
+ [revelationFor: `${KeyID}_for_${AccountID | AgentID}`]: Sealed<KeySecret>;
23
22
  [revelationFor: `${KeyID}_for_${Everyone}`]: KeySecret;
24
23
  [oldKeyForNewKey: `${KeyID}_for_${KeyID}`]: Encrypted<
25
24
  KeySecret,
@@ -56,12 +55,12 @@ export class RawGroup<
56
55
  *
57
56
  * @category 1. Role reading
58
57
  */
59
- roleOf(accountID: RawAccountID): Role | undefined {
58
+ roleOf(accountID: AccountID): Role | undefined {
60
59
  return this.roleOfInternal(accountID);
61
60
  }
62
61
 
63
62
  /** @internal */
64
- roleOfInternal(accountID: RawAccountID | AgentID): Role | undefined {
63
+ roleOfInternal(accountID: AccountID | AgentID): Role | undefined {
65
64
  return this.get(accountID);
66
65
  }
67
66
 
@@ -157,7 +156,7 @@ export class RawGroup<
157
156
  } else {
158
157
  return false;
159
158
  }
160
- }) as (RawAccountID | AgentID)[];
159
+ }) as (AccountID | AgentID)[];
161
160
 
162
161
  const maybeCurrentReadKey = this.core.getCurrentReadKey();
163
162
 
@@ -256,7 +255,6 @@ export class RawGroup<
256
255
  init?: M["_shape"],
257
256
  meta?: M["headerMeta"],
258
257
  initPrivacy: "trusting" | "private" = "private",
259
- uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
260
258
  ): M {
261
259
  const map = this.core.node
262
260
  .createCoValue({
@@ -266,7 +264,7 @@ export class RawGroup<
266
264
  group: this.id,
267
265
  },
268
266
  meta: meta || null,
269
- ...uniqueness
267
+ ...this.core.crypto.createdNowUnique(),
270
268
  })
271
269
  .getCurrentContent() as M;
272
270
 
@@ -289,7 +287,6 @@ export class RawGroup<
289
287
  init?: L["_item"][],
290
288
  meta?: L["headerMeta"],
291
289
  initPrivacy: "trusting" | "private" = "private",
292
- uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
293
290
  ): L {
294
291
  const list = this.core.node
295
292
  .createCoValue({
@@ -299,7 +296,7 @@ export class RawGroup<
299
296
  group: this.id,
300
297
  },
301
298
  meta: meta || null,
302
- ...uniqueness
299
+ ...this.core.crypto.createdNowUnique(),
303
300
  })
304
301
  .getCurrentContent() as L;
305
302
 
@@ -313,7 +310,7 @@ export class RawGroup<
313
310
  }
314
311
 
315
312
  /** @category 3. Value creation */
316
- createStream<C extends RawCoStream>(meta?: C["headerMeta"], uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()): C {
313
+ createStream<C extends RawCoStream>(meta?: C["headerMeta"]): C {
317
314
  return this.core.node
318
315
  .createCoValue({
319
316
  type: "costream",
@@ -322,7 +319,7 @@ export class RawGroup<
322
319
  group: this.id,
323
320
  },
324
321
  meta: meta || null,
325
- ...uniqueness
322
+ ...this.core.crypto.createdNowUnique(),
326
323
  })
327
324
  .getCurrentContent() as C;
328
325
  }
@@ -330,7 +327,6 @@ export class RawGroup<
330
327
  /** @category 3. Value creation */
331
328
  createBinaryStream<C extends RawBinaryCoStream>(
332
329
  meta: C["headerMeta"] = { type: "binary" },
333
- uniqueness: CoValueUniqueness = this.core.crypto.createdNowUnique()
334
330
  ): C {
335
331
  return this.core.node
336
332
  .createCoValue({
@@ -340,7 +336,7 @@ export class RawGroup<
340
336
  group: this.id,
341
337
  },
342
338
  meta: meta,
343
- ...uniqueness
339
+ ...this.core.crypto.createdNowUnique(),
344
340
  })
345
341
  .getCurrentContent() as C;
346
342
  }
@@ -2,7 +2,6 @@ import { JsonValue } from "../jsonValue.js";
2
2
  import { base58 } from "@scure/base";
3
3
  import { AgentID, RawCoID, TransactionID } from "../ids.js";
4
4
  import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
5
- import { RawAccountID, SessionID } from "../index.js";
6
5
 
7
6
  export type SignerSecret = `signerSecret_z${string}`;
8
7
  export type SignerID = `signer_z${string}`;
@@ -291,10 +290,6 @@ export abstract class CryptoProvider<Blake3State = any> {
291
290
  }),
292
291
  )}`;
293
292
  }
294
-
295
- newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
296
- return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
297
- }
298
293
  }
299
294
 
300
295
  export type Hash = `hash_z${string}`;
package/src/ids.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RawAccountID } from "./coValues/account.js";
1
+ import { AccountID } from "./coValues/account.js";
2
2
  import { base58 } from "@scure/base";
3
3
  import { shortHashLength } from "./crypto/crypto.js";
4
4
 
@@ -28,4 +28,4 @@ export function isAgentID(id: string): id is AgentID {
28
28
  );
29
29
  }
30
30
 
31
- export type SessionID = `${RawAccountID | AgentID}_session_z${string}`;
31
+ export type SessionID = `${AccountID | AgentID}_session_z${string}`;
package/src/index.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  CoValueCore,
3
- type CoValueUniqueness,
3
+ newRandomSessionID,
4
4
  MAX_RECOMMENDED_TX_SIZE,
5
5
  idforHeader,
6
6
  } from "./coValueCore.js";
7
7
  import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
8
8
  import { LocalNode } from "./localNode.js";
9
- import type { RawCoValue } from "./coValue.js";
9
+ import { type RawCoValue } from "./coValue.js";
10
10
  import { RawCoMap } from "./coValues/coMap.js";
11
11
  import { RawCoList } from "./coValues/coList.js";
12
12
  import { RawCoStream, RawBinaryCoStream } from "./coValues/coStream.js";
@@ -50,7 +50,7 @@ import type {
50
50
  import { DisconnectedError, PingTimeoutError } from "./sync.js";
51
51
  import type { AgentSecret } from "./crypto/crypto.js";
52
52
  import type {
53
- RawAccountID,
53
+ AccountID,
54
54
  AccountMeta,
55
55
  RawAccountMigration,
56
56
  } from "./coValues/account.js";
@@ -61,9 +61,11 @@ type Value = JsonValue | AnyRawCoValue;
61
61
 
62
62
  import { LSMStorage, BlockFilename, WalFilename } from "./storage/index.js";
63
63
  import { FileSystem } from "./storage/FileSystem.js";
64
+ import { getPriorityFromHeader } from "./priority.js";
64
65
 
65
66
  /** @hidden */
66
67
  export const cojsonInternals = {
68
+ newRandomSessionID,
67
69
  connectedPeers,
68
70
  rawCoIDtoBytes,
69
71
  rawCoIDfromBytes,
@@ -79,6 +81,7 @@ export const cojsonInternals = {
79
81
  idforHeader,
80
82
  StreamingHash,
81
83
  Channel,
84
+ getPriorityFromHeader,
82
85
  };
83
86
 
84
87
  export {
@@ -95,7 +98,7 @@ export {
95
98
  CoID,
96
99
  AnyRawCoValue,
97
100
  RawAccount,
98
- RawAccountID,
101
+ AccountID,
99
102
  AccountMeta,
100
103
  RawAccountMigration,
101
104
  RawProfile as Profile,
@@ -129,7 +132,6 @@ export type {
129
132
  OutgoingSyncQueue,
130
133
  DisconnectedError,
131
134
  PingTimeoutError,
132
- CoValueUniqueness
133
135
  };
134
136
 
135
137
  // eslint-disable-next-line @typescript-eslint/no-namespace
package/src/localNode.ts CHANGED
@@ -2,7 +2,7 @@ import { AgentSecret, CryptoProvider } from "./crypto/crypto.js";
2
2
  import {
3
3
  CoValueCore,
4
4
  CoValueHeader,
5
- CoValueUniqueness,
5
+ newRandomSessionID,
6
6
  } from "./coValueCore.js";
7
7
  import {
8
8
  InviteSecret,
@@ -19,7 +19,7 @@ import {
19
19
  ControlledAccountOrAgent,
20
20
  RawControlledAccount,
21
21
  ControlledAgent,
22
- RawAccountID,
22
+ AccountID,
23
23
  RawProfile,
24
24
  RawAccountMigration,
25
25
  InvalidAccountAgentIDError,
@@ -81,14 +81,14 @@ export class LocalNode {
81
81
  initialAgentSecret?: AgentSecret;
82
82
  }): Promise<{
83
83
  node: LocalNode;
84
- accountID: RawAccountID;
84
+ accountID: AccountID;
85
85
  accountSecret: AgentSecret;
86
86
  sessionID: SessionID;
87
87
  }> {
88
88
  const throwawayAgent = crypto.newRandomAgentSecret();
89
89
  const setupNode = new LocalNode(
90
90
  new ControlledAgent(throwawayAgent, crypto),
91
- crypto.newRandomSessionID(crypto.getAgentID(throwawayAgent)),
91
+ newRandomSessionID(crypto.getAgentID(throwawayAgent)),
92
92
  crypto,
93
93
  );
94
94
 
@@ -96,7 +96,7 @@ export class LocalNode {
96
96
 
97
97
  const nodeWithAccount = account.core.node.testWithDifferentAccount(
98
98
  account,
99
- crypto.newRandomSessionID(account.id),
99
+ newRandomSessionID(account.id),
100
100
  );
101
101
 
102
102
  const accountOnNodeWithAccount =
@@ -173,7 +173,7 @@ export class LocalNode {
173
173
  crypto,
174
174
  migration,
175
175
  }: {
176
- accountID: RawAccountID;
176
+ accountID: AccountID;
177
177
  accountSecret: AgentSecret;
178
178
  sessionID: SessionID | undefined;
179
179
  peersToLoadFrom: Peer[];
@@ -182,7 +182,7 @@ export class LocalNode {
182
182
  }): Promise<LocalNode> {
183
183
  const loadingNode = new LocalNode(
184
184
  new ControlledAgent(accountSecret, crypto),
185
- crypto.newRandomSessionID(accountID),
185
+ newRandomSessionID(accountID),
186
186
  crypto,
187
187
  );
188
188
 
@@ -206,7 +206,7 @@ export class LocalNode {
206
206
  // since this is all synchronous, we can just swap out nodes for the SyncManager
207
207
  const node = loadingNode.testWithDifferentAccount(
208
208
  controlledAccount,
209
- sessionID || crypto.newRandomSessionID(accountID),
209
+ sessionID || newRandomSessionID(accountID),
210
210
  );
211
211
  node.syncManager = loadingNode.syncManager;
212
212
  node.syncManager.local = node;
@@ -429,7 +429,7 @@ export class LocalNode {
429
429
  group.core
430
430
  .testWithDifferentAccount(
431
431
  new ControlledAgent(inviteAgentSecret, this.crypto),
432
- this.crypto.newRandomSessionID(inviteAgentID),
432
+ newRandomSessionID(inviteAgentID),
433
433
  )
434
434
  .getCurrentContent(),
435
435
  );
@@ -470,7 +470,7 @@ export class LocalNode {
470
470
  }
471
471
 
472
472
  /** @internal */
473
- expectProfileLoaded(id: RawAccountID, expectation?: string): RawProfile {
473
+ expectProfileLoaded(id: AccountID, expectation?: string): RawProfile {
474
474
  const account = this.expectCoValueLoaded(id, expectation);
475
475
  const profileID = expectGroup(account.getCurrentContent()).get(
476
476
  "profile",
@@ -499,7 +499,7 @@ export class LocalNode {
499
499
  )
500
500
  .testWithDifferentAccount(
501
501
  new ControlledAgent(agentSecret, this.crypto),
502
- this.crypto.newRandomSessionID(accountAgentID),
502
+ newRandomSessionID(accountAgentID),
503
503
  )
504
504
  .getCurrentContent(),
505
505
  );
@@ -533,7 +533,7 @@ export class LocalNode {
533
533
 
534
534
  /** @internal */
535
535
  resolveAccountAgent(
536
- id: RawAccountID | AgentID,
536
+ id: AccountID | AgentID,
537
537
  expectation?: string,
538
538
  ): Result<AgentID, ResolveAccountAgentError> {
539
539
  if (isAgentID(id)) {
@@ -560,7 +560,7 @@ export class LocalNode {
560
560
  }
561
561
 
562
562
  resolveAccountAgentAsync(
563
- id: RawAccountID | AgentID,
563
+ id: AccountID | AgentID,
564
564
  expectation?: string,
565
565
  ): ResultAsync<AgentID, ResolveAccountAgentError> {
566
566
  if (isAgentID(id)) {
@@ -606,12 +606,12 @@ export class LocalNode {
606
606
  /**
607
607
  * @deprecated use Account.createGroup() instead
608
608
  */
609
- createGroup(uniqueness: CoValueUniqueness = this.crypto.createdNowUnique()): RawGroup {
609
+ createGroup(): RawGroup {
610
610
  const groupCoValue = this.createCoValue({
611
611
  type: "comap",
612
612
  ruleset: { type: "group", initialAdmin: this.account.id },
613
613
  meta: null,
614
- ...uniqueness
614
+ ...this.crypto.createdNowUnique(),
615
615
  });
616
616
 
617
617
  const group = expectGroup(groupCoValue.getCurrentContent());
@@ -731,19 +731,19 @@ export type LoadCoValueCoreError = {
731
731
  type: "ErrorLoadingCoValueCore";
732
732
  error: unknown;
733
733
  expectation?: string;
734
- id: RawAccountID;
734
+ id: AccountID;
735
735
  };
736
736
 
737
737
  export type AccountUnavailableFromAllPeersError = {
738
738
  type: "AccountUnavailableFromAllPeers";
739
739
  expectation?: string;
740
- id: RawAccountID;
740
+ id: AccountID;
741
741
  };
742
742
 
743
743
  export type UnexpectedlyNotAccountError = {
744
744
  type: "UnexpectedlyNotAccount";
745
745
  expectation?: string;
746
- id: RawAccountID;
746
+ id: AccountID;
747
747
  };
748
748
 
749
749
  export type ResolveAccountAgentError =
@@ -5,13 +5,13 @@ 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";
8
- import { RawAccount, RawAccountID, RawProfile } 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";
12
12
 
13
13
  export type PermissionsDef =
14
- | { type: "group"; initialAdmin: RawAccountID | AgentID }
14
+ | { type: "group"; initialAdmin: AccountID | AgentID }
15
15
  | { type: "ownedByGroup"; group: RawCoID }
16
16
  | { type: "unsafeAllowAll" };
17
17
 
@@ -53,7 +53,7 @@ export function determineValidTransactions(
53
53
  }
54
54
 
55
55
  const memberState: {
56
- [agent: RawAccountID | AgentID]: Role;
56
+ [agent: AccountID | AgentID]: Role;
57
57
  [EVERYONE]?: Role;
58
58
  } = {};
59
59
 
@@ -99,7 +99,7 @@ export function determineValidTransactions(
99
99
  }
100
100
 
101
101
  const change = changes[0] as
102
- | MapOpPayload<RawAccountID | AgentID | Everyone, Role>
102
+ | MapOpPayload<AccountID | AgentID | Everyone, Role>
103
103
  | MapOpPayload<"readKey", JsonValue>
104
104
  | MapOpPayload<"profile", CoID<RawProfile>>;
105
105
  if (changes.length !== 1) {
@@ -303,7 +303,7 @@ export function isKeyForKeyField(co: string): co is `${KeyID}_for_${KeyID}` {
303
303
 
304
304
  export function isKeyForAccountField(
305
305
  co: string,
306
- ): co is `${KeyID}_for_${RawAccountID | AgentID}` {
306
+ ): co is `${KeyID}_for_${AccountID | AgentID}` {
307
307
  return (
308
308
  (co.startsWith("key_") &&
309
309
  (co.includes("_for_sealer") || co.includes("_for_co"))) ||
@@ -0,0 +1,39 @@
1
+ import { type CoValueHeader } from "./coValueCore.js";
2
+
3
+ /**
4
+ * The priority of a `CoValue` determines how much priority is given
5
+ * to its content messages.
6
+ *
7
+ * The priority value is handled as weight in the weighed round robin algorithm
8
+ * used to determine the order in which messages are sent.
9
+ *
10
+ * Follows the HTTP urgency range and order:
11
+ * - https://www.rfc-editor.org/rfc/rfc9218.html#name-urgency
12
+ */
13
+ export const CO_VALUE_PRIORITY = {
14
+ HIGH: 0,
15
+ MEDIUM: 3,
16
+ LOW: 6,
17
+ } as const;
18
+
19
+ export type CoValuePriority = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
20
+
21
+ export function getPriorityFromHeader(header: CoValueHeader | undefined | boolean): CoValuePriority {
22
+ if (typeof header === "boolean" || !header) {
23
+ return CO_VALUE_PRIORITY.MEDIUM;
24
+ }
25
+
26
+ if (header.meta?.type === "account") {
27
+ return CO_VALUE_PRIORITY.HIGH;
28
+ }
29
+
30
+ if (header.ruleset.type === "group") {
31
+ return CO_VALUE_PRIORITY.HIGH;
32
+ }
33
+
34
+ if (header.type === "costream" && header.meta?.type === "binary") {
35
+ return CO_VALUE_PRIORITY.LOW;
36
+ }
37
+
38
+ return CO_VALUE_PRIORITY.MEDIUM;
39
+ }
@@ -1,5 +1,6 @@
1
1
  import { RawCoID, SessionID } from "../ids.js";
2
2
  import { MAX_RECOMMENDED_TX_SIZE } from "../index.js";
3
+ import { getPriorityFromHeader } from "../priority.js";
3
4
  import { CoValueKnownState, NewContentMessage } from "../sync.js";
4
5
  import { CoValueChunk } from "./index.js";
5
6
 
@@ -15,6 +16,7 @@ export function contentSinceChunk(
15
16
  action: "content",
16
17
  header: known?.header ? undefined : chunk.header,
17
18
  new: {},
19
+ priority: getPriorityFromHeader(chunk.header),
18
20
  });
19
21
 
20
22
  for (const [sessionID, sessionsEntry] of Object.entries(