@peerbit/document 13.1.5 → 13.1.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/document",
3
- "version": "13.1.5",
3
+ "version": "13.1.7",
4
4
  "description": "Document store implementation",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -49,7 +49,7 @@
49
49
  "publishConfig": {
50
50
  "access": "public"
51
51
  },
52
- "author": "dao.xyz",
52
+ "author": "Peerbit contributors",
53
53
  "license": "MIT",
54
54
  "dependencies": {
55
55
  "@chainsafe/libp2p-yamux": "^8.0.1",
@@ -59,20 +59,20 @@
59
59
  "@multiformats/multiaddr": "^13.0.1",
60
60
  "p-defer": "^4.0.0",
61
61
  "uint8arrays": "^5.1.0",
62
- "@peerbit/indexer-cache": "0.2.8",
63
- "@peerbit/indexer-interface": "3.0.5",
64
62
  "@peerbit/cache": "3.1.0",
65
- "@peerbit/document-interface": "3.2.47",
66
- "@peerbit/indexer-simple": "1.2.9",
67
- "@peerbit/crypto": "3.1.2",
68
- "@peerbit/log": "6.2.4",
63
+ "@peerbit/document-interface": "3.2.49",
64
+ "@peerbit/indexer-cache": "0.2.10",
65
+ "@peerbit/crypto": "3.1.3",
66
+ "@peerbit/indexer-interface": "3.0.7",
67
+ "@peerbit/indexer-simple": "1.2.11",
68
+ "@peerbit/indexer-sqlite3": "3.0.10",
69
+ "@peerbit/log": "6.2.6",
69
70
  "@peerbit/logger": "2.0.1",
70
- "@peerbit/indexer-sqlite3": "3.0.8",
71
- "@peerbit/pubsub": "5.3.0",
72
- "@peerbit/program": "6.0.34",
73
- "@peerbit/rpc": "6.1.2",
74
- "@peerbit/shared-log": "13.2.5",
75
- "@peerbit/stream-interface": "6.0.11"
71
+ "@peerbit/program": "6.0.36",
72
+ "@peerbit/pubsub": "5.3.1",
73
+ "@peerbit/rpc": "6.1.4",
74
+ "@peerbit/shared-log": "13.2.7",
75
+ "@peerbit/stream-interface": "6.0.12"
76
76
  },
77
77
  "optionalDependencies": {
78
78
  "@peerbit/document-rust": "0.1.1"
@@ -82,12 +82,12 @@
82
82
  "@libp2p/websockets": "^10.1.7",
83
83
  "@types/pidusage": "^2.0.5",
84
84
  "pidusage": "^4.0.1",
85
- "uuid": "^10.0.0",
85
+ "uuid": "^11.1.1",
86
+ "@peerbit/native-backbone": "0.2.0",
86
87
  "@peerbit/log-rust": "1.1.2",
87
- "@peerbit/native-backbone": "0.1.4",
88
- "@peerbit/time": "3.0.0",
89
- "@peerbit/test-utils": "3.1.5",
90
- "peerbit": "5.3.5"
88
+ "@peerbit/test-utils": "3.1.7",
89
+ "@peerbit/time": "3.0.1",
90
+ "peerbit": "5.3.7"
91
91
  },
92
92
  "repository": {
93
93
  "type": "git",
@@ -102,7 +102,7 @@
102
102
  "clean": "aegir clean",
103
103
  "build": "aegir build --no-bundle",
104
104
  "test": "aegir test --target node",
105
- "test:document-rust-core": "npm run build && PEERBIT_SHARED_LOG_RUST_CORE=1 aegir test -t node --grep '^(?!.*(uses the validated local append path|uses the independent native prepared batch path|uses native shared-log planning for replicated target-none puts|uses commit-only local puts when coordinate persistence is deferred|can delete without being replicator)).*(native conformance guard |operations basic |operations get |operations index |operations search |iterate sort |count approximate |query distribution |returnIndexed |caching |custom index |prefetch )'",
105
+ "test:document-rust-core": "npm run build && PEERBIT_SHARED_LOG_RUST_CORE=1 aegir test -t node --grep '^(?!.*(uses the validated local append path|uses the independent native prepared batch path|uses native shared-log planning for replicated target-none puts|uses commit-only local puts when coordinate persistence is deferred)).*(native conformance guard |operations basic |operations get |operations index |operations search |iterate sort |count approximate |query distribution |returnIndexed |caching |custom index |prefetch )' -- --forbid-pending",
106
106
  "lint": "aegir lint",
107
107
  "test:cov": "aegir test -t node --cov"
108
108
  }
package/src/program.ts CHANGED
@@ -735,6 +735,7 @@ type TrustedDocumentSharedLogAppendManyResult = {
735
735
  };
736
736
 
737
737
  type TrustedDocumentSharedLog = {
738
+ finishNativeStrictDurableDocumentRecovery(): Promise<void>;
738
739
  appendLocallyPrepared(
739
740
  data: Operation,
740
741
  options?: SharedAppendOptions<Operation>,
@@ -2418,6 +2419,9 @@ export class Documents<
2418
2419
  await initializeDocumentRust();
2419
2420
  }
2420
2421
  }
2422
+ await asTrustedDocumentSharedLog(
2423
+ this.log,
2424
+ ).finishNativeStrictDurableDocumentRecovery();
2421
2425
 
