cojson 0.8.12 → 0.8.17

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 (164) hide show
  1. package/CHANGELOG.md +95 -83
  2. package/dist/native/PeerKnownStates.js +6 -1
  3. package/dist/native/PeerKnownStates.js.map +1 -1
  4. package/dist/native/PeerState.js +4 -3
  5. package/dist/native/PeerState.js.map +1 -1
  6. package/dist/native/PriorityBasedMessageQueue.js +1 -10
  7. package/dist/native/PriorityBasedMessageQueue.js.map +1 -1
  8. package/dist/native/SyncStateSubscriptionManager.js +70 -0
  9. package/dist/native/SyncStateSubscriptionManager.js.map +1 -0
  10. package/dist/native/base64url.js.map +1 -1
  11. package/dist/native/base64url.test.js +1 -1
  12. package/dist/native/base64url.test.js.map +1 -1
  13. package/dist/native/coValue.js.map +1 -1
  14. package/dist/native/coValueCore.js +141 -149
  15. package/dist/native/coValueCore.js.map +1 -1
  16. package/dist/native/coValueState.js.map +1 -1
  17. package/dist/native/coValues/account.js +6 -6
  18. package/dist/native/coValues/account.js.map +1 -1
  19. package/dist/native/coValues/coList.js +2 -3
  20. package/dist/native/coValues/coList.js.map +1 -1
  21. package/dist/native/coValues/coMap.js +1 -1
  22. package/dist/native/coValues/coMap.js.map +1 -1
  23. package/dist/native/coValues/coStream.js +3 -5
  24. package/dist/native/coValues/coStream.js.map +1 -1
  25. package/dist/native/coValues/group.js +11 -11
  26. package/dist/native/coValues/group.js.map +1 -1
  27. package/dist/native/coreToCoValue.js +2 -2
  28. package/dist/native/coreToCoValue.js.map +1 -1
  29. package/dist/native/crypto/PureJSCrypto.js +4 -4
  30. package/dist/native/crypto/PureJSCrypto.js.map +1 -1
  31. package/dist/native/crypto/crypto.js.map +1 -1
  32. package/dist/native/exports.js +12 -12
  33. package/dist/native/exports.js.map +1 -1
  34. package/dist/native/ids.js.map +1 -1
  35. package/dist/native/jsonStringify.js.map +1 -1
  36. package/dist/native/localNode.js +5 -7
  37. package/dist/native/localNode.js.map +1 -1
  38. package/dist/native/permissions.js +4 -7
  39. package/dist/native/permissions.js.map +1 -1
  40. package/dist/native/priority.js.map +1 -1
  41. package/dist/native/storage/FileSystem.js.map +1 -1
  42. package/dist/native/storage/chunksAndKnownStates.js +2 -4
  43. package/dist/native/storage/chunksAndKnownStates.js.map +1 -1
  44. package/dist/native/storage/index.js +6 -15
  45. package/dist/native/storage/index.js.map +1 -1
  46. package/dist/native/streamUtils.js.map +1 -1
  47. package/dist/native/sync.js +57 -7
  48. package/dist/native/sync.js.map +1 -1
  49. package/dist/native/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  50. package/dist/native/typeUtils/expectGroup.js.map +1 -1
  51. package/dist/native/typeUtils/isAccountID.js.map +1 -1
  52. package/dist/native/typeUtils/isCoValue.js +1 -1
  53. package/dist/native/typeUtils/isCoValue.js.map +1 -1
  54. package/dist/web/PeerKnownStates.js +6 -1
  55. package/dist/web/PeerKnownStates.js.map +1 -1
  56. package/dist/web/PeerState.js +4 -3
  57. package/dist/web/PeerState.js.map +1 -1
  58. package/dist/web/PriorityBasedMessageQueue.js +1 -10
  59. package/dist/web/PriorityBasedMessageQueue.js.map +1 -1
  60. package/dist/web/SyncStateSubscriptionManager.js +70 -0
  61. package/dist/web/SyncStateSubscriptionManager.js.map +1 -0
  62. package/dist/web/base64url.js.map +1 -1
  63. package/dist/web/base64url.test.js +1 -1
  64. package/dist/web/base64url.test.js.map +1 -1
  65. package/dist/web/coValue.js.map +1 -1
  66. package/dist/web/coValueCore.js +141 -149
  67. package/dist/web/coValueCore.js.map +1 -1
  68. package/dist/web/coValueState.js.map +1 -1
  69. package/dist/web/coValues/account.js +6 -6
  70. package/dist/web/coValues/account.js.map +1 -1
  71. package/dist/web/coValues/coList.js +2 -3
  72. package/dist/web/coValues/coList.js.map +1 -1
  73. package/dist/web/coValues/coMap.js +1 -1
  74. package/dist/web/coValues/coMap.js.map +1 -1
  75. package/dist/web/coValues/coStream.js +3 -5
  76. package/dist/web/coValues/coStream.js.map +1 -1
  77. package/dist/web/coValues/group.js +11 -11
  78. package/dist/web/coValues/group.js.map +1 -1
  79. package/dist/web/coreToCoValue.js +2 -2
  80. package/dist/web/coreToCoValue.js.map +1 -1
  81. package/dist/web/crypto/PureJSCrypto.js +4 -4
  82. package/dist/web/crypto/PureJSCrypto.js.map +1 -1
  83. package/dist/web/crypto/WasmCrypto.js +5 -5
  84. package/dist/web/crypto/WasmCrypto.js.map +1 -1
  85. package/dist/web/crypto/crypto.js.map +1 -1
  86. package/dist/web/exports.js +12 -12
  87. package/dist/web/exports.js.map +1 -1
  88. package/dist/web/ids.js.map +1 -1
  89. package/dist/web/jsonStringify.js.map +1 -1
  90. package/dist/web/localNode.js +5 -7
  91. package/dist/web/localNode.js.map +1 -1
  92. package/dist/web/permissions.js +4 -7
  93. package/dist/web/permissions.js.map +1 -1
  94. package/dist/web/priority.js.map +1 -1
  95. package/dist/web/storage/FileSystem.js.map +1 -1
  96. package/dist/web/storage/chunksAndKnownStates.js +2 -4
  97. package/dist/web/storage/chunksAndKnownStates.js.map +1 -1
  98. package/dist/web/storage/index.js +6 -15
  99. package/dist/web/storage/index.js.map +1 -1
  100. package/dist/web/streamUtils.js.map +1 -1
  101. package/dist/web/sync.js +57 -7
  102. package/dist/web/sync.js.map +1 -1
  103. package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  104. package/dist/web/typeUtils/expectGroup.js.map +1 -1
  105. package/dist/web/typeUtils/isAccountID.js.map +1 -1
  106. package/dist/web/typeUtils/isCoValue.js +1 -1
  107. package/dist/web/typeUtils/isCoValue.js.map +1 -1
  108. package/package.json +4 -14
  109. package/src/PeerKnownStates.ts +98 -90
  110. package/src/PeerState.ts +92 -73
  111. package/src/PriorityBasedMessageQueue.ts +42 -49
  112. package/src/SyncStateSubscriptionManager.ts +124 -0
  113. package/src/base64url.test.ts +24 -24
  114. package/src/base64url.ts +44 -45
  115. package/src/coValue.ts +45 -45
  116. package/src/coValueCore.ts +746 -785
  117. package/src/coValueState.ts +82 -72
  118. package/src/coValues/account.ts +143 -150
  119. package/src/coValues/coList.ts +520 -522
  120. package/src/coValues/coMap.ts +283 -285
  121. package/src/coValues/coStream.ts +320 -324
  122. package/src/coValues/group.ts +306 -305
  123. package/src/coreToCoValue.ts +28 -31
  124. package/src/crypto/PureJSCrypto.ts +188 -194
  125. package/src/crypto/WasmCrypto.ts +236 -254
  126. package/src/crypto/crypto.ts +302 -309
  127. package/src/exports.ts +116 -116
  128. package/src/ids.ts +9 -9
  129. package/src/jsonStringify.ts +46 -46
  130. package/src/jsonValue.ts +24 -10
  131. package/src/localNode.ts +635 -660
  132. package/src/media.ts +3 -3
  133. package/src/permissions.ts +272 -278
  134. package/src/priority.ts +21 -19
  135. package/src/storage/FileSystem.ts +91 -99
  136. package/src/storage/chunksAndKnownStates.ts +110 -115
  137. package/src/storage/index.ts +466 -497
  138. package/src/streamUtils.ts +60 -60
  139. package/src/sync.ts +656 -608
  140. package/src/tests/PeerKnownStates.test.ts +38 -34
  141. package/src/tests/PeerState.test.ts +101 -64
  142. package/src/tests/PriorityBasedMessageQueue.test.ts +91 -91
  143. package/src/tests/SyncStateSubscriptionManager.test.ts +232 -0
  144. package/src/tests/account.test.ts +59 -59
  145. package/src/tests/coList.test.ts +65 -65
  146. package/src/tests/coMap.test.ts +137 -137
  147. package/src/tests/coStream.test.ts +254 -257
  148. package/src/tests/coValueCore.test.ts +153 -156
  149. package/src/tests/crypto.test.ts +136 -144
  150. package/src/tests/cryptoImpl.test.ts +205 -197
  151. package/src/tests/group.test.ts +24 -24
  152. package/src/tests/permissions.test.ts +1306 -1371
  153. package/src/tests/priority.test.ts +65 -82
  154. package/src/tests/sync.test.ts +1573 -1263
  155. package/src/tests/testUtils.ts +85 -53
  156. package/src/typeUtils/accountOrAgentIDfromSessionID.ts +4 -4
  157. package/src/typeUtils/expectGroup.ts +9 -9
  158. package/src/typeUtils/isAccountID.ts +1 -1
  159. package/src/typeUtils/isCoValue.ts +9 -9
  160. package/tsconfig.json +4 -6
  161. package/tsconfig.native.json +9 -11
  162. package/tsconfig.web.json +4 -10
  163. package/.eslintrc.cjs +0 -25
  164. package/.prettierrc.js +0 -9
