cojson 0.13.11 → 0.13.13

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 (72) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/CoValuesStore.d.ts +3 -1
  4. package/dist/CoValuesStore.d.ts.map +1 -1
  5. package/dist/CoValuesStore.js +7 -6
  6. package/dist/CoValuesStore.js.map +1 -1
  7. package/dist/PeerState.d.ts +0 -2
  8. package/dist/PeerState.d.ts.map +1 -1
  9. package/dist/PeerState.js +0 -1
  10. package/dist/PeerState.js.map +1 -1
  11. package/dist/SyncStateManager.js +2 -2
  12. package/dist/SyncStateManager.js.map +1 -1
  13. package/dist/coValueCore.js +2 -2
  14. package/dist/coValueCore.js.map +1 -1
  15. package/dist/coValueState.d.ts +21 -46
  16. package/dist/coValueState.d.ts.map +1 -1
  17. package/dist/coValueState.js +170 -246
  18. package/dist/coValueState.js.map +1 -1
  19. package/dist/coValues/group.js +2 -2
  20. package/dist/coValues/group.js.map +1 -1
  21. package/dist/exports.d.ts +2 -4
  22. package/dist/exports.d.ts.map +1 -1
  23. package/dist/exports.js +1 -2
  24. package/dist/exports.js.map +1 -1
  25. package/dist/localNode.d.ts.map +1 -1
  26. package/dist/localNode.js +20 -16
  27. package/dist/localNode.js.map +1 -1
  28. package/dist/sync.d.ts.map +1 -1
  29. package/dist/sync.js +32 -41
  30. package/dist/sync.js.map +1 -1
  31. package/dist/tests/coValueState.test.js +57 -104
  32. package/dist/tests/coValueState.test.js.map +1 -1
  33. package/dist/tests/group.test.js +1 -2
  34. package/dist/tests/group.test.js.map +1 -1
  35. package/dist/tests/messagesTestUtils.d.ts +4 -1
  36. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  37. package/dist/tests/messagesTestUtils.js +10 -0
  38. package/dist/tests/messagesTestUtils.js.map +1 -1
  39. package/dist/tests/sync.peerReconciliation.test.js +8 -8
  40. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  41. package/dist/tests/sync.test.js +6 -4
  42. package/dist/tests/sync.test.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/CoValuesStore.ts +9 -6
  45. package/src/PeerState.ts +0 -2
  46. package/src/SyncStateManager.ts +2 -2
  47. package/src/coValueCore.ts +2 -2
  48. package/src/coValueState.ts +194 -316
  49. package/src/coValues/group.ts +2 -2
  50. package/src/exports.ts +0 -6
  51. package/src/localNode.ts +30 -21
  52. package/src/sync.ts +35 -43
  53. package/src/tests/coValueState.test.ts +55 -106
  54. package/src/tests/group.test.ts +2 -2
  55. package/src/tests/messagesTestUtils.ts +12 -1
  56. package/src/tests/sync.peerReconciliation.test.ts +8 -8
  57. package/src/tests/sync.test.ts +8 -23
  58. package/dist/storage/FileSystem.d.ts +0 -37
  59. package/dist/storage/FileSystem.d.ts.map +0 -1
  60. package/dist/storage/FileSystem.js +0 -48
  61. package/dist/storage/FileSystem.js.map +0 -1
  62. package/dist/storage/chunksAndKnownStates.d.ts +0 -7
  63. package/dist/storage/chunksAndKnownStates.d.ts.map +0 -1
  64. package/dist/storage/chunksAndKnownStates.js +0 -98
  65. package/dist/storage/chunksAndKnownStates.js.map +0 -1
  66. package/dist/storage/index.d.ts +0 -52
  67. package/dist/storage/index.d.ts.map +0 -1
  68. package/dist/storage/index.js +0 -335
  69. package/dist/storage/index.js.map +0 -1
  70. package/src/storage/FileSystem.ts +0 -113
  71. package/src/storage/chunksAndKnownStates.ts +0 -137
  72. package/src/storage/index.ts +0 -531
@@ -1,249 +1,205 @@
1
1
  import { ValueType } from "@opentelemetry/api";
2
2
  import { UpDownCounter, metrics } from "@opentelemetry/api";
3
3
  import { PeerState } from "./PeerState.js";
