@agentshouse/mdruntime 0.1.0-alpha.45 → 0.1.0-alpha.46
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/adapter.d.ts +2 -3
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/bootstrap.d.ts +2 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +1 -1
- package/dist/bootstrap.js.map +1 -1
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -6
- package/dist/change-set.js.map +1 -1
- package/dist/collection.d.ts +4 -3
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +14 -49
- package/dist/collection.js.map +1 -1
- package/dist/connection.d.ts +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +29 -27
- package/dist/connection.js.map +1 -1
- package/dist/memory.js +4 -2
- package/dist/memory.js.map +1 -1
- package/dist/refresh.d.ts +1 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +5 -5
- package/dist/refresh.js.map +1 -1
- package/dist/replica.d.ts +6 -2
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +16 -3
- package/dist/replica.js.map +1 -1
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +2 -2
- package/dist/save.js.map +1 -1
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +1 -1
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -12,7 +12,7 @@ import { MD_MODEL, parseCollection, validRoot } from './collection.js';
|
|
|
12
12
|
import { createLog } from './log.js';
|
|
13
13
|
import { refreshRoom } from './refresh.js';
|
|
14
14
|
import { buildBatch } from './save.js';
|
|
15
|
-
import { applyReturned, compositionOf, landed, readConfirmed, replicaOf, withdrawals } from './replica.js';
|
|
15
|
+
import { applyReturned, compositionOf, landed, readConfirmed, readReclassified, replicaOf, sameMembership, withdrawals } from './replica.js';
|
|
16
16
|
import { changedParts, changesOf, held, readParts, returnedInto, underneath } from './room-draft.js';
|
|
17
17
|
import { settled, same, saving, STARTING, transferring } from './status.js';
|
|
18
18
|
import { detectStorageLoss, nextGeneration } from './durability.js';
|
|
@@ -41,7 +41,14 @@ function declaredSelection(room) {
|
|
|
41
41
|
if (selection === undefined) return true;
|
|
42
42
|
if (!Array.isArray(selection.roots) || selection.roots.length === 0) return false;
|
|
43
43
|
if (!declaredIdentity(selection.attachedModel)) return false;
|
|
44
|
-
return selection.roots.every((root, index)=>validRoot(root) && root !== '' &&
|
|
44
|
+
return selection.roots.every((root, index)=>validRoot(root) && root !== '' && selection.roots.every((other, at)=>at === index || !within(other, root)));
|
|
45
|
+
}
|
|
46
|
+
function declaredUntypedFolders(room) {
|
|
47
|
+
const roots = room.untypedFolders;
|
|
48
|
+
if (roots === undefined) return true;
|
|
49
|
+
if (!Array.isArray(roots) || roots.length === 0) return false;
|
|
50
|
+
const selected = room.typedSelection?.roots ?? [];
|
|
51
|
+
return roots.every((root, index)=>validRoot(root) && root !== '' && roots.every((other, at)=>at === index || !within(other, root)) && selected.every((other)=>!within(other, root) && !within(root, other)));
|
|
45
52
|
}
|
|
46
53
|
export function createMdRuntime(options) {
|
|
47
54
|
return composeRuntime(options).md;
|
|
@@ -94,7 +101,6 @@ export function composeRuntime(options) {
|
|
|
94
101
|
selectionModel: savedModel(record.locator, 'typed-selection')
|
|
95
102
|
});
|
|
96
103
|
}
|
|
97
|
-
const mismatchedRoots = new Set();
|
|
98
104
|
let refusal = null;
|
|
99
105
|
let storageLoss = null;
|
|
100
106
|
let status = STARTING;
|
|
@@ -428,7 +434,6 @@ export function composeRuntime(options) {
|
|
|
428
434
|
const selection = room.typedSelection ?? null;
|
|
429
435
|
rooms.set(room.locator, {
|
|
430
436
|
name: room.name,
|
|
431
|
-
collectionRoot: room.collectionRoot,
|
|
432
437
|
locator: room.locator,
|
|
433
438
|
operations: room.operations,
|
|
434
439
|
replica: room.replica,
|
|
@@ -439,6 +444,7 @@ export function composeRuntime(options) {
|
|
|
439
444
|
attachedModel: selection.attachedModel,
|
|
440
445
|
model: modelTypes(modelOf(room.locator, 'typed-selection'))
|
|
441
446
|
},
|
|
447
|
+
untypedFolders: room.untypedFolders ?? [],
|
|
442
448
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
443
449
|
roomVersion: replicas.get(room.locator)?.confirmed.record.roomVersion ?? null,
|
|
444
450
|
synchronizationAvailable,
|
|
@@ -578,7 +584,6 @@ export function composeRuntime(options) {
|
|
|
578
584
|
selectionModel
|
|
579
585
|
};
|
|
580
586
|
const read = readConfirmed(retyped, prior?.confirmed);
|
|
581
|
-
if (read.kind === 'unconfirmed') continue;
|
|
582
587
|
const confirmed = read.kind === 'staged' ? read.confirmed : {
|
|
583
588
|
record: retyped,
|
|
584
589
|
collection: parseCollection(retyped.documents, compositionOf(retyped))
|
|
@@ -598,7 +603,8 @@ export function composeRuntime(options) {
|
|
|
598
603
|
roots: record.typedSelection.roots,
|
|
599
604
|
attachedModel: record.typedSelection.attachedModel,
|
|
600
605
|
model: modelTypes(selectionModel)
|
|
601
|
-
}
|
|
606
|
+
},
|
|
607
|
+
untypedFolders: record.untypedFolders
|
|
602
608
|
});
|
|
603
609
|
}
|
|
604
610
|
if (read.kind === 'refused') {
|
|
@@ -784,10 +790,6 @@ export function composeRuntime(options) {
|
|
|
784
790
|
if (replica === undefined || room === undefined) {
|
|
785
791
|
throw new Error(`No Local Replica for ${locator}`);
|
|
786
792
|
}
|
|
787
|
-
if (mismatchedRoots.has(locator)) return {
|
|
788
|
-
outcome: 'refused',
|
|
789
|
-
rule: 'collection-root-mismatch'
|
|
790
|
-
};
|
|
791
793
|
const saved = [];
|
|
792
794
|
for (const { path, revision } of named){
|
|
793
795
|
const record = roomDrafts.get(locator)?.get(path);
|
|
@@ -1033,10 +1035,10 @@ export function composeRuntime(options) {
|
|
|
1033
1035
|
}
|
|
1034
1036
|
return target === undefined || reachedBy(locator, target) ? undefined : target;
|
|
1035
1037
|
}
|
|
1036
|
-
async function pullRefresh(authorized, confirmed,
|
|
1038
|
+
async function pullRefresh(authorized, confirmed, minPosition) {
|
|
1037
1039
|
if (!continuing()) return unconfirmed;
|
|
1038
1040
|
try {
|
|
1039
|
-
const result = await refreshRoom(options.adapter, authorized, confirmed, continuing,
|
|
1041
|
+
const result = await refreshRoom(options.adapter, authorized, confirmed, continuing, minPosition);
|
|
1040
1042
|
const detail = result.kind === 'advanced' ? result.confirmed.record.roomVersion : result.kind;
|
|
1041
1043
|
journal.record(`transfer refresh ${confirmed.record.locator} ${detail}`);
|
|
1042
1044
|
return result;
|
|
@@ -1458,7 +1460,7 @@ export function composeRuntime(options) {
|
|
|
1458
1460
|
const epoch = modelEpoch.get(key) ?? 0;
|
|
1459
1461
|
const previous = modelOf(room.locator, attached);
|
|
1460
1462
|
const heldBefore = replicas.get(room.locator)?.confirmed.record;
|
|
1461
|
-
if (JSON.stringify(previous) === JSON.stringify(next) && (heldBefore === undefined || JSON.stringify(heldBefore.operations) === JSON.stringify(room.operations) && JSON.stringify(heldBefore.replica) === JSON.stringify(room.replica) && JSON.stringify(heldBefore.attachedModel) === JSON.stringify(room.attachedModel) && JSON.stringify(heldBefore.typedSelection) === JSON.stringify(room.typedSelection ?? null))) return;
|
|
1463
|
+
if (JSON.stringify(previous) === JSON.stringify(next) && (heldBefore === undefined || JSON.stringify(heldBefore.operations) === JSON.stringify(room.operations) && JSON.stringify(heldBefore.replica) === JSON.stringify(room.replica) && JSON.stringify(heldBefore.attachedModel) === JSON.stringify(room.attachedModel) && JSON.stringify(heldBefore.typedSelection) === JSON.stringify(room.typedSelection ?? null) && JSON.stringify(heldBefore.untypedFolders) === JSON.stringify(room.untypedFolders ?? []))) return;
|
|
1462
1464
|
if (next.status === 'unavailable') {
|
|
1463
1465
|
invalidModels.add(key);
|
|
1464
1466
|
liveModels.delete(key);
|
|
@@ -1468,24 +1470,31 @@ export function composeRuntime(options) {
|
|
|
1468
1470
|
if (next.status !== 'unavailable' && epoch !== (modelEpoch.get(key) ?? 0)) return;
|
|
1469
1471
|
const held = replicas.get(room.locator);
|
|
1470
1472
|
if (held !== undefined) {
|
|
1471
|
-
const
|
|
1473
|
+
const declared = {
|
|
1472
1474
|
...held.confirmed.record,
|
|
1473
1475
|
operations: room.operations,
|
|
1474
1476
|
replica: room.replica,
|
|
1475
1477
|
attachedModel: room.attachedModel,
|
|
1476
1478
|
typedSelection: room.typedSelection ?? null,
|
|
1479
|
+
untypedFolders: room.untypedFolders ?? [],
|
|
1477
1480
|
...attached === 'collection' ? {
|
|
1478
1481
|
model: next
|
|
1479
1482
|
} : {
|
|
1480
1483
|
selectionModel: next
|
|
1481
1484
|
}
|
|
1482
1485
|
};
|
|
1486
|
+
const reclassified = sameMembership(declared, held.confirmed.record) ? readConfirmed(declared, held.confirmed) : readReclassified(declared, held.confirmed);
|
|
1487
|
+
const record = reclassified.kind === 'staged' ? declared : {
|
|
1488
|
+
...declared,
|
|
1489
|
+
typedSelection: held.confirmed.record.typedSelection,
|
|
1490
|
+
untypedFolders: held.confirmed.record.untypedFolders
|
|
1491
|
+
};
|
|
1492
|
+
const read = reclassified.kind === 'deferred' ? readConfirmed(record, held.confirmed) : reclassified;
|
|
1483
1493
|
await local.write({
|
|
1484
1494
|
next: record,
|
|
1485
1495
|
previous: held.confirmed.record,
|
|
1486
1496
|
queue: held.queue
|
|
1487
1497
|
});
|
|
1488
|
-
const read = readConfirmed(record, held.confirmed);
|
|
1489
1498
|
if (read.kind === 'staged') {
|
|
1490
1499
|
replicas.set(room.locator, replicaOf(read.confirmed, held.queue, rewriting(), held));
|
|
1491
1500
|
if (declarationRefusals.delete(room.locator)) {
|
|
@@ -1535,7 +1544,6 @@ export function composeRuntime(options) {
|
|
|
1535
1544
|
answer = await options.adapter.model(authorized, selection === null ? {
|
|
1536
1545
|
locator: room.locator,
|
|
1537
1546
|
attached: 'collection',
|
|
1538
|
-
collectionRoot: room.collectionRoot,
|
|
1539
1547
|
model: declared
|
|
1540
1548
|
} : {
|
|
1541
1549
|
locator: room.locator,
|
|
@@ -1736,10 +1744,7 @@ export function composeRuntime(options) {
|
|
|
1736
1744
|
notifyReady();
|
|
1737
1745
|
return;
|
|
1738
1746
|
}
|
|
1739
|
-
mismatchedRoots.clear();
|
|
1740
1747
|
for (const room of result.rooms){
|
|
1741
|
-
const held = replicas.get(room.locator)?.confirmed.record;
|
|
1742
|
-
const malformed = !validRoot(room.collectionRoot);
|
|
1743
1748
|
if (room.operations === undefined || ![
|
|
1744
1749
|
'read',
|
|
1745
1750
|
'sync',
|
|
@@ -1760,16 +1765,13 @@ export function composeRuntime(options) {
|
|
|
1760
1765
|
notifyReady();
|
|
1761
1766
|
return;
|
|
1762
1767
|
}
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
|
|
1768
|
+
if (!declaredUntypedFolders(room)) {
|
|
1769
|
+
journal.record(`invalid untyped folder declaration ${room.locator}`);
|
|
1770
|
+
await refuse('missing-required-guarantee');
|
|
1771
|
+
notifyReady();
|
|
1772
|
+
return;
|
|
1766
1773
|
}
|
|
1767
1774
|
}
|
|
1768
|
-
if (mismatchedRoots.size > 0) {
|
|
1769
|
-
await refuse('missing-required-guarantee');
|
|
1770
|
-
notifyReady();
|
|
1771
|
-
return;
|
|
1772
|
-
}
|
|
1773
1775
|
const declared = new Set(result.capabilities.map((capability)=>capability.name));
|
|
1774
1776
|
for (const required of options.requiredGuarantees){
|
|
1775
1777
|
if (!knownCapabilities.has(required) || !declared.has(required)) {
|