package/src/media.ts CHANGED
@@ -2,7 +2,7 @@ import { RawCoMap } from "./coValues/coMap.js";
2
2
  import { RawBinaryCoStream } from "./coValues/coStream.js";
3
3
 
4
4
  export type ImageDefinition = RawCoMap<{
5
- originalSize: [number, number];
6
- placeholderDataURL?: string;
7
- [res: `${number}x${number}`]: RawBinaryCoStream["id"];
5
+ originalSize: [number, number];
6
+ placeholderDataURL?: string;
7
+ [res: `${number}x${number}`]: RawBinaryCoStream["id"];
8
8
  }>;
@@ -1,312 +1,306 @@
1
1
  import { CoID } from "./coValue.js";
2
+ import { CoValueCore, Transaction } from "./coValueCore.js";
3
+ import { RawAccount, RawAccountID, RawProfile } from "./coValues/account.js";
2
4
  import { MapOpPayload } from "./coValues/coMap.js";
3
- import { JsonValue } from "./jsonValue.js";
5
+ import { EVERYONE, Everyone } from "./coValues/group.js";
4
6
  import { KeyID } from "./crypto/crypto.js";
5
- import { CoValueCore, Transaction } from "./coValueCore.js";
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";
9
8
  import { parseJSON } from "./jsonStringify.js";
