cojson 0.13.16 → 0.13.18

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 (168) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +16 -0
  3. package/dist/PeerState.d.ts +3 -0
  4. package/dist/PeerState.d.ts.map +1 -1
  5. package/dist/PeerState.js +9 -0
  6. package/dist/PeerState.js.map +1 -1
  7. package/dist/SyncStateManager.d.ts.map +1 -1
  8. package/dist/SyncStateManager.js +2 -3
  9. package/dist/SyncStateManager.js.map +1 -1
  10. package/dist/coValue.d.ts +6 -4
  11. package/dist/coValue.d.ts.map +1 -1
  12. package/dist/coValue.js +5 -4
  13. package/dist/coValue.js.map +1 -1
  14. package/dist/coValueCore/coValueCore.d.ts +143 -0
  15. package/dist/coValueCore/coValueCore.d.ts.map +1 -0
  16. package/dist/{coValueCore.js → coValueCore/coValueCore.js} +314 -246
  17. package/dist/coValueCore/coValueCore.js.map +1 -0
  18. package/dist/coValueCore/verifiedState.d.ts +65 -0
  19. package/dist/coValueCore/verifiedState.d.ts.map +1 -0
  20. package/dist/coValueCore/verifiedState.js +210 -0
  21. package/dist/coValueCore/verifiedState.js.map +1 -0
  22. package/dist/coValues/account.d.ts +8 -10
  23. package/dist/coValues/account.d.ts.map +1 -1
  24. package/dist/coValues/account.js +12 -13
  25. package/dist/coValues/account.js.map +1 -1
  26. package/dist/coValues/coList.d.ts +10 -6
  27. package/dist/coValues/coList.d.ts.map +1 -1
  28. package/dist/coValues/coList.js +41 -15
  29. package/dist/coValues/coList.js.map +1 -1
  30. package/dist/coValues/coMap.d.ts +4 -3
  31. package/dist/coValues/coMap.d.ts.map +1 -1
  32. package/dist/coValues/coMap.js +5 -3
  33. package/dist/coValues/coMap.js.map +1 -1
  34. package/dist/coValues/coPlainText.d.ts +2 -2
  35. package/dist/coValues/coPlainText.d.ts.map +1 -1
  36. package/dist/coValues/coPlainText.js +5 -5
  37. package/dist/coValues/coPlainText.js.map +1 -1
  38. package/dist/coValues/coStream.d.ts +5 -4
  39. package/dist/coValues/coStream.d.ts.map +1 -1
  40. package/dist/coValues/coStream.js +5 -3
  41. package/dist/coValues/coStream.js.map +1 -1
  42. package/dist/coValues/group.d.ts +7 -2
  43. package/dist/coValues/group.d.ts.map +1 -1
  44. package/dist/coValues/group.js +29 -26
  45. package/dist/coValues/group.js.map +1 -1
  46. package/dist/coreToCoValue.d.ts +4 -3
  47. package/dist/coreToCoValue.d.ts.map +1 -1
  48. package/dist/coreToCoValue.js +10 -14
  49. package/dist/coreToCoValue.js.map +1 -1
  50. package/dist/exports.d.ts +6 -5
  51. package/dist/exports.d.ts.map +1 -1
  52. package/dist/exports.js +3 -4
  53. package/dist/exports.js.map +1 -1
  54. package/dist/localNode.d.ts +30 -24
  55. package/dist/localNode.d.ts.map +1 -1
  56. package/dist/localNode.js +153 -177
  57. package/dist/localNode.js.map +1 -1
  58. package/dist/permissions.d.ts +2 -1
  59. package/dist/permissions.d.ts.map +1 -1
  60. package/dist/permissions.js +15 -11
  61. package/dist/permissions.js.map +1 -1
  62. package/dist/priority.d.ts +1 -1
  63. package/dist/priority.d.ts.map +1 -1
  64. package/dist/sync.d.ts +2 -2
  65. package/dist/sync.d.ts.map +1 -1
  66. package/dist/sync.js +86 -55
  67. package/dist/sync.js.map +1 -1
  68. package/dist/tests/coList.test.js +133 -13
  69. package/dist/tests/coList.test.js.map +1 -1
  70. package/dist/tests/coMap.test.js +43 -14
  71. package/dist/tests/coMap.test.js.map +1 -1
  72. package/dist/tests/coPlainText.test.js +9 -10
  73. package/dist/tests/coPlainText.test.js.map +1 -1
  74. package/dist/tests/coStream.test.js +49 -18
  75. package/dist/tests/coStream.test.js.map +1 -1
  76. package/dist/tests/coValueCore.test.js +22 -28
  77. package/dist/tests/coValueCore.test.js.map +1 -1
  78. package/dist/tests/coValueCoreLoadingState.test.d.ts +2 -0
  79. package/dist/tests/coValueCoreLoadingState.test.d.ts.map +1 -0
  80. package/dist/tests/coValueCoreLoadingState.test.js +227 -0
  81. package/dist/tests/coValueCoreLoadingState.test.js.map +1 -0
  82. package/dist/tests/group.test.js +42 -43
  83. package/dist/tests/group.test.js.map +1 -1
  84. package/dist/tests/messagesTestUtils.d.ts +2 -2
  85. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  86. package/dist/tests/messagesTestUtils.js +1 -1
  87. package/dist/tests/messagesTestUtils.js.map +1 -1
  88. package/dist/tests/permissions.test.js +224 -292
  89. package/dist/tests/permissions.test.js.map +1 -1
  90. package/dist/tests/priority.test.js +13 -14
  91. package/dist/tests/priority.test.js.map +1 -1
  92. package/dist/tests/sync.auth.test.d.ts +2 -0
  93. package/dist/tests/sync.auth.test.d.ts.map +1 -0
  94. package/dist/tests/sync.auth.test.js +141 -0
  95. package/dist/tests/sync.auth.test.js.map +1 -0
  96. package/dist/tests/sync.load.test.js +60 -2
  97. package/dist/tests/sync.load.test.js.map +1 -1
  98. package/dist/tests/sync.mesh.test.js +70 -10
  99. package/dist/tests/sync.mesh.test.js.map +1 -1
  100. package/dist/tests/sync.peerReconciliation.test.js +19 -19
  101. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  102. package/dist/tests/sync.storage.test.js +20 -13
  103. package/dist/tests/sync.storage.test.js.map +1 -1
  104. package/dist/tests/sync.test.js +32 -39
  105. package/dist/tests/sync.test.js.map +1 -1
  106. package/dist/tests/sync.upload.test.js +126 -37
  107. package/dist/tests/sync.upload.test.js.map +1 -1
  108. package/dist/tests/testUtils.d.ts +24 -15
  109. package/dist/tests/testUtils.d.ts.map +1 -1
  110. package/dist/tests/testUtils.js +88 -61
  111. package/dist/tests/testUtils.js.map +1 -1
  112. package/dist/typeUtils/expectGroup.js +1 -1
  113. package/dist/typeUtils/expectGroup.js.map +1 -1
  114. package/package.json +1 -1
  115. package/src/PeerState.ts +11 -0
  116. package/src/SyncStateManager.ts +2 -3
  117. package/src/coValue.ts +14 -8
  118. package/src/{coValueCore.ts → coValueCore/coValueCore.ts} +470 -413
  119. package/src/coValueCore/verifiedState.ts +376 -0
  120. package/src/coValues/account.ts +20 -25
  121. package/src/coValues/coList.ts +63 -29
  122. package/src/coValues/coMap.ts +13 -6
  123. package/src/coValues/coPlainText.ts +10 -8
  124. package/src/coValues/coStream.ts +12 -7
  125. package/src/coValues/group.ts +50 -28
  126. package/src/coreToCoValue.ts +14 -15
  127. package/src/exports.ts +9 -7
  128. package/src/localNode.ts +248 -283
  129. package/src/permissions.ts +18 -12
  130. package/src/priority.ts +1 -1
  131. package/src/sync.ts +96 -63
  132. package/src/tests/coList.test.ts +200 -12
  133. package/src/tests/coMap.test.ts +65 -14
  134. package/src/tests/coPlainText.test.ts +12 -9
  135. package/src/tests/coStream.test.ts +80 -17
  136. package/src/tests/coValueCore.test.ts +30 -27
  137. package/src/tests/coValueCoreLoadingState.test.ts +337 -0
  138. package/src/tests/group.test.ts +44 -68
  139. package/src/tests/messagesTestUtils.ts +3 -8
  140. package/src/tests/permissions.test.ts +283 -449
  141. package/src/tests/priority.test.ts +17 -13
  142. package/src/tests/sync.auth.test.ts +188 -0
  143. package/src/tests/sync.load.test.ts +79 -2
  144. package/src/tests/sync.mesh.test.ts +89 -9
  145. package/src/tests/sync.peerReconciliation.test.ts +25 -25
  146. package/src/tests/sync.storage.test.ts +20 -13
  147. package/src/tests/sync.test.ts +43 -43
  148. package/src/tests/sync.upload.test.ts +157 -37
  149. package/src/tests/testUtils.ts +120 -74
  150. package/src/typeUtils/expectGroup.ts +1 -1
  151. package/dist/CoValuesStore.d.ts +0 -14
  152. package/dist/CoValuesStore.d.ts.map +0 -1
  153. package/dist/CoValuesStore.js +0 -32
  154. package/dist/CoValuesStore.js.map +0 -1
  155. package/dist/coValueCore.d.ts +0 -141
  156. package/dist/coValueCore.d.ts.map +0 -1
  157. package/dist/coValueCore.js.map +0 -1
  158. package/dist/coValueState.d.ts +0 -34
  159. package/dist/coValueState.d.ts.map +0 -1
  160. package/dist/coValueState.js +0 -228
  161. package/dist/coValueState.js.map +0 -1
  162. package/dist/tests/coValueState.test.d.ts +0 -2
  163. package/dist/tests/coValueState.test.d.ts.map +0 -1
  164. package/dist/tests/coValueState.test.js +0 -344
  165. package/dist/tests/coValueState.test.js.map +0 -1
  166. package/src/CoValuesStore.ts +0 -41
  167. package/src/coValueState.ts +0 -300
  168. package/src/tests/coValueState.test.ts +0 -525
