@peerbit/document 13.1.0 → 13.1.2
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/dist/src/program.d.ts.map +1 -1
- package/dist/src/program.js +1 -0
- package/dist/src/program.js.map +1 -1
- package/dist/src/search.d.ts +2 -0
- package/dist/src/search.d.ts.map +1 -1
- package/dist/src/search.js +50 -6
- package/dist/src/search.js.map +1 -1
- package/package.json +11 -11
- package/src/program.ts +1 -0
- package/src/search.ts +74 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/document",
|
|
3
|
-
"version": "13.1.
|
|
3
|
+
"version": "13.1.2",
|
|
4
4
|
"description": "Document store implementation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"uint8arrays": "^5.1.0",
|
|
62
62
|
"@peerbit/cache": "3.1.0",
|
|
63
63
|
"@peerbit/crypto": "3.1.2",
|
|
64
|
-
"@peerbit/document-interface": "3.2.43",
|
|
65
64
|
"@peerbit/indexer-cache": "0.2.8",
|
|
65
|
+
"@peerbit/document-interface": "3.2.45",
|
|
66
66
|
"@peerbit/indexer-interface": "3.0.5",
|
|
67
|
-
"@peerbit/indexer-sqlite3": "3.0.8",
|
|
68
67
|
"@peerbit/indexer-simple": "1.2.8",
|
|
69
|
-
"@peerbit/
|
|
68
|
+
"@peerbit/indexer-sqlite3": "3.0.8",
|
|
69
|
+
"@peerbit/log": "6.2.2",
|
|
70
70
|
"@peerbit/logger": "2.0.1",
|
|
71
71
|
"@peerbit/program": "6.0.32",
|
|
72
|
-
"@peerbit/rpc": "6.1.0",
|
|
73
72
|
"@peerbit/pubsub": "5.3.0",
|
|
73
|
+
"@peerbit/rpc": "6.1.0",
|
|
74
74
|
"@peerbit/stream-interface": "6.0.11",
|
|
75
|
-
"@peerbit/shared-log": "13.2.
|
|
75
|
+
"@peerbit/shared-log": "13.2.2"
|
|
76
76
|
},
|
|
77
77
|
"optionalDependencies": {
|
|
78
|
-
"@peerbit/document-rust": "0.1.
|
|
78
|
+
"@peerbit/document-rust": "0.1.1"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@chainsafe/libp2p-noise": "^17.0.0",
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"@types/pidusage": "^2.0.5",
|
|
84
84
|
"pidusage": "^4.0.1",
|
|
85
85
|
"uuid": "^10.0.0",
|
|
86
|
-
"@peerbit/
|
|
86
|
+
"@peerbit/log-rust": "1.1.2",
|
|
87
|
+
"@peerbit/native-backbone": "0.1.2",
|
|
88
|
+
"@peerbit/test-utils": "3.1.2",
|
|
87
89
|
"@peerbit/time": "3.0.0",
|
|
88
|
-
"
|
|
89
|
-
"@peerbit/test-utils": "3.1.0",
|
|
90
|
-
"peerbit": "5.3.0"
|
|
90
|
+
"peerbit": "5.3.2"
|
|
91
91
|
},
|
|
92
92
|
"repository": {
|
|
93
93
|
"type": "git",
|
package/src/program.ts
CHANGED
|
@@ -2300,6 +2300,7 @@ export class Documents<
|
|
|
2300
2300
|
maybeOpen: this.maybeSubprogramOpen.bind(this),
|
|
2301
2301
|
prefetch: options.index?.prefetch,
|
|
2302
2302
|
includeIndexed: options.index?.includeIndexed,
|
|
2303
|
+
immutable: this.immutable,
|
|
2303
2304
|
});
|
|
2304
2305
|
this._documentInternalChangeListenerCount = Math.max(
|
|
2305
2306
|
0,
|
package/src/search.ts
CHANGED
|
@@ -859,6 +859,7 @@ export type OpenOptions<
|
|
|
859
859
|
maybeOpen: (value: T & Program) => Promise<T & Program>;
|
|
860
860
|
prefetch?: boolean | Partial<PrefetchOptions>;
|
|
861
861
|
includeIndexed?: boolean; // if true, indexed representations will always be included in the search results
|
|
862
|
+
immutable?: boolean; // conflict rule of the owning store: oldest version wins when true (mirrors Documents "immutable")
|
|
862
863
|
};
|
|
863
864
|
|
|
864
865
|
type IndexableClass<I> = new (
|
|
@@ -1093,6 +1094,7 @@ export class DocumentIndex<
|
|
|
1093
1094
|
private _resumableIterators: ResumableIterators<WithContext<I>>;
|
|
1094
1095
|
private _prefetch?: PrefetchOptions | undefined;
|
|
1095
1096
|
private includeIndexed: boolean | undefined = undefined;
|
|
1097
|
+
private immutable: boolean = false;
|
|
1096
1098
|
|
|
1097
1099
|
compatibility: 6 | 7 | 8 | 9 | undefined;
|
|
1098
1100
|
|
|
@@ -1427,6 +1429,7 @@ export class DocumentIndex<
|
|
|
1427
1429
|
this.canRead = properties.canRead;
|
|
1428
1430
|
this.canSearch = properties.canSearch;
|
|
1429
1431
|
this.includeIndexed = properties.includeIndexed;
|
|
1432
|
+
this.immutable = properties.immutable ?? false;
|
|
1430
1433
|
|
|
1431
1434
|
@variant(0)
|
|
1432
1435
|
class IndexedClassWithContext {
|
|
@@ -4663,6 +4666,53 @@ export class DocumentIndex<
|
|
|
4663
4666
|
return indexedPlaceholders;
|
|
4664
4667
|
};
|
|
4665
4668
|
|
|
4669
|
+
// The `visited` set prevents re-emitting the same document across pages
|
|
4670
|
+
// and sources, but different sources can return different versions of the
|
|
4671
|
+
// same document (e.g. a stale local head merged before a newer remote
|
|
4672
|
+
// head arrives). Plain id-based dedupe would let the first-seen, stale
|
|
4673
|
+
// version permanently shadow the newer one. If the id is still buffered
|
|
4674
|
+
// (not yet handed to the consumer) and the incoming result is strictly
|
|
4675
|
+
// preferred by the store's conflict rule, evict the stale buffered entry
|
|
4676
|
+
// so the caller can buffer the preferred result in its place. Returns
|
|
4677
|
+
// true when the caller should proceed to buffer the incoming result.
|
|
4678
|
+
// Results that were already emitted to the consumer cannot be retracted
|
|
4679
|
+
// here; those are only corrected via live updates/replication.
|
|
4680
|
+
// The preference direction mirrors the index merge rule in program.ts:
|
|
4681
|
+
// newest wins for mutable stores, oldest wins for immutable stores.
|
|
4682
|
+
const isPreferredContext = (
|
|
4683
|
+
incoming: types.Context,
|
|
4684
|
+
existing: types.Context,
|
|
4685
|
+
): boolean =>
|
|
4686
|
+
incoming.head !== existing.head &&
|
|
4687
|
+
(this.immutable
|
|
4688
|
+
? incoming.modified < existing.modified
|
|
4689
|
+
: incoming.modified > existing.modified);
|
|
4690
|
+
|
|
4691
|
+
const evictStaleBuffered = (
|
|
4692
|
+
indexKey: indexerTypes.IdPrimitive,
|
|
4693
|
+
incomingContext: types.Context,
|
|
4694
|
+
): boolean => {
|
|
4695
|
+
for (const peerBuffer of peerBufferMap.values()) {
|
|
4696
|
+
for (let i = 0; i < peerBuffer.buffer.length; i++) {
|
|
4697
|
+
const existing = peerBuffer.buffer[i];
|
|
4698
|
+
const existingKey = indexerTypes.toId(
|
|
4699
|
+
this.indexByResolver(existing.indexed),
|
|
4700
|
+
).primitive;
|
|
4701
|
+
if (existingKey !== indexKey) {
|
|
4702
|
+
continue;
|
|
4703
|
+
}
|
|
4704
|
+
if (!isPreferredContext(incomingContext, existing.context)) {
|
|
4705
|
+
// same or non-preferred version: keep normal dedupe behavior
|
|
4706
|
+
return false;
|
|
4707
|
+
}
|
|
4708
|
+
peerBuffer.buffer.splice(i, 1);
|
|
4709
|
+
indexedPlaceholders?.delete(indexKey);
|
|
4710
|
+
return true;
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
return false; // not buffered (already emitted): skip incoming
|
|
4714
|
+
};
|
|
4715
|
+
|
|
4666
4716
|
let done = false;
|
|
4667
4717
|
let drain = false; // if true, close on empty once (overrides manual)
|
|
4668
4718
|
let first = false;
|
|
@@ -4921,7 +4971,10 @@ export class DocumentIndex<
|
|
|
4921
4971
|
indexedPlaceholders?.delete(indexKey);
|
|
4922
4972
|
continue;
|
|
4923
4973
|
}
|
|
4924
|
-
if (
|
|
4974
|
+
if (
|
|
4975
|
+
visited.has(indexKey) &&
|
|
4976
|
+
!evictStaleBuffered(indexKey, result.context)
|
|
4977
|
+
) {
|
|
4925
4978
|
continue;
|
|
4926
4979
|
}
|
|
4927
4980
|
visited.add(indexKey);
|
|
@@ -4940,7 +4993,8 @@ export class DocumentIndex<
|
|
|
4940
4993
|
result as unknown as types.ResultIndexedValue<I>;
|
|
4941
4994
|
if (
|
|
4942
4995
|
visited.has(indexKey) &&
|
|
4943
|
-
!indexedPlaceholders?.has(indexKey)
|
|
4996
|
+
!indexedPlaceholders?.has(indexKey) &&
|
|
4997
|
+
!evictStaleBuffered(indexKey, indexedResult.context)
|
|
4944
4998
|
) {
|
|
4945
4999
|
continue;
|
|
4946
5000
|
}
|
|
@@ -5127,7 +5181,10 @@ export class DocumentIndex<
|
|
|
5127
5181
|
indexedPlaceholders?.delete(keyPrimitive);
|
|
5128
5182
|
continue;
|
|
5129
5183
|
}
|
|
5130
|
-
if (
|
|
5184
|
+
if (
|
|
5185
|
+
visited.has(keyPrimitive) &&
|
|
5186
|
+
!evictStaleBuffered(keyPrimitive, result.context)
|
|
5187
|
+
) {
|
|
5131
5188
|
continue;
|
|
5132
5189
|
}
|
|
5133
5190
|
visited.add(keyPrimitive);
|
|
@@ -5154,7 +5211,11 @@ export class DocumentIndex<
|
|
|
5154
5211
|
result as unknown as types.ResultIndexedValue<I>;
|
|
5155
5212
|
if (
|
|
5156
5213
|
visited.has(keyPrimitive) &&
|
|
5157
|
-
!indexedPlaceholders?.has(keyPrimitive)
|
|
5214
|
+
!indexedPlaceholders?.has(keyPrimitive) &&
|
|
5215
|
+
!evictStaleBuffered(
|
|
5216
|
+
keyPrimitive,
|
|
5217
|
+
indexedResult.context,
|
|
5218
|
+
)
|
|
5158
5219
|
) {
|
|
5159
5220
|
continue;
|
|
5160
5221
|
}
|
|
@@ -5279,7 +5340,10 @@ export class DocumentIndex<
|
|
|
5279
5340
|
indexedPlaceholders?.delete(indexKey);
|
|
5280
5341
|
continue;
|
|
5281
5342
|
}
|
|
5282
|
-
if (
|
|
5343
|
+
if (
|
|
5344
|
+
visited.has(indexKey) &&
|
|
5345
|
+
!evictStaleBuffered(indexKey, result.context)
|
|
5346
|
+
) {
|
|
5283
5347
|
continue;
|
|
5284
5348
|
}
|
|
5285
5349
|
visited.add(indexKey);
|
|
@@ -5309,7 +5373,11 @@ export class DocumentIndex<
|
|
|
5309
5373
|
result as unknown as types.ResultIndexedValue<I>;
|
|
5310
5374
|
if (
|
|
5311
5375
|
visited.has(indexKey) &&
|
|
5312
|
-
!indexedPlaceholders?.has(indexKey)
|
|
5376
|
+
!indexedPlaceholders?.has(indexKey) &&
|
|
5377
|
+
!evictStaleBuffered(
|
|
5378
|
+
indexKey,
|
|
5379
|
+
indexedResult.context,
|
|
5380
|
+
)
|
|
5313
5381
|
) {
|
|
5314
5382
|
continue;
|
|
5315
5383
|
}
|