10
- import { EVERYONE, Everyone } from "./coValues/group.js";
9
+ import { JsonValue } from "./jsonValue.js";
10
+ import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
11
11
  import { expectGroup } from "./typeUtils/expectGroup.js";
12
12
 
13
13
  export type PermissionsDef =
14
- | { type: "group"; initialAdmin: RawAccountID | AgentID }
15
- | { type: "ownedByGroup"; group: RawCoID }
16
- | { type: "unsafeAllowAll" };
14
+ | { type: "group"; initialAdmin: RawAccountID | AgentID }
15
+ | { type: "ownedByGroup"; group: RawCoID }
16
+ | { type: "unsafeAllowAll" };
17
17
 
18
18
  export type Role =
19
- | "reader"
20
- | "writer"
21
- | "admin"
22
- | "revoked"
23
- | "adminInvite"
24
- | "writerInvite"
25
- | "readerInvite";
19
+ | "reader"
20
+ | "writer"
21
+ | "admin"
22
+ | "revoked"
23
+ | "adminInvite"
24
+ | "writerInvite"
25
+ | "readerInvite";
26
26
 
27
27
  export function determineValidTransactions(
28
- coValue: CoValueCore,
28
+ coValue: CoValueCore,
29
29
  ): { txID: TransactionID; tx: Transaction }[] {
30
- if (coValue.header.ruleset.type === "group") {
31
- const allTransactionsSorted = [
32
- ...coValue.sessionLogs.entries(),
33
- ].flatMap(([sessionID, sessionLog]) => {
34
- return sessionLog.transactions.map((tx, txIndex) => ({
35
- sessionID,
36
- txIndex,
37
- tx,
38
- })) as {
39
- sessionID: SessionID;
40
- txIndex: number;
41
- tx: Transaction;
42
- }[];
43
- });
44
-
45
- allTransactionsSorted.sort((a, b) => {
46
- return a.tx.madeAt - b.tx.madeAt;
47
- });
48
-
49
- const initialAdmin = coValue.header.ruleset.initialAdmin;
50
-
51
- if (!initialAdmin) {
52
- throw new Error("Group must have initialAdmin");
53
- }
30
+ if (coValue.header.ruleset.type === "group") {
31
+ const allTransactionsSorted = [...coValue.sessionLogs.entries()].flatMap(
32
+ ([sessionID, sessionLog]) => {
33
+ return sessionLog.transactions.map((tx, txIndex) => ({
34
+ sessionID,
35
+ txIndex,
36
+ tx,
37
+ })) as {
38
+ sessionID: SessionID;
39
+ txIndex: number;
40
+ tx: Transaction;
41
+ }[];
42
+ },
43
+ );
54
44
 
55
- const memberState: {
56
- [agent: RawAccountID | AgentID]: Role;
57
- [EVERYONE]?: Role;
58
- } = {};
59
-
60
- const validTransactions: { txID: TransactionID; tx: Transaction }[] =
61
- [];
62
-
63
- for (const { sessionID, txIndex, tx } of allTransactionsSorted) {
64
- // console.log("before", { memberState, validTransactions });
65
- const transactor = accountOrAgentIDfromSessionID(sessionID);
66
-
67
- if (tx.privacy === "private") {
68
- if (memberState[transactor] === "admin") {
69
- validTransactions.push({
70
- txID: { sessionID, txIndex },
71
- tx,
72
- });
73
- continue;
74
- } else {
75
- console.warn(
76
- "Only admins can make private transactions in groups",
77
- );
78
- continue;
79
- }
80
- }
45
+ allTransactionsSorted.sort((a, b) => {
46
+ return a.tx.madeAt - b.tx.madeAt;
47
+ });
81
48
 
82
- let changes;
83
-
84
- try {
85
- changes = parseJSON(tx.changes);
86
- } catch (e) {
87
- console.warn(
88
- coValue.id,
89
- "Invalid JSON in transaction",
90
- e,
91
- tx,
92
- JSON.stringify(tx.changes, (k, v) =>
93
- k === "changes" || k === "encryptedChanges"
94
- ? v.slice(0, 20) + "..."
95
- : v,
96
- ),
97
- );
98
- continue;
99
- }
49
+ const initialAdmin = coValue.header.ruleset.initialAdmin;
100
50
 
101
- const change = changes[0] as
102
- | MapOpPayload<RawAccountID | AgentID | Everyone, Role>
103
- | MapOpPayload<"readKey", JsonValue>
104
- | MapOpPayload<"profile", CoID<RawProfile>>;
105
- if (changes.length !== 1) {
106
- console.warn("Group transaction must have exactly one change");
107
- continue;
108
- }
51
+ if (!initialAdmin) {
52
+ throw new Error("Group must have initialAdmin");
53
+ }
109
54
 
110
- if (change.op !== "set") {
111
- console.warn("Group transaction must set a role or readKey");
112
- continue;
113
- }
55
+ const memberState: {
56
+ [agent: RawAccountID | AgentID]: Role;
57
+ [EVERYONE]?: Role;
58
+ } = {};
59
+
60
+ const validTransactions: { txID: TransactionID; tx: Transaction }[] = [];
61
+
62
+ for (const { sessionID, txIndex, tx } of allTransactionsSorted) {
63
+ // console.log("before", { memberState, validTransactions });
64
+ const transactor = accountOrAgentIDfromSessionID(sessionID);
65
+
66
+ if (tx.privacy === "private") {
67
+ if (memberState[transactor] === "admin") {
68
+ validTransactions.push({
69
+ txID: { sessionID, txIndex },
70
+ tx,
71
+ });
72
+ continue;
73
+ } else {
74
+ console.warn("Only admins can make private transactions in groups");
75
+ continue;
76
+ }
77
+ }
78
+
79
+ let changes;
80
+
81
+ try {
82
+ changes = parseJSON(tx.changes);
83
+ } catch (e) {
84
+ console.warn(
85
+ coValue.id,
86
+ "Invalid JSON in transaction",
87
+ e,
88
+ tx,
89
+ JSON.stringify(tx.changes, (k, v) =>
90
+ k === "changes" || k === "encryptedChanges"
91
+ ? v.slice(0, 20) + "..."
92
+ : v,
93
+ ),
94
+ );
95
+ continue;
96
+ }
97
+
98
+ const change = changes[0] as
99
+ | MapOpPayload<RawAccountID | AgentID | Everyone, Role>
100
+ | MapOpPayload<"readKey", JsonValue>
101
+ | MapOpPayload<"profile", CoID<RawProfile>>;
102
+ if (changes.length !== 1) {
103
+ console.warn("Group transaction must have exactly one change");
104
+ continue;
105
+ }
106
+
107
+ if (change.op !== "set") {
108
+ console.warn("Group transaction must set a role or readKey");
109
+ continue;
110
+ }
111
+
112
+ if (change.key === "readKey") {
113
+ if (memberState[transactor] !== "admin") {
114
+ console.warn("Only admins can set readKeys");
115
+ continue;
116
+ }
114
117
 
115
- if (change.key === "readKey") {
116
- if (memberState[transactor] !== "admin") {
117
- console.warn("Only admins can set readKeys");
118
- continue;
119
- }
120
-
121
- validTransactions.push({ txID: { sessionID, txIndex }, tx });
122
- continue;
123
- } else if (change.key === "profile") {
124
- if (memberState[transactor] !== "admin") {
125
- console.warn("Only admins can set profile");
126
- continue;
127
- }
128
-
129
- validTransactions.push({ txID: { sessionID, txIndex }, tx });
130
- continue;
131
- } else if (
132
- isKeyForKeyField(change.key) ||
133
- isKeyForAccountField(change.key)
134
- ) {
135
- if (
136
- memberState[transactor] !== "admin" &&
137
- memberState[transactor] !== "adminInvite" &&
138
- memberState[transactor] !== "writerInvite" &&
139
- memberState[transactor] !== "readerInvite"
140
- ) {
141
- console.warn("Only admins can reveal keys");
142
- continue;
143
- }
144
-
145
- // TODO: check validity of agents who the key is revealed to?
146
-
147
- validTransactions.push({ txID: { sessionID, txIndex }, tx });
148
- continue;
149
- }
118
+ validTransactions.push({ txID: { sessionID, txIndex }, tx });
119
+ continue;
120
+ } else if (change.key === "profile") {
121
+ if (memberState[transactor] !== "admin") {
122
+ console.warn("Only admins can set profile");
123
+ continue;
124
+ }
150
125
 
151
- const affectedMember = change.key;
152
- const assignedRole = change.value;
153
-
154
- if (
155
- change.value !== "admin" &&
156
- change.value !== "writer" &&
157
- change.value !== "reader" &&
158
- change.value !== "revoked" &&
159
- change.value !== "adminInvite" &&
160
- change.value !== "writerInvite" &&
161
- change.value !== "readerInvite"
162
- ) {
163
- console.warn("Group transaction must set a valid role");
164
- continue;
165
- }
126
+ validTransactions.push({ txID: { sessionID, txIndex }, tx });
127
+ continue;
128
+ } else if (
129
+ isKeyForKeyField(change.key) ||
130
+ isKeyForAccountField(change.key)
131
+ ) {
132
+ if (
133
+ memberState[transactor] !== "admin" &&
134
+ memberState[transactor] !== "adminInvite" &&
135
+ memberState[transactor] !== "writerInvite" &&
136
+ memberState[transactor] !== "readerInvite"
137
+ ) {
138
+ console.warn("Only admins can reveal keys");
139
+ continue;
140
+ }
166
141
 
167
- if (
168
- affectedMember === EVERYONE &&
169
- !(
170
- change.value === "reader" ||
171
- change.value === "writer" ||
172
- change.value === "revoked"
173
- )
174
- ) {
175
- console.warn(
176
- "Everyone can only be set to reader, writer or revoked",
177
- );
178
- continue;
179
- }
142
+ // TODO: check validity of agents who the key is revealed to?
143
+
144
+ validTransactions.push({ txID: { sessionID, txIndex }, tx });
145
+ continue;
146
+ }
147
+
148
+ const affectedMember = change.key;
149
+ const assignedRole = change.value;
150
+
151
+ if (
152
+ change.value !== "admin" &&
153
+ change.value !== "writer" &&
154
+ change.value !== "reader" &&
155
+ change.value !== "revoked" &&
156
+ change.value !== "adminInvite" &&
157
+ change.value !== "writerInvite" &&
158
+ change.value !== "readerInvite"
159
+ ) {
160
+ console.warn("Group transaction must set a valid role");
161
+ continue;
162
+ }
163
+
164
+ if (
165
+ affectedMember === EVERYONE &&
166
+ !(
167
+ change.value === "reader" ||
168
+ change.value === "writer" ||
169
+ change.value === "revoked"
170
+ )
171
+ ) {
172
+ console.warn("Everyone can only be set to reader, writer or revoked");
173
+ continue;
174
+ }
175
+
176
+ const isFirstSelfAppointment =
177
+ !memberState[transactor] &&
178
+ transactor === initialAdmin &&
179
+ change.op === "set" &&
180
+ change.key === transactor &&
181
+ change.value === "admin";
182
+
183
+ if (!isFirstSelfAppointment) {
184
+ if (memberState[transactor] === "admin") {
185
+ if (
186
+ memberState[affectedMember] === "admin" &&
187
+ affectedMember !== transactor &&
188
+ assignedRole !== "admin"
189
+ ) {
190
+ console.warn("Admins can only demote themselves.");
191
+ continue;
192
+ }
193
+ } else if (memberState[transactor] === "adminInvite") {
194
+ if (change.value !== "admin") {
195
+ console.warn("AdminInvites can only create admins.");
196
+ continue;
197
+ }
198
+ } else if (memberState[transactor] === "writerInvite") {
199
+ if (change.value !== "writer") {
200
+ console.warn("WriterInvites can only create writers.");
201
+ continue;
202
+ }
203
+ } else if (memberState[transactor] === "readerInvite") {
204
+ if (change.value !== "reader") {
205
+ console.warn("ReaderInvites can only create reader.");
206
+ continue;
207
+ }
208
+ } else {
209
+ console.warn(
210
+ "Group transaction must be made by current admin or invite",
211
+ );
212
+ continue;
213
+ }
214
+ }
180
215
 
181
- const isFirstSelfAppointment =
182
- !memberState[transactor] &&
183
- transactor === initialAdmin &&
184
- change.op === "set" &&
185
- change.key === transactor &&
186
- change.value === "admin";
187
-
188
- if (!isFirstSelfAppointment) {
189
- if (memberState[transactor] === "admin") {
190
- if (
191
- memberState[affectedMember] === "admin" &&
192
- affectedMember !== transactor &&
193
- assignedRole !== "admin"
194
- ) {
195
- console.warn("Admins can only demote themselves.");
196
- continue;
197
- }
198
- } else if (memberState[transactor] === "adminInvite") {
199
- if (change.value !== "admin") {
200
- console.warn("AdminInvites can only create admins.");
201
- continue;
202
- }
203
- } else if (memberState[transactor] === "writerInvite") {
204
- if (change.value !== "writer") {
205
- console.warn("WriterInvites can only create writers.");
206
- continue;
207
- }
208
- } else if (memberState[transactor] === "readerInvite") {
209
- if (change.value !== "reader") {
210
- console.warn("ReaderInvites can only create reader.");
211
- continue;
212
- }
213
- } else {
214
- console.warn(
215
- "Group transaction must be made by current admin or invite",
216
- );
217
- continue;
218
- }
219
- }
216
+ memberState[affectedMember] = change.value;
217
+ validTransactions.push({ txID: { sessionID, txIndex }, tx });
220
218
 
221
- memberState[affectedMember] = change.value;
222
- validTransactions.push({ txID: { sessionID, txIndex }, tx });
219
+ // console.log("after", { memberState, validTransactions });
220
+ }
223
221
 
224
- // console.log("after", { memberState, validTransactions });
225
- }
222
+ return validTransactions;
223
+ } else if (coValue.header.ruleset.type === "ownedByGroup") {
224
+ const groupContent = expectGroup(
225
+ coValue.node
226
+ .expectCoValueLoaded(
227
+ coValue.header.ruleset.group,
228
+ "Determining valid transaction in owned object but its group wasn't loaded",
229
+ )
230
+ .getCurrentContent(),
231
+ );
226
232
 
227
- return validTransactions;
228
- } else if (coValue.header.ruleset.type === "ownedByGroup") {
229
- const groupContent = expectGroup(
230
- coValue.node
231
- .expectCoValueLoaded(
232
- coValue.header.ruleset.group,
233
- "Determining valid transaction in owned object but its group wasn't loaded",
234
- )
235
- .getCurrentContent(),
236
- );
233
+ if (groupContent.type !== "comap") {
234
+ throw new Error("Group must be a map");
235
+ }
237
236
 
238
- if (groupContent.type !== "comap") {
239
- throw new Error("Group must be a map");
240
- }
237
+ return [...coValue.sessionLogs.entries()].flatMap(
238
+ ([sessionID, sessionLog]) => {
239
+ const transactor = accountOrAgentIDfromSessionID(sessionID);
240
+
241
+ return sessionLog.transactions
242
+ .filter((tx) => {
243
+ const groupAtTime = groupContent.atTime(tx.madeAt);
244
+ const effectiveTransactor =
245
+ transactor === groupContent.id &&
246
+ groupAtTime instanceof RawAccount
247
+ ? groupAtTime.currentAgentID().match(
248
+ (agentID) => agentID,
249
+ (e) => {
250
+ console.error(
251
+ "Error while determining current agent ID in valid transactions",
252
+ e,
253
+ );
254
+ return undefined;
255
+ },
256
+ )
257
+ : transactor;
258
+
259
+ if (!effectiveTransactor) {
260
+ return false;
261
+ }
241
262
 
242
- return [...coValue.sessionLogs.entries()].flatMap(
243
- ([sessionID, sessionLog]) => {
244
- const transactor = accountOrAgentIDfromSessionID(sessionID);
245
-
246
- return sessionLog.transactions
247
- .filter((tx) => {
248
- const groupAtTime = groupContent.atTime(tx.madeAt);
249
- const effectiveTransactor =
250
- transactor === groupContent.id &&
251
- groupAtTime instanceof RawAccount
252
- ? groupAtTime.currentAgentID().match(
253
- (agentID) => agentID,
254
- (e) => {
255
- console.error(
256
- "Error while determining current agent ID in valid transactions",
257
- e,
258
- );
259
- return undefined;
260
- },
261
- )
262
- : transactor;
263
-
264
- if (!effectiveTransactor) {
265
- return false;
266
- }
267
-
268
- const transactorRoleAtTxTime =
269
- groupAtTime.get(effectiveTransactor) ||
270
- groupAtTime.get(EVERYONE);
271
-
272
- return (
273
- transactorRoleAtTxTime === "admin" ||
274
- transactorRoleAtTxTime === "writer"
275
- );
276
- })
277
- .map((tx, txIndex) => ({
278
- txID: { sessionID: sessionID, txIndex },
279
- tx,
280
- }));
281
- },
282
- );
283
- } else if (coValue.header.ruleset.type === "unsafeAllowAll") {
284
- return [...coValue.sessionLogs.entries()].flatMap(
285
- ([sessionID, sessionLog]) => {
286
- return sessionLog.transactions.map((tx, txIndex) => ({
287
- txID: { sessionID: sessionID, txIndex },
288
- tx,
289
- }));
290
- },
291
- );
292
- } else {
293
- throw new Error(
294
- "Unknown ruleset type " +
295
- (coValue.header.ruleset as { type: string }).type,
296
- );
297
- }
263
+ const transactorRoleAtTxTime =
264
+ groupAtTime.get(effectiveTransactor) || groupAtTime.get(EVERYONE);
265
+
266
+ return (
267
+ transactorRoleAtTxTime === "admin" ||
268
+ transactorRoleAtTxTime === "writer"
269
+ );
270
+ })
271
+ .map((tx, txIndex) => ({
272
+ txID: { sessionID: sessionID, txIndex },
273
+ tx,
274
+ }));
275
+ },
276
+ );
277
+ } else if (coValue.header.ruleset.type === "unsafeAllowAll") {
278
+ return [...coValue.sessionLogs.entries()].flatMap(
279
+ ([sessionID, sessionLog]) => {
280
+ return sessionLog.transactions.map((tx, txIndex) => ({
281
+ txID: { sessionID: sessionID, txIndex },
282
+ tx,
283
+ }));
284
+ },
285
+ );
286
+ } else {
287
+ throw new Error(
288
+ "Unknown ruleset type " +
289
+ (coValue.header.ruleset as { type: string }).type,
290
+ );
291
+ }
298
292
  }