@@ -1,300 +0,0 @@
1
- import { ValueType } from "@opentelemetry/api";
2
- import { UpDownCounter, metrics } from "@opentelemetry/api";
3
- import { PeerState } from "./PeerState.js";
4
- import { CoValueCore, TryAddTransactionsError } from "./coValueCore.js";
5
- import { RawCoID } from "./ids.js";
6
- import { logger } from "./logger.js";
7
- import { PeerID, emptyKnownState } from "./sync.js";
8
-
9
- export const CO_VALUE_LOADING_CONFIG = {
10
- MAX_RETRIES: 2,
11
- TIMEOUT: 30_000,
12
- };
13
-
14
- export class CoValueState {
15
- private peers = new Map<
16
- PeerID,
17
- | { type: "unknown" | "pending" | "available" | "unavailable" }
18
- | {
19
- type: "errored";
20
- error: TryAddTransactionsError;
21
- }
22
- >();
23
-
24
- core: CoValueCore | null = null;
25
- id: RawCoID;
26
-
27
- private listeners: Set<(state: CoValueState) => void> = new Set();
28
- private counter: UpDownCounter;
29
-
30
- constructor(id: RawCoID) {
31
- this.id = id;
32
-
33
- this.counter = metrics
34
- .getMeter("cojson")
35
- .createUpDownCounter("jazz.covalues.loaded", {
36
- description: "The number of covalues in the system",
37
- unit: "covalue",
38
- valueType: ValueType.INT,
39
- });
40
-
41
- this.updateCounter(null);
42
- }
43
-
44
- get highLevelState() {
45
- if (this.core) {
46
- return "available";
47
- } else if (this.peers.size === 0) {
48
- return "unknown";
49
- }
50
-
51
- for (const peer of this.peers.values()) {
52
- if (peer.type === "pending") {
53
- return "loading";
54
- } else if (peer.type === "unknown") {
55
- return "unknown";
56
- }
57
- }
58
-
59
- return "unavailable";
60
- }
61
-
62
- isErroredInPeer(peerId: PeerID) {
63
- return this.peers.get(peerId)?.type === "errored";
64
- }
65
-
66
- isAvailable(): this is { type: "available"; core: CoValueCore } {
67
- return !!this.core;
68
- }
69
-
70
- addListener(listener: (state: CoValueState) => void) {
71
- this.listeners.add(listener);
72
- listener(this);
73
- }
74
-
75
- removeListener(listener: (state: CoValueState) => void) {
76
- this.listeners.delete(listener);
77
- }
78
-
79
- private notifyListeners() {
80
- for (const listener of this.listeners) {
81
- listener(this);
82
- }
83
- }
84
-
85
- async getCoValue() {
86
- if (this.highLevelState === "unavailable") {
87
- return "unavailable";
88
- }
89
-
90
- return new Promise<CoValueCore>((resolve) => {
91
- const listener = (state: CoValueState) => {
92
- if (state.core) {
93
- resolve(state.core);
94
- this.removeListener(listener);
95
- }
96
- };
97
-
98
- this.addListener(listener);
99
- });
100
- }
101
-
102
- async loadFromPeers(peers: PeerState[]) {
103
- if (peers.length === 0) {
104
- return;
105
- }
106
-
107
- const loadAttempt = async (peersToLoadFrom: PeerState[]) => {
108
- const peersToActuallyLoadFrom = [];
109
- for (const peer of peersToLoadFrom) {
110
- const currentState = this.peers.get(peer.id);
111
-
112
- if (currentState?.type === "available") {
113
- continue;
114
- }
115
-
116
- if (currentState?.type === "errored") {
117
- continue;
118
- }
119
-
120
- if (
121
- currentState?.type === "unavailable" ||
122
- currentState?.type === "pending"
123
- ) {
124
- if (peer.shouldRetryUnavailableCoValues()) {
125
- this.markPending(peer.id);
126
- peersToActuallyLoadFrom.push(peer);
127
- }
128
-
129
- continue;
130
- }
131
-
132
- if (!currentState || currentState?.type === "unknown") {
133
- this.markPending(peer.id);
134
- peersToActuallyLoadFrom.push(peer);
135
- }
136
- }
137
-
138
- for (const peer of peersToActuallyLoadFrom) {
139
- if (peer.closed) {
140
- this.markNotFoundInPeer(peer.id);
141
- continue;
142
- }
143
-
144
- peer.pushOutgoingMessage({
145
- action: "load",
146
- ...(this.core ? this.core.knownState() : emptyKnownState(this.id)),
147
- });
148
-
149
- /**
150
- * Use a very long timeout for storage peers, because under pressure
151
- * they may take a long time to consume the messages queue
152
- *
153
- * TODO: Track errors on storage and do not rely on timeout
154
- */
155
- const timeoutDuration =
156
- peer.role === "storage"
157
- ? CO_VALUE_LOADING_CONFIG.TIMEOUT * 10
158
- : CO_VALUE_LOADING_CONFIG.TIMEOUT;
159
-
160
- const waitingForPeer = new Promise<void>((resolve) => {
161
- const markNotFound = () => {
162
- if (this.peers.get(peer.id)?.type === "pending") {
163
- this.markNotFoundInPeer(peer.id);
164
- }
165
- };
166
-
167
- const timeout = setTimeout(markNotFound, timeoutDuration);
168
- const removeCloseListener = peer.addCloseListener(markNotFound);
169
-
170
- const listener = (state: CoValueState) => {
171
- const peerState = state.peers.get(peer.id);
172
- if (
173
- state.isAvailable() || // might have become available from another peer e.g. through handleNewContent
174
- peerState?.type === "available" ||
175
- peerState?.type === "errored" ||
176
- peerState?.type === "unavailable"
177
- ) {
178
- state.removeListener(listener);
179
- removeCloseListener();
180
- clearTimeout(timeout);
181
- resolve();
182
- }
183
- };
184
-
185
- this.addListener(listener);
186
- });
187
-
188
- await waitingForPeer;
189
- }
190
- };
191
-
192
- await loadAttempt(peers);
193
-
194
- if (this.isAvailable()) {
195
- return;
196
- }
197
-
198
- // Retry loading from peers that have the retry flag enabled
199
- const peersWithRetry = peers.filter((p) =>
200
- p.shouldRetryUnavailableCoValues(),
201
- );
202
-
203
- if (peersWithRetry.length > 0) {
204
- const waitingForCoValue = new Promise<void>((resolve) => {
205
- const listener = (state: CoValueState) => {
206
- if (state.isAvailable()) {
207
- resolve();
208
- this.removeListener(listener);
209
- }
210
- };
211
-
212
- this.addListener(listener);
213
- });
214
-
215
- // We want to exit early if the coValue becomes available in between the retries
216
- await Promise.race([
217
- waitingForCoValue,
218
- runWithRetry(
219
- () => loadAttempt(peersWithRetry),
220
- CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
221
- ),
222
- ]);
223
- }
224
- }
225
-
226
- private updateCounter(previousState: string | null) {
227
- const newState = this.highLevelState;
228
-
229
- if (previousState !== newState) {
230
- if (previousState) {
231
- this.counter.add(-1, { state: previousState });
232
- }
233
- this.counter.add(1, { state: newState });
234
- }
235
- }
236
-
237
- markNotFoundInPeer(peerId: PeerID) {
238
- const previousState = this.highLevelState;
239
- this.peers.set(peerId, { type: "unavailable" });
240
- this.updateCounter(previousState);
241
- this.notifyListeners();
242
- }
243
-
244
- // TODO: rename to "provided"
245
- markAvailable(coValue: CoValueCore, fromPeerId: PeerID) {
246
- const previousState = this.highLevelState;
247
- this.core = coValue;
248
- this.peers.set(fromPeerId, { type: "available" });
249
- this.updateCounter(previousState);
250
- this.notifyListeners();
251
- }
252
-
253
- internalMarkMagicallyAvailable(coValue: CoValueCore) {
254
- const previousState = this.highLevelState;
255
- this.core = coValue;
256
- this.updateCounter(previousState);
257
- this.notifyListeners();
258
- }
259
-
260
- markErrored(peerId: PeerID, error: TryAddTransactionsError) {
261
- const previousState = this.highLevelState;
262
- this.peers.set(peerId, { type: "errored", error });
263
- this.updateCounter(previousState);
264
- this.notifyListeners();
265
- }
266
-
267
- private markPending(peerId: PeerID) {
268
- const previousState = this.highLevelState;
269
- this.peers.set(peerId, { type: "pending" });
270
- this.updateCounter(previousState);
271
- this.notifyListeners();
272
- }
273
- }
274
-
275
- async function runWithRetry<T>(fn: () => Promise<T>, maxRetries: number) {
276
- let retries = 1;
277
-
278
- while (retries < maxRetries) {
279
- /**
280
- * With maxRetries of 5 we should wait:
281
- * 300ms
282
- * 900ms
283
- * 2700ms
284
- * 8100ms
285
- */
286
- await sleep(3 ** retries * 100);
287
-
288
- const result = await fn();
289
-
290
- if (result === true) {
291
- return;
292
- }
293
-
294
- retries++;
295
- }
296
- }
297
-
298
- function sleep(ms: number) {
299
- return new Promise((resolve) => setTimeout(resolve, ms));
300
- }