2422
2426
  this._optionCanPerformNativeFastPath = this._optionCanPerformNativePolicy
2423
2427
  ? createCanPerformPolicyEvaluator(
@@ -11,6 +11,11 @@ import { logger as loggerFn } from "@peerbit/logger";
11
11
  const iteratorLogger = loggerFn("peerbit:document:index:iterate");
12
12
 
13
13
  export class ResumableIterators<T extends Record<string, any>> {
14
+ private readonly pendingMarks = new Map<
15
+ string,
16
+ Map<string, indexerTypes.IdKey>
17
+ >();
18
+
14
19
  constructor(
15
20
  readonly index: indexerTypes.Index<T>,
16
21
  readonly queues = new Cache<{
@@ -22,6 +27,36 @@ export class ResumableIterators<T extends Record<string, any>> {
22
27
  // TODO choose upper limit better
23
28
  }
24
29
 
30
+ private markKey(id: indexerTypes.IdKey) {
31
+ return `${id.key instanceof Uint8Array ? "bytes" : typeof id.key}:${String(id.primitive)}`;
32
+ }
33
+
34
+ private retainMarks(id: string, ids: Iterable<indexerTypes.IdKey>) {
35
+ let retained = this.pendingMarks.get(id);
36
+ for (const mark of ids) {
37
+ if (!retained) {
38
+ retained = new Map();
39
+ this.pendingMarks.set(id, retained);
40
+ }
41
+ retained.set(this.markKey(mark), mark);
42
+ }
43
+ }
44
+
45
+ private async applyPendingMarks(
46
+ id: string,
47
+ iterator: indexerTypes.IndexIterator<T, undefined>,
48
+ ) {
49
+ while (true) {
50
+ const retained = this.pendingMarks.get(id);
51
+ if (!retained?.size) {
52
+ this.pendingMarks.delete(id);
53
+ return;
54
+ }
55
+ this.pendingMarks.delete(id);
56
+ await iterator.markYielded?.(retained.values());
57
+ }
58
+ }
59
+
25
60
  async iterateAndFetch(
26
61
  request: SearchRequest | SearchRequestIndexed | IterationRequest,
27
62
  options?: { keepAlive?: boolean },
@@ -31,29 +66,32 @@ export class ResumableIterators<T extends Record<string, any>> {
31
66
  fetch: request.fetch,
32
67
  keepAlive: Boolean(options?.keepAlive),
33
68
  });
34
- const iterator = this.index.iterate(request);
35
- const firstResult = await iterator.next(request.fetch);
36
69
  const keepAlive = options?.keepAlive === true;
37
- if (keepAlive || iterator.done() !== true) {
38
- const cachedIterator = {
39
- iterator,
40
- request,
70
+ const iterator = this.index.iterate(request);
71
+ this.queues.add(request.idString, { iterator, request, keepAlive });
72
+ try {
73
+ await this.applyPendingMarks(request.idString, iterator);
74
+ const firstResult = await iterator.next(request.fetch);
75
+ if (!keepAlive && iterator.done() === true) {
76
+ this.queues.del(request.idString);
77
+ this.pendingMarks.delete(request.idString);
78
+ }
79
+ iteratorLogger("iterate:queued", {
80
+ id: request.idString,
41
81
  keepAlive,
42
- };
43
- this.queues.add(request.idString, cachedIterator);
82
+ done: iterator.done() === true,
83
+ batch: firstResult.length,
84
+ });
85
+ /* console.debug(
86
+ "[ResumableIterators] iterateAndFetch",
87
+ request.idString,
88
+ { keepAlive },
89
+ ); */
90
+ return firstResult;
91
+ } catch (error) {
92
+ this.clear(request.idString);
93
+ throw error;
44
94
  }
45
- iteratorLogger("iterate:queued", {
46
- id: request.idString,
47
- keepAlive,
48
- done: iterator.done() === true,
49
- batch: firstResult.length,
50
- });
51
- /* console.debug(
52
- "[ResumableIterators] iterateAndFetch",
53
- request.idString,
54
- { keepAlive },
55
- ); */
56
- return firstResult;
57
95
  }
58
96
 
59
97
  async next(
@@ -138,6 +176,7 @@ export class ResumableIterators<T extends Record<string, any>> {
138
176
  }
139
177
  }
140
178
  this.queues.del(id);
179
+ this.pendingMarks.delete(id);
141
180
  }
142
181
 
143
182
  async clearAll() {
@@ -155,6 +194,7 @@ export class ResumableIterators<T extends Record<string, any>> {
155
194
  ),
156
195
  );
157
196
  this.queues.clear();
197
+ this.pendingMarks.clear();
158
198
  }
159
199
 
160
200
  has(id: string) {
@@ -179,4 +219,12 @@ export class ResumableIterators<T extends Record<string, any>> {
179
219
  });
180
220
  return pending;
181
221
  }
222
+
223
+ async markYielded(id: string, ids: Iterable<indexerTypes.IdKey>) {
224
+ this.retainMarks(id, ids);
225
+ const iterator = this.queues.get(id);
226
+ if (iterator) {
227
+ await this.applyPendingMarks(id, iterator.iterator);
228
+ }
229
+ }
182
230
  }