299
293
 
300
294
  export function isKeyForKeyField(co: string): co is `${KeyID}_for_${KeyID}` {
301
- return co.startsWith("key_") && co.includes("_for_key");
295
+ return co.startsWith("key_") && co.includes("_for_key");
302
296
  }
303
297
 
304
298
  export function isKeyForAccountField(
305
- co: string,
299
+ co: string,
306
300
  ): co is `${KeyID}_for_${RawAccountID | AgentID}` {
307
- return (
308
- (co.startsWith("key_") &&
309
- (co.includes("_for_sealer") || co.includes("_for_co"))) ||
310
- co.includes("_for_everyone")
311
- );
301
+ return (
302
+ (co.startsWith("key_") &&
303
+ (co.includes("_for_sealer") || co.includes("_for_co"))) ||
304
+ co.includes("_for_everyone")
305
+ );
312
306
  }
package/src/priority.ts CHANGED
@@ -3,37 +3,39 @@ import { type CoValueHeader } from "./coValueCore.js";
3
3
  /**
4
4
  * The priority of a `CoValue` determines how much priority is given
5
5
  * to its content messages.
6
- *
6
+ *
7
7
  * The priority value is handled as weight in the weighed round robin algorithm
8
8
  * used to determine the order in which messages are sent.
9
- *
9
+ *
10
10
  * Follows the HTTP urgency range and order:
11
11
  * - https://www.rfc-editor.org/rfc/rfc9218.html#name-urgency
12
12
  */