4
- import { CoValueCore } from "./coValueCore.js";
4
+ import { CoValueCore, TryAddTransactionsError } from "./coValueCore.js";
5
5
  import { RawCoID } from "./ids.js";
6
6
  import { logger } from "./logger.js";
7
- import { PeerID } from "./sync.js";
7
+ import { PeerID, emptyKnownState } from "./sync.js";
8
8
 
9
9
  export const CO_VALUE_LOADING_CONFIG = {
10
10
  MAX_RETRIES: 2,
11
11
  TIMEOUT: 30_000,
12
12
  };
13
13
 
14
- export class CoValueUnknownState {
15
- type = "unknown" as const;
16
- }
17
-
18
- export class CoValueLoadingState {
19
- type = "loading" as const;
14
+ export class CoValueState {
20
15
  private peers = new Map<
21
16
  PeerID,
22
- ReturnType<typeof createResolvablePromise<void>>
17
+ | { type: "unknown" | "pending" | "available" | "unavailable" }
18
+ | {
19
+ type: "errored";
20
+ error: TryAddTransactionsError;
21
+ }
23
22
  >();
24
- private resolveResult: (value: CoValueCore | "unavailable") => void;
25
-
26
- result: Promise<CoValueCore | "unavailable">;
27
-
28
- constructor(peersIds: Iterable<PeerID>) {
29
- this.peers = new Map();
30
-
31
- for (const peerId of peersIds) {
32
- this.peers.set(peerId, createResolvablePromise<void>());
33
- }
34
23
 
35
- const { resolve, promise } = createResolvablePromise<
36
- CoValueCore | "unavailable"
37
- >();
24
+ core: CoValueCore | null = null;
25
+ id: RawCoID;
38
26
 
39
- this.result = promise;
40
- this.resolveResult = resolve;
41
- }
42
-
43
- markAsUnavailable(peerId: PeerID) {
44
- const entry = this.peers.get(peerId);
27
+ private listeners: Set<(state: CoValueState) => void> = new Set();
28
+ private counter: UpDownCounter;
45
29
 
46
- if (entry) {
47
- entry.resolve();
48
- }
30
+ constructor(id: RawCoID) {
31
+ this.id = id;
49
32
 
50
- this.peers.delete(peerId);
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
+ });
51
40
 
52
- // If none of the peers have the coValue, we resolve to unavailable
53
- if (this.peers.size === 0) {
54
- this.resolve("unavailable");
55
- }
41
+ this.updateCounter(null);
56
42
  }
57
43
 
58
- resolve(value: CoValueCore | "unavailable") {
59
- this.resolveResult(value);
60
- for (const entry of this.peers.values()) {
61
- entry.resolve();
44
+ get highLevelState() {
45
+ if (this.core) {
46
+ return "available";
47
+ } else if (this.peers.size === 0) {
48
+ return "unknown";
62
49
  }
63
- this.peers.clear();
64
- }
65
-
66
- // Wait for a specific peer to have a known state
67
- waitForPeer(peerId: PeerID) {
68
- const entry = this.peers.get(peerId);
69
50
 
70
- if (!entry) {
71
- return Promise.resolve();
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
+ }
72
57
  }
73
58
 
74
- return entry.promise;
59
+ return "unavailable";
75
60
  }
76
- }
77
-
78
- export class CoValueAvailableState {
79
- type = "available" as const;
80
-
81
- constructor(public coValue: CoValueCore) {}
82
- }
83
-
84
- export class CoValueUnavailableState {
85
- type = "unavailable" as const;
86
- }
87
61
 
88
- type CoValueStateAction =
89
- | {
90
- type: "load-requested";
91
- peersIds: PeerID[];
92
- }
93
- | {
94
- type: "not-found-in-peer";
95
- peerId: PeerID;
96
- }
97
- | {
98
- type: "available";
99
- coValue: CoValueCore;
100
- };
101
-
102
- type CoValueStateType =
103
- | CoValueUnknownState
104
- | CoValueLoadingState
105
- | CoValueAvailableState
106
- | CoValueUnavailableState;
107
-
108
- export class CoValueState {
109
- promise?: Promise<CoValueCore | "unavailable">;
110
- private resolve?: (value: CoValueCore | "unavailable") => void;
111
- private counter: UpDownCounter;
112
-
113
- constructor(
114
- public id: RawCoID,
115
- public state: CoValueStateType,
116
- ) {
117
- this.counter = metrics
118
- .getMeter("cojson")
119
- .createUpDownCounter("jazz.covalues.loaded", {
120
- description: "The number of covalues in the system",
121
- unit: "covalue",
122
- valueType: ValueType.INT,
123
- });
124
-
125
- this.counter.add(1, {
126
- state: this.state.type,
127
- });
62
+ isErroredInPeer(peerId: PeerID) {
63
+ return this.peers.get(peerId)?.type === "errored";
128
64
  }
129
65
 
130
- static Unknown(id: RawCoID) {
131
- return new CoValueState(id, new CoValueUnknownState());
66
+ isAvailable(): this is { type: "available"; core: CoValueCore } {
67
+ return !!this.core;
132
68
  }
133
69
 
134
- static Loading(id: RawCoID, peersIds: Iterable<PeerID>) {
135
- return new CoValueState(id, new CoValueLoadingState(peersIds));
70
+ addListener(listener: (state: CoValueState) => void) {
71
+ this.listeners.add(listener);
72
+ listener(this);
136
73
  }
137
74
 
138
- static Available(coValue: CoValueCore) {
139
- return new CoValueState(coValue.id, new CoValueAvailableState(coValue));
75
+ removeListener(listener: (state: CoValueState) => void) {
76
+ this.listeners.delete(listener);
140
77
  }
141
78
 
142
- static Unavailable(id: RawCoID) {
143
- return new CoValueState(id, new CoValueUnavailableState());
79
+ private notifyListeners() {
80
+ for (const listener of this.listeners) {
81
+ listener(this);
82
+ }
144
83
  }
145
84
 
146
85
  async getCoValue() {
147
- if (this.state.type === "available") {
148
- return this.state.coValue;
149
- }
150
- if (this.state.type === "unavailable") {
86
+ if (this.highLevelState === "unavailable") {
151
87
  return "unavailable";
152
88
  }
153
89
 
154
- // If we don't have a resolved state we return a new promise
155
- // that will be resolved when the state will move to available or unavailable
156
- if (!this.promise) {
157
- const { promise, resolve } = createResolvablePromise<
158
- CoValueCore | "unavailable"
159
- >();
160
-
161
- this.promise = promise;
162
- this.resolve = resolve;
163
- }
164
-
165
- return this.promise;
166
- }
167
-
168
- private moveToState(value: CoValueStateType) {
169
- this.counter.add(-1, {
170
- state: this.state.type,
171
- });
172
- this.state = value;
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
+ };
173
97
 
174
- this.counter.add(1, {
175
- state: this.state.type,
98
+ this.addListener(listener);
176
99
  });
100
+ }
177
101
 
178
- if (!this.resolve) {
102
+ async loadFromPeers(peers: PeerState[]) {
103
+ if (peers.length === 0) {
179
104
  return;
180
105
  }
181
106
 
182
- // If the state is available we resolve the promise
183
- // and clear it to handle the possible transition from unavailable to available
184
- if (value.type === "available") {
185
- this.resolve(value.coValue);
186
- this.clearPromise();
187
- } else if (value.type === "unavailable") {
188
- this.resolve("unavailable");
189
- this.clearPromise();
190
- }
191
- }
107
+ const loadAttempt = async (peersToLoadFrom: PeerState[]) => {
108
+ const peersToActuallyLoadFrom = [];
109
+ for (const peer of peersToLoadFrom) {
110
+ const currentState = this.peers.get(peer.id);
192
111
 
193
- private clearPromise() {
194
- this.promise = undefined;
195
- this.resolve = undefined;
196
- }
112
+ if (currentState?.type === "available") {
113
+ continue;
114
+ }
197
115
 
198
- async loadFromPeers(peers: PeerState[]) {
199
- const state = this.state;
116
+ if (currentState?.type === "errored") {
117
+ continue;
118
+ }
200
119
 
201
- if (state.type === "loading" || state.type === "available") {
202
- return;
203
- }
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
+ }
204
128
 
205
- if (peers.length === 0) {
206
- this.moveToState(new CoValueUnavailableState());
207
- return;
208
- }
129
+ continue;
130
+ }
209
131
 
210
- const doLoad = async (peersToLoadFrom: PeerState[]) => {
211
- const peersWithoutErrors = getPeersWithoutErrors(
212
- peersToLoadFrom,
213
- this.id,
214
- );
215
-
216
- // If we are in the loading state we move to a new loading state
217
- // to reset all the loading promises
218
- if (
219
- this.state.type === "loading" ||
220
- this.state.type === "unknown" ||
221
- this.state.type === "unavailable"
222
- ) {
223
- this.moveToState(
224
- new CoValueLoadingState(peersWithoutErrors.map((p) => p.id)),
225
- );
132
+ if (!currentState || currentState?.type === "unknown") {
133
+ this.markPending(peer.id);
134
+ peersToActuallyLoadFrom.push(peer);
135
+ }
226
136
  }
227
137
 
228
- // Assign the current state to a variable to not depend on the state changes
229
- // that may happen while we wait for loadCoValueFromPeers to complete
230
- const currentState = this.state;
138
+ for (const peer of peersToActuallyLoadFrom) {
139
+ if (peer.closed) {
140
+ this.markNotFoundInPeer(peer.id);
141
+ continue;
142
+ }
231
143
 
232
- // If we entered successfully the loading state, we load the coValue from the peers
233
- //
234
- // We may not enter the loading state if the coValue has become available in between
235
- // of the retries
236
- if (currentState.type === "loading") {
237
- await loadCoValueFromPeers(this, peersWithoutErrors);
144
+ peer
145
+ .pushOutgoingMessage({
146
+ action: "load",
147
+ ...(this.core ? this.core.knownState() : emptyKnownState(this.id)),
148
+ })
149
+ .catch((err) => {
150
+ logger.warn(`Failed to push load message to peer ${peer.id}`, {
151
+ err,
152
+ });
153
+ });
238
154
 
239
- const result = await currentState.result;
240
- return result !== "unavailable";
241
- }
155
+ /**
156
+ * Use a very long timeout for storage peers, because under pressure
157
+ * they may take a long time to consume the messages queue
158
+ *
159
+ * TODO: Track errors on storage and do not rely on timeout
160
+ */
161
+ const timeoutDuration =
162
+ peer.role === "storage"
163
+ ? CO_VALUE_LOADING_CONFIG.TIMEOUT * 10
164
+ : CO_VALUE_LOADING_CONFIG.TIMEOUT;
165
+
166
+ const waitingForPeer = new Promise<void>((resolve) => {
167
+ const markNotFound = () => {
168
+ if (this.peers.get(peer.id)?.type === "pending") {
169
+ this.markNotFoundInPeer(peer.id);
170
+ }
171
+ };
172
+
173
+ const timeout = setTimeout(markNotFound, timeoutDuration);
174
+ const removeCloseListener = peer.addCloseListener(markNotFound);
175
+
176
+ const listener = (state: CoValueState) => {
177
+ const peerState = state.peers.get(peer.id);
178
+ if (
179
+ state.isAvailable() || // might have become available from another peer e.g. through handleNewContent
180
+ peerState?.type === "available" ||
181
+ peerState?.type === "errored" ||
182
+ peerState?.type === "unavailable"
183
+ ) {
184
+ state.removeListener(listener);
185
+ removeCloseListener();
186
+ clearTimeout(timeout);
187
+ resolve();
188
+ }
189
+ };
190
+
191
+ this.addListener(listener);
192
+ });
242
193
 
243
- return currentState.type === "available";
194
+ await waitingForPeer;
195
+ }
244
196
  };
245
197
 
246
- await doLoad(peers);
198
+ await loadAttempt(peers);
199
+
200
+ if (this.isAvailable()) {
201
+ return;
202
+ }
247
203
 
248
204
  // Retry loading from peers that have the retry flag enabled
249
205
  const peersWithRetry = peers.filter((p) =>
@@ -251,129 +207,74 @@ export class CoValueState {
251
207
  );
252
208
 
253
209
  if (peersWithRetry.length > 0) {
210
+ const waitingForCoValue = new Promise<void>((resolve) => {
211
+ const listener = (state: CoValueState) => {
212
+ if (state.isAvailable()) {
213
+ resolve();
214
+ this.removeListener(listener);
215
+ }
216
+ };
217
+
218
+ this.addListener(listener);
219
+ });
220
+
254
221
  // We want to exit early if the coValue becomes available in between the retries
255
222
  await Promise.race([
256
- this.getCoValue(),
223
+ waitingForCoValue,
257
224
  runWithRetry(
258
- () => doLoad(peersWithRetry),
225
+ () => loadAttempt(peersWithRetry),
259
226
  CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
260
227
  ),
261
228
  ]);
262
229
  }
263
-
264
- // If after the retries the coValue is still loading, we consider the load failed
265
- if (this.state.type === "loading") {
266
- this.moveToState(new CoValueUnavailableState());
267
- }
268
230
  }
269
231
 
270
- dispatch(action: CoValueStateAction) {
271
- const currentState = this.state;
272
-
273
- switch (action.type) {
274
- case "available":
275
- if (currentState.type === "loading") {
276
- currentState.resolve(action.coValue);
277
- }
278
-
279
- // It should be always possible to move to the available state
280
- this.moveToState(new CoValueAvailableState(action.coValue));
232
+ private updateCounter(previousState: string | null) {
233
+ const newState = this.highLevelState;
281
234
 
282
- break;
283
- case "not-found-in-peer":
284
- if (currentState.type === "loading") {
285
- currentState.markAsUnavailable(action.peerId);
286
- }
287
-
288
- break;
235
+ if (previousState !== newState) {
236
+ if (previousState) {
237
+ this.counter.add(-1, { state: previousState });
238
+ }
239
+ this.counter.add(1, { state: newState });
289
240
  }
290
241
  }
291
- }
292
242
 
293
- async function loadCoValueFromPeers(
294
- coValueEntry: CoValueState,
295
- peers: PeerState[],
296
- ) {
297
- for (const peer of peers) {
298
- if (peer.closed) {
299
- coValueEntry.dispatch({
300
- type: "not-found-in-peer",
301
- peerId: peer.id,
302
- });
303
- continue;
304
- }
243
+ markNotFoundInPeer(peerId: PeerID) {
244
+ const previousState = this.highLevelState;
245
+ this.peers.set(peerId, { type: "unavailable" });
246
+ this.updateCounter(previousState);
247
+ this.notifyListeners();
248
+ }
305
249
 
306
- if (coValueEntry.state.type === "available") {
307
- /**
308
- * We don't need to wait for the message to be delivered here.
309
- *
310
- * This way when the coValue becomes available because it's cached we don't wait for the server
311
- * peer to consume the messages queue before moving forward.
312
- */
313
- peer
314
- .pushOutgoingMessage({
315
- action: "load",
316
- ...coValueEntry.state.coValue.knownState(),
317
- })
318
- .catch((err) => {
319
- logger.warn(`Failed to push load message to peer ${peer.id}`, {
320
- err,
321
- });
322
- });
323
- } else {
324
- /**
325
- * We only wait for the load state to be resolved.
326
- */
327
- peer
328
- .pushOutgoingMessage({
329
- action: "load",
330
- id: coValueEntry.id,
331
- header: false,
332
- sessions: {},
333
- })
334
- .catch((err) => {
335
- logger.warn(`Failed to push load message to peer ${peer.id}`, {
336
- err,
337
- });
338
- });
339
- }
250
+ // TODO: rename to "provided"
251
+ markAvailable(coValue: CoValueCore, fromPeerId: PeerID) {
252
+ const previousState = this.highLevelState;
253
+ this.core = coValue;
254
+ this.peers.set(fromPeerId, { type: "available" });
255
+ this.updateCounter(previousState);
256
+ this.notifyListeners();
257
+ }
340
258
 
341
- if (coValueEntry.state.type === "loading") {
342
- const { promise, resolve } = createResolvablePromise<void>();
343
-
344
- /**
345
- * Use a very long timeout for storage peers, because under pressure
346
- * they may take a long time to consume the messages queue
347
- *
348
- * TODO: Track errors on storage and do not rely on timeout
349
- */
350
- const timeoutDuration =
351
- peer.role === "storage"
352
- ? CO_VALUE_LOADING_CONFIG.TIMEOUT * 10
353
- : CO_VALUE_LOADING_CONFIG.TIMEOUT;
354
-
355
- const handleTimeoutOrClose = () => {
356
- if (coValueEntry.state.type === "loading") {
357
- logger.warn("Failed to load coValue from peer", {
358
- coValueId: coValueEntry.id,
359
- peerId: peer.id,
360
- peerRole: peer.role,
361
- });
362
- coValueEntry.dispatch({
363
- type: "not-found-in-peer",
364
- peerId: peer.id,
365
- });
366
- resolve();
367
- }
368
- };
259
+ internalMarkMagicallyAvailable(coValue: CoValueCore) {
260
+ const previousState = this.highLevelState;
261
+ this.core = coValue;
262
+ this.updateCounter(previousState);
263
+ this.notifyListeners();
264
+ }
369
265
 
370
- const timeout = setTimeout(handleTimeoutOrClose, timeoutDuration);
371
- const closeListener = peer.addCloseListener(handleTimeoutOrClose);
266
+ markErrored(peerId: PeerID, error: TryAddTransactionsError) {
267
+ const previousState = this.highLevelState;
268
+ this.peers.set(peerId, { type: "errored", error });
269
+ this.updateCounter(previousState);
270
+ this.notifyListeners();
271
+ }
372
272
 
373
- await Promise.race([promise, coValueEntry.state.waitForPeer(peer.id)]);
374
- clearTimeout(timeout);
375
- closeListener();
376
- }
273
+ private markPending(peerId: PeerID) {
274
+ const previousState = this.highLevelState;
275
+ this.peers.set(peerId, { type: "pending" });
276
+ this.updateCounter(previousState);
277
+ this.notifyListeners();
377
278
  }
378
279
  }
379
280
 
@@ -400,29 +301,6 @@ async function runWithRetry<T>(fn: () => Promise<T>, maxRetries: number) {
400
301
  }
401
302
  }
402
303
 
403
- function createResolvablePromise<T>() {
404
- let resolve!: (value: T) => void;
405
-
406
- const promise = new Promise<T>((res) => {
407
- resolve = res;
408
- });
409
-
410
- return { promise, resolve };
411
- }
412
-
413
304
  function sleep(ms: number) {
414
305
  return new Promise((resolve) => setTimeout(resolve, ms));
415
306
  }
416
-
417
- function getPeersWithoutErrors(peers: PeerState[], coValueId: RawCoID) {
418
- return peers.filter((p) => {
419
- if (p.erroredCoValues.has(coValueId)) {
420
- logger.warn(
421
- `Skipping load on errored coValue ${coValueId} from peer ${p.id}`,
422
- );
423
- return false;
424
- }
425
-
426
- return true;
427
- });
428
- }
@@ -186,8 +186,8 @@ export class RawGroup<
186
186
  const child = store.get(id);
187
187
 
188
188
  if (
189
- child.state.type === "unknown" ||
190
- child.state.type === "unavailable"
189
+ child.highLevelState === "unknown" ||
190
+ child.highLevelState === "unavailable"
191
191
  ) {
192
192
  child.loadFromPeers(peers).catch(() => {
193
193
  logger.error(`Failed to load child group ${id}`);
package/src/exports.ts CHANGED
@@ -79,8 +79,6 @@ type Value = JsonValue | AnyRawCoValue;
79
79
  import { CO_VALUE_LOADING_CONFIG } from "./coValueState.js";
80
80
  import { logger } from "./logger.js";
81
81
  import { getPriorityFromHeader } from "./priority.js";
82
- import { FileSystem } from "./storage/FileSystem.js";
83
- import { BlockFilename, LSMStorage, WalFilename } from "./storage/index.js";
84
82
 
85
83
  /** @hidden */
86
84
  export const cojsonInternals = {
@@ -143,7 +141,6 @@ export {
143
141
  CryptoProvider,
144
142
  SyncMessage,
145
143
  isRawCoID,
146
- LSMStorage,
147
144
  emptyKnownState,
148
145
  RawCoPlainText,
149
146
  stringifyOpID,
@@ -154,9 +151,6 @@ export {
154
151
 
155
152
  export type {
156
153
  Value,
157
- FileSystem,
158
- BlockFilename,
159
- WalFilename,
160
154
  IncomingSyncStream,
161
155
  OutgoingSyncQueue,
162
156
  DisconnectedError,