@peerbit/document 15.0.13 → 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 +4 -0
- package/dist/src/program.d.ts.map +1 -1
- package/dist/src/program.js +140 -39
- package/dist/src/program.js.map +1 -1
- package/package.json +11 -11
- package/src/callback-detachment.ts +308 -0
- package/src/domain.ts +11 -3
- package/src/program.ts +220 -48
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) => {
|
|
@@ -1216,6 +1288,7 @@ let Documents = (() => {
|
|
|
1216
1288
|
(typeof idProperty === "string"
|
|
1217
1289
|
? (obj) => obj[idProperty]
|
|
1218
1290
|
: (obj) => indexerTypes.extractFieldValue(obj, idProperty));
|
|
1291
|
+
this._hasCustomIdResolver = options.id != null;
|
|
1219
1292
|
this.idResolver = idResolver;
|
|
1220
1293
|
this.strictHistory = options.strictHistory ?? false;
|
|
1221
1294
|
this._hasLogTrim = options.log?.trim != null;
|
|
@@ -1252,7 +1325,9 @@ let Documents = (() => {
|
|
|
1252
1325
|
// B12: the historical document->log compatibility mapping (6 -> log v8,
|
|
1253
1326
|
// 7 -> log v9) is retired; the rejection at the top of open() fires for
|
|
1254
1327
|
// any defined value before this point.
|
|
1255
|
-
this.domain = options.domain
|
|
1328
|
+
this.domain = options.domain
|
|
1329
|
+
? this.detachDomainEntryCallback(options.domain(this))
|
|
1330
|
+
: undefined;
|
|
1256
1331
|
let keepFunction;
|
|
1257
1332
|
if (options?.keep === "self") {
|
|
1258
1333
|
this.keepCache = new Set();
|
|
@@ -1293,7 +1368,16 @@ let Documents = (() => {
|
|
|
1293
1368
|
};
|
|
1294
1369
|
}
|
|
1295
1370
|
else {
|
|
1296
|
-
|
|
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;
|
|
1297
1381
|
}
|
|
1298
1382
|
await this.log.open({
|
|
1299
1383
|
encoding: BORSH_ENCODING_OPERATION,
|
|
@@ -1316,7 +1400,7 @@ let Documents = (() => {
|
|
|
1316
1400
|
distributionDebounceTime: options?.distributionDebounceTime,
|
|
1317
1401
|
strictFullReplicaFallback: false,
|
|
1318
1402
|
domain: options?.domain
|
|
1319
|
-
? () => options.domain(this)
|
|
1403
|
+
? () => this.detachDomainEntryCallback(options.domain(this))
|
|
1320
1404
|
: undefined,
|
|
1321
1405
|
eagerBlocks: options?.eagerBlocks,
|
|
1322
1406
|
fanout: options?.fanout,
|
|
@@ -1375,41 +1459,41 @@ let Documents = (() => {
|
|
|
1375
1459
|
return false;
|
|
1376
1460
|
}
|
|
1377
1461
|
try {
|
|
1378
|
-
|
|
1462
|
+
const operation = l0;
|
|
1379
1463
|
if (this._optionCanPerform) {
|
|
1380
1464
|
if (this._optionCanPerformNativePolicy && this.isNativeMode()) {
|
|
1381
1465
|
return this.nativeCanPerformAllowsAppend(this._optionCanPerformNativePolicy, operation, entry, reference?.document);
|
|
1382
1466
|
}
|
|
1383
|
-
let document
|
|
1384
|
-
if (
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
}
|
|
1393
|
-
else if (isDeleteOperation(l0)) {
|
|
1394
|
-
// Nothing to do here by default.
|
|
1395
|
-
// Checking if the document exists is not necessary since it
|
|
1396
|
-
// might already be deleted.
|
|
1397
|
-
}
|
|
1398
|
-
else {
|
|
1399
|
-
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;
|
|
1400
1476
|
}
|
|
1401
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
|
+
}
|
|
1402
1486
|
const previousEntries = this._optionCanPerformNativePolicy &&
|
|
1403
1487
|
isPutOperation(operation) &&
|
|
1404
1488
|
canPerformPolicyNeedsPreviousEntries(this._optionCanPerformNativePolicy)
|
|
1405
|
-
? await this.resolveCanPerformPreviousEntries(entry)
|
|
1489
|
+
? (await this.resolveCanPerformPreviousEntries(entry)).map(detachEntryPayloadForCallback)
|
|
1406
1490
|
: undefined;
|
|
1407
1491
|
const deleteValue = this._optionCanPerformNativePolicy &&
|
|
1408
1492
|
isDeleteOperation(operation) &&
|
|
1409
1493
|
canPerformPolicyNeedsDeleteValue(this._optionCanPerformNativePolicy)
|
|
1410
1494
|
? await this.resolveCanPerformDeleteValue(operation)
|
|
1411
1495
|
: undefined;
|
|
1412
|
-
if (!(await this._optionCanPerform(isPutOperation(operation)
|
|
1496
|
+
if (!(await this._optionCanPerform(detachCanPerformCallbackProperties(isPutOperation(operation)
|
|
1413
1497
|
? {
|
|
1414
1498
|
type: "put",
|
|
1415
1499
|
value: document,
|
|
@@ -1422,7 +1506,7 @@ let Documents = (() => {
|
|
|
1422
1506
|
value: deleteValue,
|
|
1423
1507
|
operation,
|
|
1424
1508
|
entry: entry,
|
|
1425
|
-
}))) {
|
|
1509
|
+
})))) {
|
|
1426
1510
|
return false;
|
|
1427
1511
|
}
|
|
1428
1512
|
}
|
|
@@ -1485,6 +1569,9 @@ let Documents = (() => {
|
|
|
1485
1569
|
}
|
|
1486
1570
|
return entries;
|
|
1487
1571
|
}
|
|
1572
|
+
detachDocumentValueForCallback(document) {
|
|
1573
|
+
return this._index.valueEncoding.decoder(this._index.valueEncoding.encoder(document));
|
|
1574
|
+
}
|
|
1488
1575
|
async resolveCanPerformDeleteValue(operation, options) {
|
|
1489
1576
|
const key = operation.key instanceof indexerTypes.IdKey
|
|
1490
1577
|
? operation.key
|
|
@@ -1496,11 +1583,11 @@ let Documents = (() => {
|
|
|
1496
1583
|
}
|
|
1497
1584
|
const indexedDocument = await this.getLocalIdentityDocumentByHead(existingHead);
|
|
1498
1585
|
if (indexedDocument) {
|
|
1499
|
-
return indexedDocument;
|
|
1586
|
+
return this.detachDocumentValueForCallback(indexedDocument);
|
|
1500
1587
|
}
|
|
1501
1588
|
const indexedPolicyDocument = await this.getLocalIndexedDocumentForNativeDeletePolicy(key);
|
|
1502
1589
|
if (indexedPolicyDocument) {
|
|
1503
|
-
return indexedPolicyDocument;
|
|
1590
|
+
return deserialize(serialize(indexedPolicyDocument), this._index.indexedType);
|
|
1504
1591
|
}
|
|
1505
1592
|
if (options?.allowEntryFallback === false) {
|
|
1506
1593
|
return;
|
|
@@ -1512,7 +1599,7 @@ let Documents = (() => {
|
|
|
1512
1599
|
if (!isPutOperation(existingOperation)) {
|
|
1513
1600
|
return;
|
|
1514
1601
|
}
|
|
1515
|
-
return this._index.valueEncoding.decoder(existingOperation.data);
|
|
1602
|
+
return this._index.valueEncoding.decoder(new Uint8Array(existingOperation.data));
|
|
1516
1603
|
}
|
|
1517
1604
|
async _canAppend(entry, reference) {
|
|
1518
1605
|
const resolve = async (history) => {
|
|
@@ -1554,9 +1641,13 @@ let Documents = (() => {
|
|
|
1554
1641
|
if (isPutOperation(operation)) {
|
|
1555
1642
|
// check nexts
|
|
1556
1643
|
const putOperation = operation;
|
|
1644
|
+
let decodedDocumentForCanPerform;
|
|
1645
|
+
let hasDecodedDocumentForCanPerform = false;
|
|
1557
1646
|
let keyValue;
|
|
1558
1647
|
if (reference?.document) {
|
|
1559
|
-
keyValue = this.idResolver(
|
|
1648
|
+
keyValue = this.idResolver(this._hasCustomIdResolver
|
|
1649
|
+
? this.index.valueEncoding.decoder(new Uint8Array(putOperation.data))
|
|
1650
|
+
: reference.document);
|
|
1560
1651
|
}
|
|
1561
1652
|
else {
|
|
1562
1653
|
keyValue = await this.getNativeDocumentIdFromPutOperation(putOperation);
|
|
@@ -1564,8 +1655,13 @@ let Documents = (() => {
|
|
|
1564
1655
|
if (this.isNativeMode()) {
|
|
1565
1656
|
return false;
|
|
1566
1657
|
}
|
|
1567
|
-
const value = this.index.valueEncoding.decoder(
|
|
1568
|
-
|
|
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
|
+
}
|
|
1569
1665
|
keyValue = this.idResolver(value);
|
|
1570
1666
|
}
|
|
1571
1667
|
}
|
|
@@ -1596,7 +1692,7 @@ let Documents = (() => {
|
|
|
1596
1692
|
if (entry.meta.next.length > 0) {
|
|
1597
1693
|
return false; // can not append to immutable document
|
|
1598
1694
|
}
|
|
1599
|
-
return putOperation;
|
|
1695
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1600
1696
|
}
|
|
1601
1697
|
else {
|
|
1602
1698
|
if (this.strictHistory) {
|
|
@@ -1605,7 +1701,7 @@ let Documents = (() => {
|
|
|
1605
1701
|
return false;
|
|
1606
1702
|
}
|
|
1607
1703
|
if (entry.meta.next[0] === existingContext.head) {
|
|
1608
|
-
return putOperation;
|
|
1704
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1609
1705
|
}
|
|
1610
1706
|
const prevEntry = await this.log.log.entryIndex.get(existingContext.head);
|
|
1611
1707
|
if (!prevEntry) {
|
|
@@ -1614,16 +1710,19 @@ let Documents = (() => {
|
|
|
1614
1710
|
return false;
|
|
1615
1711
|
}
|
|
1616
1712
|
const referenceHistoryCorrectly = await pointsToHistory(prevEntry);
|
|
1617
|
-
return referenceHistoryCorrectly
|
|
1713
|
+
return referenceHistoryCorrectly
|
|
1714
|
+
? this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform)
|
|
1715
|
+
: false;
|
|
1618
1716
|
}
|
|
1619
1717
|
else {
|
|
1620
|
-
return putOperation;
|
|
1718
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1621
1719
|
}
|
|
1622
1720
|
}
|
|
1623
1721
|
}
|
|
1624
1722
|
else {
|
|
1625
1723
|
// Keep existing behavior: next pointers may express document dependencies.
|
|
1626
1724
|
}
|
|
1725
|
+
return this.acceptPutOperation(putOperation, decodedDocumentForCanPerform, hasDecodedDocumentForCanPerform);
|
|
1627
1726
|
}
|
|
1628
1727
|
else if (isDeleteOperation(operation)) {
|
|
1629
1728
|
if (entry.meta.next.length !== 1) {
|
|
@@ -1671,7 +1770,6 @@ let Documents = (() => {
|
|
|
1671
1770
|
else {
|
|
1672
1771
|
throw new Error("Unsupported operation");
|
|
1673
1772
|
}
|
|
1674
|
-
return operation;
|
|
1675
1773
|
}
|
|
1676
1774
|
catch (error) {
|
|
1677
1775
|
if (error instanceof AccessError) {
|
|
@@ -3404,12 +3502,15 @@ let Documents = (() => {
|
|
|
3404
3502
|
}
|
|
3405
3503
|
}
|
|
3406
3504
|
}
|
|
3407
|
-
let value =
|
|
3408
|
-
|
|
3505
|
+
let value = isReferencedAppendEntry && reference?.document
|
|
3506
|
+
? reference.document
|
|
3507
|
+
: this.index.valueEncoding.decoder(new Uint8Array(payload.data));
|
|
3409
3508
|
// get index key from value
|
|
3410
3509
|
const key = isReferencedAppendEntry && reference?.key
|
|
3411
3510
|
? reference.key
|
|
3412
|
-
: indexerTypes.toId(this.idResolver(
|
|
3511
|
+
: indexerTypes.toId(this.idResolver(this._hasCustomIdResolver
|
|
3512
|
+
? this.index.valueEncoding.decoder(new Uint8Array(payload.data))
|
|
3513
|
+
: value));
|
|
3413
3514
|
// document is already updated with more recent entry
|
|
3414
3515
|
if (modified.has(key.primitive)) {
|
|
3415
3516
|
// Duplicate ids deliberately retain the scalar boundary until
|