13
13
  export const CO_VALUE_PRIORITY = {
14
- HIGH: 0,
15
- MEDIUM: 3,
16
- LOW: 6,
14
+ HIGH: 0,
15
+ MEDIUM: 3,
16
+ LOW: 6,
17
17
  } as const;
18
18
 
19
19
  export type CoValuePriority = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
20
20
 
21
- export function getPriorityFromHeader(header: CoValueHeader | undefined | boolean): CoValuePriority {
22
- if (typeof header === "boolean" || !header) {
23
- return CO_VALUE_PRIORITY.MEDIUM;
24
- }
21
+ export function getPriorityFromHeader(
22
+ header: CoValueHeader | undefined | boolean,
23
+ ): CoValuePriority {
24
+ if (typeof header === "boolean" || !header) {
25
+ return CO_VALUE_PRIORITY.MEDIUM;
26
+ }
25
27
 
26
- if (header.meta?.type === "account") {
27
- return CO_VALUE_PRIORITY.HIGH;
28
- }
28
+ if (header.meta?.type === "account") {
29
+ return CO_VALUE_PRIORITY.HIGH;
30
+ }
29
31
 
30
- if (header.ruleset.type === "group") {
31
- return CO_VALUE_PRIORITY.HIGH;
32
- }
32
+ if (header.ruleset.type === "group") {
33
+ return CO_VALUE_PRIORITY.HIGH;
34
+ }
33
35
 
34
- if (header.type === "costream" && header.meta?.type === "binary") {
35
- return CO_VALUE_PRIORITY.LOW;
36
- }
36
+ if (header.type === "costream" && header.meta?.type === "binary") {
37
+ return CO_VALUE_PRIORITY.LOW;
38
+ }
37
39
 
38
- return CO_VALUE_PRIORITY.MEDIUM;
40
+ return CO_VALUE_PRIORITY.MEDIUM;
39
41
  }