@peerbit/document 15.0.12 → 15.0.14
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/callback-detachment.d.ts +14 -0
- package/dist/src/callback-detachment.d.ts.map +1 -0
- package/dist/src/callback-detachment.js +234 -0
- package/dist/src/callback-detachment.js.map +1 -0
- package/dist/src/domain.d.ts.map +1 -1
- package/dist/src/domain.js +5 -3
- package/dist/src/domain.js.map +1 -1
- package/dist/src/program.d.ts +5 -0
- package/dist/src/program.d.ts.map +1 -1
- package/dist/src/program.js +170 -43
- package/dist/src/program.js.map +1 -1
- package/dist/src/search.d.ts +5 -2
- package/dist/src/search.d.ts.map +1 -1
- package/dist/src/search.js +20 -6
- package/dist/src/search.js.map +1 -1
- package/package.json +15 -13
- package/src/callback-detachment.ts +308 -0
- package/src/domain.ts +11 -3
- package/src/program.ts +265 -52
- package/src/search.ts +44 -9
package/dist/src/program.js
CHANGED
|
@@ -32,7 +32,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import { BorshError, field, serialize, variant, } from "@dao-xyz/borsh";
|
|
35
|
+
import { BorshError, deserialize, field, serialize, variant, } from "@dao-xyz/borsh";
|
|
36
36
|
import { AccessError } from "@peerbit/crypto";
|
|
37
37
|
import { Context, NotFoundError, } from "@peerbit/document-interface";
|
|
38
38
|
import { extractDocumentFieldSimple, initializeDocumentRust, planDocumentContext, planDocumentContextBatch, tryPlanDocumentContext, tryPlanDocumentContextBatch, } from "./native-rust.js";
|
|
@@ -41,6 +41,7 @@ import { Entry, EntryType, LamportClock, ShallowEntry, ShallowMeta, Timestamp, e
|
|
|
41
41
|
import { logger as loggerFn } from "@peerbit/logger";
|
|
42
42
|
import { Program } from "@peerbit/program";
|
|
43
43
|
import { SharedLog, } from "@peerbit/shared-log";
|
|
44
|
+
import { detachCanPerformCallbackProperties, detachEntryPayloadForCallback, } from "./callback-detachment.js";
|
|
44
45
|
import { MAX_BATCH_SIZE } from "./constants.js";
|
|
45
46
|
import { BORSH_ENCODING_OPERATION, DeleteOperation, PutOperation, PutWithKeyOperation, coerceDeleteOperation, isDeleteOperation, isPutOperation, } from "./operation.js";
|
|
46
47
|
import { createCanPerformPolicyEvaluator, createCanPerformDeletePolicyEvaluator, getCanPerformPolicyDescriptor, canPerformPolicyDeleteFieldPaths, canPerformPolicyNeedsDeleteValue, canPerformPolicyNeedsPreviousEntries, canPerformPolicyPutNeedsEntryPublicKeys, canPerformPolicySignedByFieldPaths, } from "./policy.js";
|
|
@@ -392,9 +393,16 @@ let Documents = (() => {
|
|
|
392
393
|
_documentChangeListenerTrackingInitialized = false;
|
|
393
394
|
_documentBackend;
|
|
394
395
|
_canAppendDecodedDocuments = new WeakMap();
|
|
396
|
+
acceptPutOperation(operation, document, hasDocument) {
|
|
397
|
+
if (hasDocument) {
|
|
398
|
+
this._canAppendDecodedDocuments.set(operation, document);
|
|
399
|
+
}
|
|
400
|
+
return operation;
|
|
401
|
+
}
|
|
395
402
|
_nativeDocumentIdExtractionPlan;
|
|
396
403
|
_nativeDocumentFieldExtractionPlans;
|
|
397
404
|
_hasLogTrim = false;
|
|
405
|
+
_hasCustomIdResolver = false;
|
|
398
406
|
idResolver;
|
|
399
407
|
domain;
|
|
400
408
|
strictHistory;
|
|
@@ -418,6 +426,70 @@ let Documents = (() => {
|
|
|
418
426
|
? new NativeDocumentBackend(this.createNativeDocumentBackendContext())
|
|
419
427
|
: new CompatDocumentBackend(this.putCompatDocumentBackend.bind(this), this.putManyCompatDocumentBackend.bind(this), this.delCompatDocumentBackend.bind(this));
|
|
420
428
|
}
|
|
429
|
+
detachDomainEntryCallback(domain) {
|
|
430
|
+
const boundMethods = new Map();
|
|
431
|
+
const detachedFromEntry = (entry) => {
|
|
432
|
+
const fromEntry = Reflect.get(domain, "fromEntry", domain);
|
|
433
|
+
return Reflect.apply(fromEntry, domain, [
|
|
434
|
+
entry instanceof Entry
|
|
435
|
+
? detachEntryPayloadForCallback(entry)
|
|
436
|
+
: entry,
|
|
437
|
+
]);
|
|
438
|
+
};
|
|
439
|
+
const facade = Object.create(Object.getPrototypeOf(domain));
|
|
440
|
+
let callbackDomain;
|
|
441
|
+
callbackDomain = new Proxy(facade, {
|
|
442
|
+
get(_target, property) {
|
|
443
|
+
if (property === "fromEntry") {
|
|
444
|
+
return detachedFromEntry;
|
|
445
|
+
}
|
|
446
|
+
if (property === "valueOf") {
|
|
447
|
+
return () => callbackDomain;
|
|
448
|
+
}
|
|
449
|
+
const value = Reflect.get(domain, property, domain);
|
|
450
|
+
if (property === "constructor" || typeof value !== "function") {
|
|
451
|
+
return value;
|
|
452
|
+
}
|
|
453
|
+
const existing = boundMethods.get(property);
|
|
454
|
+
if (existing && existing.source === value) {
|
|
455
|
+
return existing.bound;
|
|
456
|
+
}
|
|
457
|
+
const bound = value.bind(domain);
|
|
458
|
+
boundMethods.set(property, { source: value, bound });
|
|
459
|
+
return bound;
|
|
460
|
+
},
|
|
461
|
+
set(_target, property, value) {
|
|
462
|
+
return Reflect.set(domain, property, value, domain);
|
|
463
|
+
},
|
|
464
|
+
has(_target, property) {
|
|
465
|
+
return Reflect.has(domain, property);
|
|
466
|
+
},
|
|
467
|
+
ownKeys() {
|
|
468
|
+
return Reflect.ownKeys(domain);
|
|
469
|
+
},
|
|
470
|
+
getOwnPropertyDescriptor(_target, property) {
|
|
471
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(domain, property);
|
|
472
|
+
if (!descriptor) {
|
|
473
|
+
return undefined;
|
|
474
|
+
}
|
|
475
|
+
if (property === "fromEntry") {
|
|
476
|
+
return "value" in descriptor
|
|
477
|
+
? {
|
|
478
|
+
...descriptor,
|
|
479
|
+
value: detachedFromEntry,
|
|
480
|
+
configurable: true,
|
|
481
|
+
}
|
|
482
|
+
: {
|
|
483
|
+
...descriptor,
|
|
484
|
+
get: () => detachedFromEntry,
|
|
485
|
+
configurable: true,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
return { ...descriptor, configurable: true };
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
return callbackDomain;
|
|
492
|
+
}
|
|
421
493
|
createNativeDocumentBackendContext() {
|
|
422
494
|
return {
|
|
423
495
|
assertPlainPutSupported: (doc, options) => {
|
|
@@ -1027,9 +1099,11 @@ let Documents = (() => {
|
|
|
1027
1099
|
* Those callers must keep throwing: outside change delivery, a closed index is
|
|
1028
1100
|
* a caller error, not a state to paper over.
|
|
1029
1101
|
*/
|
|
1030
|
-
getLocalIndexedContextForChange(key) {
|
|
1102
|
+
getLocalIndexedContextForChange(key, orderedSession) {
|
|
1031
1103
|
try {
|
|
1032
|
-
const result =
|
|
1104
|
+
const result = (orderedSession
|
|
1105
|
+
? orderedSession.get(key, { shape: INDEX_CONTEXT_SHAPE })
|
|
1106
|
+
: this.getLocalIndexedContext(key));
|
|
1033
1107
|
return (isPromiseLike(result)
|
|
1034
1108
|
? result.catch((error) => this.recoverClosedIndexContextRead(error))
|
|
1035
1109
|
: result);
|
|
@@ -1214,6 +1288,7 @@ let Documents = (() => {
|
|
|
1214
1288
|
(typeof idProperty === "string"
|
|
1215
1289
|
? (obj) => obj[idProperty]
|
|
1216
1290
|
: (obj) => indexerTypes.extractFieldValue(obj, idProperty));
|
|
1291
|
+
this._hasCustomIdResolver = options.id != null;
|
|
1217
1292
|
this.idResolver = idResolver;
|
|
1218
1293
|
this.strictHistory = options.strictHistory ?? false;
|
|
1219
1294
|
this._hasLogTrim = options.log?.trim != null;
|
|
@@ -1250,7 +1325,9 @@ let Documents = (() => {
|
|
|
1250
1325
|
// B12: the historical document->log compatibility mapping (6 -> log v8,
|
|
1251
1326
|
// 7 -> log v9) is retired; the rejection at the top of open() fires for
|
|
1252
1327
|
// any defined value before this point.
|
|
1253
|
-
this.domain = options.domain
|
|
1328
|
+
this.domain = options.domain
|
|
1329
|
+
? this.detachDomainEntryCallback(options.domain(this))
|
|
1330
|
+
: undefined;
|
|
1254
1331
|
let keepFunction;
|
|
1255
1332
|
if (options?.keep === "self") {
|
|
1256
1333
|
this.keepCache = new Set();
|
|
@@ -1291,7 +1368,16 @@ let Documents = (() => {
|
|
|
1291
1368
|
};
|
|
1292
1369
|
}
|
|
1293
1370
|
else {
|
|
1294
|
-
|
|
1371
|
+
const keep = options?.keep;
|
|
1372
|
+
keepFunction = keep
|
|
1373
|
+
? function (entry) {
|
|
1374
|
+
return Reflect.apply(keep, this, [
|
|
1375
|
+
entry instanceof Entry
|
|
1376
|
+
? detachEntryPayloadForCallback(entry)
|
|
1377
|
+
: entry,
|
|
1378
|
+
]);
|
|
1379
|
+
}
|
|
1380
|
+
: undefined;
|
|
1295
1381
|
}
|
|
1296
1382
|
await this.log.open({
|
|
1297
1383
|
encoding: BORSH_ENCODING_OPERATION,
|
|
@@ -1314,7 +1400,7 @@ let Documents = (() => {
|
|
|
1314
1400
|
distributionDebounceTime: options?.distributionDebounceTime,
|
|
1315
1401
|
strictFullReplicaFallback: false,
|
|
1316
1402
|
domain: options?.domain
|
|
1317
|
-
? () => options.domain(this)
|
|
1403
|
+
? () => this.detachDomainEntryCallback(options.domain(this))
|
|
1318
1404
|
: undefined,
|
|
1319
1405
|
eagerBlocks: options?.eagerBlocks,
|
|
1320
1406
|
fanout: options?.fanout,
|
|
@@ -1373,41 +1459,41 @@ let Documents = (() => {
|
|
|
1373
1459
|
return false;
|
|
1374
1460
|
}
|
|
1375
1461
|
try {
|
|
1376
|
-
|
|
1462
|
+
const operation = l0;
|
|
1377
1463
|
if (this._optionCanPerform) {
|
|
1378
1464
|
if (this._optionCanPerformNativePolicy && this.isNativeMode()) {
|
|
1379
1465
|
return this.nativeCanPerformAllowsAppend(this._optionCanPerformNativePolicy, operation, entry, reference?.document);
|
|
1380
1466
|
}
|
|
1381
|
-
let document
|
|
1382
|
-
if (
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
}
|
|
1391
|
-
else if (isDeleteOperation(l0)) {
|
|
1392
|
-
// Nothing to do here by default.
|
|
1393
|
-
// Checking if the document exists is not necessary since it
|
|
1394
|
-
// might already be deleted.
|
|
1395
|
-
}
|
|
1396
|
-
else {
|
|
1397
|
-
throw new Error("Unsupported operation");
|
|
1467
|
+
let document;
|
|
1468
|
+
if (isPutOperation(l0)) {
|
|
1469
|
+
const cachedDocument = this._canAppendDecodedDocuments.get(l0);
|
|
1470
|
+
this._canAppendDecodedDocuments.delete(l0);
|
|
1471
|
+
document =
|
|
1472
|
+
cachedDocument ??
|
|
1473
|
+
this._index.valueEncoding.decoder(new Uint8Array(l0.data));
|
|
1474
|
+
if (!document) {
|
|
1475
|
+
return false;
|
|
1398
1476
|
}
|
|
1399
1477
|
}
|
|
1478
|
+
else if (isDeleteOperation(l0)) {
|
|
1479
|
+
// Nothing to do here by default.
|
|
1480
|
+
// Checking if the document exists is not necessary since it
|
|
1481
|
+
// might already be deleted.
|
|
1482
|
+
}
|
|
1483
|
+
else {
|
|
1484
|
+
throw new Error("Unsupported operation");
|
|
1485
|
+
}
|
|
1400
1486
|
const previousEntries = this._optionCanPerformNativePolicy &&
|
|
1401
1487
|
isPutOperation(operation) &&
|
|
1402
1488
|
canPerformPolicyNeedsPreviousEntries(this._optionCanPerformNativePolicy)
|
|
1403
|
-
? await this.resolveCanPerformPreviousEntries(entry)
|
|
1489
|
+
? (await this.resolveCanPerformPreviousEntries(entry)).map(detachEntryPayloadForCallback)
|
|
1404
1490
|
: undefined;
|
|
1405
1491
|
const deleteValue = this._optionCanPerformNativePolicy &&
|
|
1406
1492
|
isDeleteOperation(operation) &&
|
|
1407
1493
|
canPerformPolicyNeedsDeleteValue(this._optionCanPerformNativePolicy)
|
|
1408
1494
|
? await this.resolveCanPerformDeleteValue(operation)
|
|
1409
1495
|
: undefined;
|
|
1410
|
-
if (!(await this._optionCanPerform(isPutOperation(operation)
|
|
1496
|
+
if (!(await this._optionCanPerform(detachCanPerformCallbackProperties(isPutOperation(operation)
|
|
1411
1497
|
? {
|
|
1412
1498
|
type: "put",
|
|
1413
1499
|
value: document,
|
|
@@ -1420,7 +1506,7 @@ let Documents = (() => {
|
|
|
1420
1506
|
value: deleteValue,
|
|
1421
1507
|
operation,
|
|
1422
1508
|
entry: entry,
|
|
1423
|
-
}))) {
|
|
1509
|
+
})))) {
|
|
1424
1510
|
return false;
|
|
1425
1511
|
}
|
|
1426
1512
|
}
|
|
@@ -1483,6 +1569,9 @@ let Documents = (() => {
|
|
|
1483
1569
|
}
|
|
1484
1570
|
return entries;
|
|
1485
1571
|
}
|
|
1572
|
+
detachDocumentValueForCallback(document) {
|
|
1573
|
+
return this._index.valueEncoding.decoder(this._index.valueEncoding.encoder(document));
|
|
1574
|
+
}
|
|
1486
1575
|
async resolveCanPerformDeleteValue(operation, options) {
|
|
1487
1576
|
const key = operation.key instanceof indexerTypes.IdKey
|
|
1488
1577
|
? operation.key
|
|
@@ -1494,11 +1583,11 @@ let Documents = (() => {
|
|
|
1494
1583
|
}
|
|
1495
1584
|
const indexedDocument = await this.getLocalIdentityDocumentByHead(existingHead);
|
|
1496
1585
|
if (indexedDocument) {
|
|
1497
|
-
return indexedDocument;
|
|
1586
|
+
return this.detachDocumentValueForCallback(indexedDocument);
|
|
1498
1587
|
}
|
|
1499
1588
|
const indexedPolicyDocument = await this.getLocalIndexedDocumentForNativeDeletePolicy(key);
|
|
1500
1589
|
if (indexedPolicyDocument) {
|
|
1501
|
-
return indexedPolicyDocument;
|
|
1590
|
+
return deserialize(serialize(indexedPolicyDocument), this._index.indexedType);
|
|
1502
1591
|
}
|
|
1503
1592
|
if (options?.allowEntryFallback === false) {
|
|
1504
1593
|
return;
|
|
@@ -1510,7 +1599,7 @@ let Documents = (() => {
|
|
|
1510
1599
|
if (!isPutOperation(existingOperation)) {
|
|
1511
1600
|
return;
|
|
1512
1601
|
}
|
|
1513
|
-
return this._index.valueEncoding.decoder(existingOperation.data);
|
|
1602
|
+
return this._index.valueEncoding.decoder(new Uint8Array(existingOperation.data));
|
|
1514
1603
|
}
|
|
1515
1604
|
async _canAppend(entry, reference) {
|
|
1516
1605
|
const resolve = async (history) => {
|
|
@@ -1552,9 +1641,13 @@ let Documents = (() => {
|
|
|
1552
1641
|
if (isPutOperation(operation)) {
|
|
1553
1642
|
// check nexts
|
|
1554
1643
|
const putOperation = operation;
|
|
1644
|
+
let decodedDocumentForCanPerform;
|
|
1645
|
+
let hasDecodedDocumentForCanPerform = false;
|
|
1555
1646
|
let keyValue;
|
|
1556
1647
|
if (reference?.document) {
|
|
1557
|
-
keyValue = this.idResolver(
|
|
1648
|
+
keyValue = this.idResolver(this._hasCustomIdResolver
|
|
1649
|
+
? this.index.valueEncoding.decoder(new Uint8Array(putOperation.data))
|
|
1650
|
+
: reference.document);
|
|
1558
1651
|
}
|
|
1559
1652
|
else {
|
|
1560
1653
|
keyValue = await this.getNativeDocumentIdFromPutOperation(putOperation);
|
|
@@ -1562,8 +1655,13 @@ let Documents = (() => {
|
|
|
1562
1655
|
if (this.isNativeMode()) {
|
|
1563
1656
|
return false;
|
|
1564
1657
|
}
|
|
1565
|
-
const value = this.index.valueEncoding.decoder(
|
|
1566
|
-
|
|
1658
|
+
const value = this.index.valueEncoding.decoder(this._hasCustomIdResolver || this._optionCanPerform
|
|
1659
|
+
? new Uint8Array(putOperation.data)
|
|
1660
|
+
: putOperation.data);
|
|
1661
|
+
if (this._optionCanPerform && !this._hasCustomIdResolver) {
|
|
1662
|
+
decodedDocumentForCanPerform = value;
|
|
1663
|
+
hasDecodedDocumentForCanPerform = true;
|
|
1664
|
+
}
|
|
1567
1665
|
keyValue = this.idResolver(value);
|
|
1568
1666
|
}
|
|
1569
1667
|
}
|
|
@@ -1594,7 +1692,7 @@ let Documents = (() => {
|
|
|
1594
1692
|
if (entry.meta.next.length > 0) {
|
|
1595
1693
|
return false; // can not append to immutable document
|
|
1596
1694
|
}
|
|
1597
|
-
return putOperation;
|
|
1695
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1598
1696
|
}
|
|
1599
1697
|
else {
|
|
1600
1698
|
if (this.strictHistory) {
|
|
@@ -1603,7 +1701,7 @@ let Documents = (() => {
|
|
|
1603
1701
|
return false;
|
|
1604
1702
|
}
|
|
1605
1703
|
if (entry.meta.next[0] === existingContext.head) {
|
|
1606
|
-
return putOperation;
|
|
1704
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1607
1705
|
}
|
|
1608
1706
|
const prevEntry = await this.log.log.entryIndex.get(existingContext.head);
|
|
1609
1707
|
if (!prevEntry) {
|
|
@@ -1612,16 +1710,19 @@ let Documents = (() => {
|
|
|
1612
1710
|
return false;
|
|
1613
1711
|
}
|
|
1614
1712
|
const referenceHistoryCorrectly = await pointsToHistory(prevEntry);
|
|
1615
|
-
return referenceHistoryCorrectly
|
|
1713
|
+
return referenceHistoryCorrectly
|
|
1714
|
+
? this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform)
|
|
1715
|
+
: false;
|
|
1616
1716
|
}
|
|
1617
1717
|
else {
|
|
1618
|
-
return putOperation;
|
|
1718
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1619
1719
|
}
|
|
1620
1720
|
}
|
|
1621
1721
|
}
|
|
1622
1722
|
else {
|
|
1623
1723
|
// Keep existing behavior: next pointers may express document dependencies.
|
|
1624
1724
|
}
|
|
1725
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1625
1726
|
}
|
|
1626
1727
|
else if (isDeleteOperation(operation)) {
|
|
1627
1728
|
if (entry.meta.next.length !== 1) {
|
|
@@ -1669,7 +1770,6 @@ let Documents = (() => {
|
|
|
1669
1770
|
else {
|
|
1670
1771
|
throw new Error("Unsupported operation");
|
|
1671
1772
|
}
|
|
1672
|
-
return operation;
|
|
1673
1773
|
}
|
|
1674
1774
|
catch (error) {
|
|
1675
1775
|
if (error instanceof AccessError) {
|
|
@@ -3320,6 +3420,15 @@ let Documents = (() => {
|
|
|
3320
3420
|
}
|
|
3321
3421
|
async handleChanges(change, reference) {
|
|
3322
3422
|
logger.trace("handleChanges called", change);
|
|
3423
|
+
if (reference == null &&
|
|
3424
|
+
change.added.length >= 2 &&
|
|
3425
|
+
!this.isNativeMode() &&
|
|
3426
|
+
this._index.canUseOrderedWriteSession()) {
|
|
3427
|
+
return this._index.withOrderedWriteSession((orderedSession) => this.handleChangesInOrder(change, reference, orderedSession));
|
|
3428
|
+
}
|
|
3429
|
+
return this.handleChangesInOrder(change, reference);
|
|
3430
|
+
}
|
|
3431
|
+
async handleChangesInOrder(change, reference, orderedSession) {
|
|
3323
3432
|
const isAppendOperation = change?.added.length === 1 ? !!change.added[0] : false;
|
|
3324
3433
|
const removedSet = new Map();
|
|
3325
3434
|
for (const r of change.removed) {
|
|
@@ -3348,6 +3457,7 @@ let Documents = (() => {
|
|
|
3348
3457
|
let modified = new Set();
|
|
3349
3458
|
for (const item of sortedEntries) {
|
|
3350
3459
|
if (!item) {
|
|
3460
|
+
await orderedSession?.flush();
|
|
3351
3461
|
continue;
|
|
3352
3462
|
}
|
|
3353
3463
|
try {
|
|
@@ -3358,6 +3468,7 @@ let Documents = (() => {
|
|
|
3358
3468
|
? reference.operation
|
|
3359
3469
|
: await this.getAppendOperation(item);
|
|
3360
3470
|
if (!payload) {
|
|
3471
|
+
await orderedSession?.flush();
|
|
3361
3472
|
continue;
|
|
3362
3473
|
}
|
|
3363
3474
|
if (isPutOperation(payload) && !removedSet.has(item.hash)) {
|
|
@@ -3391,14 +3502,20 @@ let Documents = (() => {
|
|
|
3391
3502
|
}
|
|
3392
3503
|
}
|
|
3393
3504
|
}
|
|
3394
|
-
let value =
|
|
3395
|
-
|
|
3505
|
+
let value = isReferencedAppendEntry && reference?.document
|
|
3506
|
+
? reference.document
|
|
3507
|
+
: this.index.valueEncoding.decoder(new Uint8Array(payload.data));
|
|
3396
3508
|
// get index key from value
|
|
3397
3509
|
const key = isReferencedAppendEntry && reference?.key
|
|
3398
3510
|
? reference.key
|
|
3399
|
-
: indexerTypes.toId(this.idResolver(
|
|
3511
|
+
: indexerTypes.toId(this.idResolver(this._hasCustomIdResolver
|
|
3512
|
+
? this.index.valueEncoding.decoder(new Uint8Array(payload.data))
|
|
3513
|
+
: value));
|
|
3400
3514
|
// document is already updated with more recent entry
|
|
3401
3515
|
if (modified.has(key.primitive)) {
|
|
3516
|
+
// Duplicate ids deliberately retain the scalar boundary until
|
|
3517
|
+
// their callback and event semantics are proven independently.
|
|
3518
|
+
await orderedSession?.flush();
|
|
3402
3519
|
continue;
|
|
3403
3520
|
}
|
|
3404
3521
|
// if no casual ordering is used, use timestamps to order docs
|
|
@@ -3408,7 +3525,7 @@ let Documents = (() => {
|
|
|
3408
3525
|
? reference.existing
|
|
3409
3526
|
: this.isNativeMode()
|
|
3410
3527
|
? this.getNativeModeIndexedContext(key) || null
|
|
3411
|
-
: (await this.getLocalIndexedContextForChange(key)) || null;
|
|
3528
|
+
: (await this.getLocalIndexedContextForChange(key, orderedSession)) || null;
|
|
3412
3529
|
if (!this.strictHistory && existing) {
|
|
3413
3530
|
// if immutable use oldest, else use newest
|
|
3414
3531
|
let shouldIgnoreChange = this.immutable
|
|
@@ -3417,9 +3534,16 @@ let Documents = (() => {
|
|
|
3417
3534
|
: existing.value.__context.modified >
|
|
3418
3535
|
item.meta.clock.timestamp.wallTime;
|
|
3419
3536
|
if (shouldIgnoreChange) {
|
|
3537
|
+
await orderedSession?.flush();
|
|
3420
3538
|
continue;
|
|
3421
3539
|
}
|
|
3422
3540
|
}
|
|
3541
|
+
const useOrderedWrite = orderedSession != null &&
|
|
3542
|
+
existing == null &&
|
|
3543
|
+
!(value instanceof Program);
|
|
3544
|
+
if (!useOrderedWrite) {
|
|
3545
|
+
await orderedSession?.flush();
|
|
3546
|
+
}
|
|
3423
3547
|
// Program specific
|
|
3424
3548
|
if (value instanceof Program) {
|
|
3425
3549
|
// if replicator, then open
|
|
@@ -3433,13 +3557,14 @@ let Documents = (() => {
|
|
|
3433
3557
|
modified.add(key.primitive);
|
|
3434
3558
|
continue;
|
|
3435
3559
|
}
|
|
3436
|
-
const { context, indexable } = await this._index.put(value, key, item, existing);
|
|
3560
|
+
const { context, indexable } = await this._index.put(value, key, item, existing, useOrderedWrite ? orderedSession : undefined);
|
|
3437
3561
|
documentsChanged?.added.push(coerceWithIndexed(coerceWithContext(value, context), indexable));
|
|
3438
3562
|
modified.add(key.primitive);
|
|
3439
3563
|
}
|
|
3440
3564
|
else if ((isDeleteOperation(payload) && !removedSet.has(item.hash)) ||
|
|
3441
3565
|
isPutOperation(payload) ||
|
|
3442
3566
|
removedSet.has(item.hash)) {
|
|
3567
|
+
await orderedSession?.flush();
|
|
3443
3568
|
if (!documentsChanged &&
|
|
3444
3569
|
(await this.collectRemovedPutChangeFromNativeId(payload, modified))) {
|
|
3445
3570
|
continue;
|
|
@@ -3453,11 +3578,13 @@ let Documents = (() => {
|
|
|
3453
3578
|
}
|
|
3454
3579
|
catch (error) {
|
|
3455
3580
|
if (error instanceof AccessError) {
|
|
3581
|
+
await orderedSession?.flush();
|
|
3456
3582
|
continue;
|
|
3457
3583
|
}
|
|
3458
3584
|
throw error;
|
|
3459
3585
|
}
|
|
3460
3586
|
}
|
|
3587
|
+
await orderedSession?.flush();
|
|
3461
3588
|
if (canRemoveByIndexedHead && change.removed.length > 0) {
|
|
3462
3589
|
const handled = await this.collectRemovedDocumentChangesFromIndexedHeads(change.removed, modified);
|
|
3463
3590
|
const remainingRemoved = change.removed.filter((entry) => !handled.has(entry.hash));
|