doxum 0.1.28 → 0.1.29
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/advanced.cjs +1 -1
- package/dist/advanced.js +1 -1
- package/dist/{driver-B5vdPohL.js → driver-B7RR-VfX.js} +31 -12
- package/dist/driver-B7RR-VfX.js.map +1 -0
- package/dist/{driver-BL91gn7_.cjs → driver-CN3dGxQI.cjs} +31 -12
- package/dist/driver-CN3dGxQI.cjs.map +1 -0
- package/dist/index.cjs +200 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +200 -131
- package/dist/index.js.map +1 -1
- package/dist/local-sync.cjs +1 -1
- package/dist/local-sync.js +1 -1
- package/dist/{transform-DUleAsG0.cjs → transform-B6YxfR0R.cjs} +176 -50
- package/dist/transform-B6YxfR0R.cjs.map +1 -0
- package/dist/{transform-B4T3AcJr.js → transform-BQY9I6il.js} +147 -51
- package/dist/transform-BQY9I6il.js.map +1 -0
- package/package.json +1 -1
- package/dist/driver-B5vdPohL.js.map +0 -1
- package/dist/driver-BL91gn7_.cjs.map +0 -1
- package/dist/transform-B4T3AcJr.js.map +0 -1
- package/dist/transform-DUleAsG0.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_transform = require("./transform-
|
|
2
|
+
const require_transform = require("./transform-B6YxfR0R.cjs");
|
|
3
3
|
const require_record = require("./record-ChYUi8PP.cjs");
|
|
4
|
-
const require_driver = require("./driver-
|
|
4
|
+
const require_driver = require("./driver-CN3dGxQI.cjs");
|
|
5
5
|
//#region core/src/schema/model.ts
|
|
6
6
|
const schemaNodeOf = (schema) => schema;
|
|
7
7
|
const collectionEntryNode = (node) => node.kind === "map" || node.kind === "table" || node.kind === "list" ? node.value : void 0;
|
|
@@ -569,18 +569,44 @@ const moveSelection = (current, selection, position) => {
|
|
|
569
569
|
selected.add(key);
|
|
570
570
|
}
|
|
571
571
|
const moved = [];
|
|
572
|
-
|
|
573
|
-
|
|
572
|
+
let remainingLength = 0;
|
|
573
|
+
let anchorIndex = -1;
|
|
574
|
+
const anchoredKey = position && ("before" in position ? position.before : "after" in position ? position.after : void 0);
|
|
575
|
+
for (const key of current) {
|
|
576
|
+
if (selected.has(key)) {
|
|
577
|
+
moved.push(key);
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
if (key === anchoredKey) anchorIndex = remainingLength;
|
|
581
|
+
remainingLength++;
|
|
582
|
+
}
|
|
574
583
|
if (moved.length !== selected.size) return { kind: "missing" };
|
|
575
|
-
|
|
576
|
-
|
|
584
|
+
let insertion;
|
|
585
|
+
if (!position || "at" in position && position.at === "end") insertion = remainingLength;
|
|
586
|
+
else if ("at" in position) {
|
|
587
|
+
if (position.at !== "start") return { kind: "invalid-anchor" };
|
|
588
|
+
insertion = 0;
|
|
589
|
+
} else {
|
|
590
|
+
if (anchorIndex < 0) return { kind: "invalid-anchor" };
|
|
591
|
+
insertion = "before" in position ? anchorIndex : anchorIndex + 1;
|
|
592
|
+
}
|
|
593
|
+
const order = new Array(current.length);
|
|
594
|
+
let outputIndex = 0;
|
|
595
|
+
let remainingIndex = 0;
|
|
596
|
+
let inserted = false;
|
|
597
|
+
for (const key of current) {
|
|
598
|
+
if (selected.has(key)) continue;
|
|
599
|
+
if (!inserted && remainingIndex === insertion) {
|
|
600
|
+
for (const movedKey of moved) order[outputIndex++] = movedKey;
|
|
601
|
+
inserted = true;
|
|
602
|
+
}
|
|
603
|
+
order[outputIndex++] = key;
|
|
604
|
+
remainingIndex++;
|
|
605
|
+
}
|
|
606
|
+
if (!inserted) for (const movedKey of moved) order[outputIndex++] = movedKey;
|
|
577
607
|
return {
|
|
578
608
|
kind: "ok",
|
|
579
|
-
order
|
|
580
|
-
...remaining.slice(0, insertion),
|
|
581
|
-
...moved,
|
|
582
|
-
...remaining.slice(insertion)
|
|
583
|
-
]
|
|
609
|
+
order
|
|
584
610
|
};
|
|
585
611
|
};
|
|
586
612
|
const index = (keys, anchor) => {
|
|
@@ -1373,6 +1399,17 @@ const contains = (parent, child) => {
|
|
|
1373
1399
|
}
|
|
1374
1400
|
return true;
|
|
1375
1401
|
};
|
|
1402
|
+
/** Compare a virtual `[...base, segment]` address with an existing address without allocating it. */
|
|
1403
|
+
const compareExtended = (base, segment, other) => {
|
|
1404
|
+
require_transform.profile.address.prefixComparison();
|
|
1405
|
+
const length = base.length + 1;
|
|
1406
|
+
const common = Math.min(length, other.length);
|
|
1407
|
+
for (let index = 0; index < common; index += 1) {
|
|
1408
|
+
require_transform.profile.address.segmentCompared();
|
|
1409
|
+
if ((index < base.length ? base[index] : segment) !== other[index]) return "disjoint";
|
|
1410
|
+
}
|
|
1411
|
+
return length === other.length ? "equal" : length < other.length ? "ancestor" : "descendant";
|
|
1412
|
+
};
|
|
1376
1413
|
//#endregion
|
|
1377
1414
|
//#region core/src/impact.ts
|
|
1378
1415
|
const createImpact = (schema, changes) => {
|
|
@@ -1799,7 +1836,7 @@ const reconstructBefore = (node, current, records, offset) => {
|
|
|
1799
1836
|
};
|
|
1800
1837
|
const sealMembers = (fact, changes) => {
|
|
1801
1838
|
const members = [];
|
|
1802
|
-
for (const member of fact.members
|
|
1839
|
+
if (fact.members) for (const member of fact.members.values()) {
|
|
1803
1840
|
if (!member) continue;
|
|
1804
1841
|
const key = memberKey(fact, member.key);
|
|
1805
1842
|
const present = Object.hasOwn(fact.parent, key);
|
|
@@ -1883,7 +1920,7 @@ var ChangeRecorder = class {
|
|
|
1883
1920
|
absorb(at, node, value, present) {
|
|
1884
1921
|
const index = this.indexGroups();
|
|
1885
1922
|
const children = [];
|
|
1886
|
-
index.
|
|
1923
|
+
index.forEachOverlap(at, (fact) => {
|
|
1887
1924
|
if (fact.kind === "members") {
|
|
1888
1925
|
if (fact.at.length < at.length) {
|
|
1889
1926
|
if (fact.at.length + 1 === at.length) {
|
|
@@ -1902,18 +1939,19 @@ var ChangeRecorder = class {
|
|
|
1902
1939
|
at: fact.at,
|
|
1903
1940
|
group: fact
|
|
1904
1941
|
});
|
|
1905
|
-
for (const member of fact.members
|
|
1942
|
+
if (fact.members) for (const member of fact.members.values()) {
|
|
1906
1943
|
if (!member) continue;
|
|
1907
|
-
const
|
|
1908
|
-
if (
|
|
1944
|
+
const compared = compareExtended(fact.at, member.key, at);
|
|
1945
|
+
if (compared !== "equal" && compared !== "descendant") continue;
|
|
1946
|
+
children.push({
|
|
1909
1947
|
kind: "member",
|
|
1910
|
-
at:
|
|
1948
|
+
at: fact.at.concat(member.key),
|
|
1911
1949
|
group: fact,
|
|
1912
1950
|
member
|
|
1913
1951
|
});
|
|
1914
1952
|
}
|
|
1915
1953
|
} else if (contains(at, fact.at)) children.push(fact);
|
|
1916
|
-
})
|
|
1954
|
+
});
|
|
1917
1955
|
if (present) value = reconstructBefore(node, value, children, at.length);
|
|
1918
1956
|
this.releaseCovered(children);
|
|
1919
1957
|
return value;
|
|
@@ -1931,7 +1969,9 @@ var ChangeRecorder = class {
|
|
|
1931
1969
|
(changedGroups ??= /* @__PURE__ */ new Set()).add(child.group);
|
|
1932
1970
|
} else this.unregister(child);
|
|
1933
1971
|
}
|
|
1934
|
-
|
|
1972
|
+
if (changedGroups) {
|
|
1973
|
+
for (const group of changedGroups) if (emptyGroup(group)) this.unregister(group);
|
|
1974
|
+
}
|
|
1935
1975
|
}
|
|
1936
1976
|
register(fact) {
|
|
1937
1977
|
this.facts.add(fact);
|
|
@@ -2880,12 +2920,7 @@ const createKeyedGet = (source, key, equality = Object.is) => {
|
|
|
2880
2920
|
} else if (sourceRevision !== collection.revision) {
|
|
2881
2921
|
const change = collection.change;
|
|
2882
2922
|
if (!change || change.kind === "reset") affected = true;
|
|
2883
|
-
else if (selected !== void 0)
|
|
2884
|
-
for (const changedKey of require_transform.collectionChange.keys(change)) if (changedKey === selected) {
|
|
2885
|
-
affected = true;
|
|
2886
|
-
break;
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2923
|
+
else if (selected !== void 0) affected = require_transform.collectionChangeTouchesKey(change, selected);
|
|
2889
2924
|
}
|
|
2890
2925
|
if (affected) output.output.set(selected === void 0 ? void 0 : collection.read.get(selected));
|
|
2891
2926
|
sourceRevision = collection.revision;
|
|
@@ -3049,9 +3084,7 @@ function createKeyedGroupBy(source, dependenciesOrSelector, maybeSelector) {
|
|
|
3049
3084
|
outputs: [{
|
|
3050
3085
|
kind: "collection",
|
|
3051
3086
|
equality: (previous, next) => {
|
|
3052
|
-
|
|
3053
|
-
const right = next;
|
|
3054
|
-
return left.length === right.length && left.every((key, index) => key === right[index]);
|
|
3087
|
+
return require_transform.sameArray(previous, next);
|
|
3055
3088
|
}
|
|
3056
3089
|
}],
|
|
3057
3090
|
create: () => {
|
|
@@ -3095,11 +3128,14 @@ function createKeyedGroupBy(source, dependenciesOrSelector, maybeSelector) {
|
|
|
3095
3128
|
output.output.set(group, Object.freeze(members));
|
|
3096
3129
|
};
|
|
3097
3130
|
const publishGroupOrder = (output) => {
|
|
3098
|
-
const order = [...groupRanks.
|
|
3131
|
+
const order = [...groupRanks.keys()];
|
|
3132
|
+
order.sort((leftKey, rightKey) => {
|
|
3133
|
+
const left = groupRanks.get(leftKey);
|
|
3134
|
+
const right = groupRanks.get(rightKey);
|
|
3099
3135
|
if (left.source !== right.source) return left.source - right.source;
|
|
3100
3136
|
if (left.selector !== right.selector) return left.selector - right.selector;
|
|
3101
3137
|
return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
|
|
3102
|
-
})
|
|
3138
|
+
});
|
|
3103
3139
|
output.output.order(order);
|
|
3104
3140
|
};
|
|
3105
3141
|
const rebuild = (driver, sources, output) => {
|
|
@@ -3368,13 +3404,14 @@ const createPublishedCollection = () => {
|
|
|
3368
3404
|
},
|
|
3369
3405
|
publish: (staged, nextIds, reset) => {
|
|
3370
3406
|
if (reset) {
|
|
3371
|
-
const entries = [];
|
|
3372
|
-
for (const [key, entry] of staged) if (entry.present) entries.push([key, entry.value]);
|
|
3373
|
-
index = PersistentKeyedIndex.from(entries);
|
|
3374
3407
|
values.clear();
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
else
|
|
3408
|
+
for (const [key, entry] of staged) if (entry.present) values.set(key, entry.value);
|
|
3409
|
+
index = PersistentKeyedIndex.from(values);
|
|
3410
|
+
} else for (const [key, entry] of staged) {
|
|
3411
|
+
index = entry.present ? index.set(key, entry.value) : index.remove(key);
|
|
3412
|
+
if (entry.present) values.set(key, entry.value);
|
|
3413
|
+
else values.delete(key);
|
|
3414
|
+
}
|
|
3378
3415
|
ids = nextIds;
|
|
3379
3416
|
},
|
|
3380
3417
|
release: () => {
|
|
@@ -3387,7 +3424,7 @@ const createPublishedCollection = () => {
|
|
|
3387
3424
|
/** Owns staged keyed intent, exact transitions and published collection state. */
|
|
3388
3425
|
const createCollectionOutput = (binding) => {
|
|
3389
3426
|
const published = createPublishedCollection();
|
|
3390
|
-
|
|
3427
|
+
const staged = /* @__PURE__ */ new Map();
|
|
3391
3428
|
let nextIds = published.ids();
|
|
3392
3429
|
let change;
|
|
3393
3430
|
let initialized = false;
|
|
@@ -3403,12 +3440,15 @@ const createCollectionOutput = (binding) => {
|
|
|
3403
3440
|
return entry ? entry.present ? entry.value : void 0 : cleared ? void 0 : published.get(key);
|
|
3404
3441
|
};
|
|
3405
3442
|
const deriveIds = () => {
|
|
3406
|
-
const result =
|
|
3443
|
+
const result = [];
|
|
3444
|
+
if (!cleared) {
|
|
3445
|
+
for (const key of published.ids()) if (hasNext(key)) result.push(key);
|
|
3446
|
+
}
|
|
3407
3447
|
for (const [key, entry] of staged) if (entry.present && (cleared || !published.has(key))) result.push(key);
|
|
3408
3448
|
return result;
|
|
3409
3449
|
};
|
|
3410
3450
|
const begin = (active, initialize) => {
|
|
3411
|
-
staged
|
|
3451
|
+
staged.clear();
|
|
3412
3452
|
nextIds = published.ids();
|
|
3413
3453
|
change = void 0;
|
|
3414
3454
|
explicitOrder = void 0;
|
|
@@ -3425,7 +3465,9 @@ const createCollectionOutput = (binding) => {
|
|
|
3425
3465
|
},
|
|
3426
3466
|
ids: () => {
|
|
3427
3467
|
require_transform.assertScope(active);
|
|
3428
|
-
|
|
3468
|
+
if (!next) return published.ids();
|
|
3469
|
+
if (explicitOrder) return explicitOrder;
|
|
3470
|
+
return Object.freeze(deriveIds());
|
|
3429
3471
|
}
|
|
3430
3472
|
});
|
|
3431
3473
|
return {
|
|
@@ -3446,7 +3488,7 @@ const createCollectionOutput = (binding) => {
|
|
|
3446
3488
|
},
|
|
3447
3489
|
order: (order) => {
|
|
3448
3490
|
require_transform.assertScope(active);
|
|
3449
|
-
explicitOrder =
|
|
3491
|
+
explicitOrder = require_transform.snapshotArray(order);
|
|
3450
3492
|
}
|
|
3451
3493
|
}
|
|
3452
3494
|
};
|
|
@@ -3456,8 +3498,6 @@ const createCollectionOutput = (binding) => {
|
|
|
3456
3498
|
for (const key of published.keys()) if (!staged.has(key)) staged.set(key, { present: false });
|
|
3457
3499
|
}
|
|
3458
3500
|
require_transform.profile.projection("touchedKeys", staged.size);
|
|
3459
|
-
const added = /* @__PURE__ */ new Set();
|
|
3460
|
-
const removed = /* @__PURE__ */ new Set();
|
|
3461
3501
|
const addedEntries = [];
|
|
3462
3502
|
const updatedEntries = [];
|
|
3463
3503
|
const removedEntries = [];
|
|
@@ -3465,7 +3505,6 @@ const createCollectionOutput = (binding) => {
|
|
|
3465
3505
|
const existed = published.has(key);
|
|
3466
3506
|
if (entry.present) {
|
|
3467
3507
|
if (!existed) {
|
|
3468
|
-
added.add(key);
|
|
3469
3508
|
addedEntries.push({
|
|
3470
3509
|
key,
|
|
3471
3510
|
after: entry.value
|
|
@@ -3481,19 +3520,28 @@ const createCollectionOutput = (binding) => {
|
|
|
3481
3520
|
else if (!nextReset) staged.delete(key);
|
|
3482
3521
|
continue;
|
|
3483
3522
|
}
|
|
3484
|
-
if (existed) {
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
});
|
|
3490
|
-
} else staged.delete(key);
|
|
3523
|
+
if (existed) removedEntries.push({
|
|
3524
|
+
key,
|
|
3525
|
+
before: published.get(key)
|
|
3526
|
+
});
|
|
3527
|
+
else staged.delete(key);
|
|
3491
3528
|
}
|
|
3492
3529
|
const ids = published.ids();
|
|
3493
|
-
if (explicitOrder
|
|
3494
|
-
const
|
|
3495
|
-
|
|
3496
|
-
|
|
3530
|
+
if (explicitOrder) {
|
|
3531
|
+
const expectedLength = published.size() + addedEntries.length - removedEntries.length;
|
|
3532
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3533
|
+
for (const key of explicitOrder) {
|
|
3534
|
+
if (seen.has(key) || !hasNext(key)) throw new TypeError("Projection order must contain every key exactly once.");
|
|
3535
|
+
seen.add(key);
|
|
3536
|
+
}
|
|
3537
|
+
if (seen.size !== expectedLength) throw new TypeError("Projection order must contain every key exactly once.");
|
|
3538
|
+
nextIds = require_transform.sameArray(ids, explicitOrder) ? ids : explicitOrder;
|
|
3539
|
+
} else if (addedEntries.length || removedEntries.length) {
|
|
3540
|
+
const order = new Array(published.size() + addedEntries.length - removedEntries.length);
|
|
3541
|
+
let index = 0;
|
|
3542
|
+
for (const key of ids) if (hasNext(key)) order[index++] = key;
|
|
3543
|
+
for (const entry of addedEntries) order[index++] = entry.key;
|
|
3544
|
+
nextIds = require_transform.sameArray(ids, order) ? ids : Object.freeze(order);
|
|
3497
3545
|
} else nextIds = ids;
|
|
3498
3546
|
require_transform.profile.projection("changedKeys", addedEntries.length + updatedEntries.length + removedEntries.length);
|
|
3499
3547
|
change = nextReset ? Object.freeze({ kind: "reset" }) : require_transform.createCollectionChange({
|
|
@@ -3810,18 +3858,19 @@ const createProcessor = (scheduler, definition, dependencies) => {
|
|
|
3810
3858
|
};
|
|
3811
3859
|
//#endregion
|
|
3812
3860
|
//#region core/src/projection/readable/listeners.ts
|
|
3813
|
-
/** Exhaustively notifies
|
|
3814
|
-
const
|
|
3815
|
-
|
|
3816
|
-
const
|
|
3817
|
-
for (const listener of snapshot) try {
|
|
3861
|
+
/** Exhaustively notifies an already-stable projection listener snapshot. */
|
|
3862
|
+
const notifyProjectionListenerSnapshot = (listeners, message) => {
|
|
3863
|
+
let failures;
|
|
3864
|
+
for (const listener of listeners) try {
|
|
3818
3865
|
listener();
|
|
3819
3866
|
} catch (error) {
|
|
3820
|
-
failures.push(error);
|
|
3867
|
+
(failures ??= []).push(error);
|
|
3821
3868
|
}
|
|
3822
|
-
if (failures
|
|
3823
|
-
if (failures
|
|
3869
|
+
if (failures?.length === 1) throw failures[0];
|
|
3870
|
+
if (failures?.length) throw new AggregateError(failures, message);
|
|
3824
3871
|
};
|
|
3872
|
+
/** Snapshots a mutable listener collection before exhaustive notification. */
|
|
3873
|
+
const notifyProjectionListeners = (listeners, message) => notifyProjectionListenerSnapshot([...listeners], message);
|
|
3825
3874
|
//#endregion
|
|
3826
3875
|
//#region core/src/projection/readable/selection.ts
|
|
3827
3876
|
let activeTracker;
|
|
@@ -3876,8 +3925,7 @@ const selectionAffects = (selection, change) => {
|
|
|
3876
3925
|
if (!change || change.kind === "reset") return true;
|
|
3877
3926
|
if (selection.all) return true;
|
|
3878
3927
|
if (selection.structure && require_transform.collectionHasStructuralChange(change)) return true;
|
|
3879
|
-
|
|
3880
|
-
return false;
|
|
3928
|
+
return require_transform.collectionChangeIntersects(change, selection.keys);
|
|
3881
3929
|
};
|
|
3882
3930
|
const createDirectReadable = (source) => Object.freeze({
|
|
3883
3931
|
current: source.current,
|
|
@@ -3919,7 +3967,7 @@ const createSelectorReadable = (source, selector, equality = Object.is) => {
|
|
|
3919
3967
|
activeTracker = previousTracker;
|
|
3920
3968
|
}
|
|
3921
3969
|
const nextSelection = Object.freeze({
|
|
3922
|
-
keys:
|
|
3970
|
+
keys: tracker.keys,
|
|
3923
3971
|
all: tracker.all || isMapLike(current) && tracker.keys.size === 0 && !tracker.structure,
|
|
3924
3972
|
structure: tracker.structure
|
|
3925
3973
|
});
|
|
@@ -4161,10 +4209,11 @@ const clearDocumentDirty = (dirty) => {
|
|
|
4161
4209
|
dirty.treeNodes.clear();
|
|
4162
4210
|
dirty.children.clear();
|
|
4163
4211
|
};
|
|
4164
|
-
const
|
|
4212
|
+
const locateRange = (dirty, path, start, tail) => {
|
|
4165
4213
|
let current = dirty;
|
|
4166
|
-
for (
|
|
4214
|
+
for (let index = start; index < path.length; index++) {
|
|
4167
4215
|
if (current.replace) return void 0;
|
|
4216
|
+
const key = path[index];
|
|
4168
4217
|
let child = current.children.get(key);
|
|
4169
4218
|
if (!child) {
|
|
4170
4219
|
child = createDocumentDirty();
|
|
@@ -4172,10 +4221,17 @@ const locate = (dirty, path) => {
|
|
|
4172
4221
|
}
|
|
4173
4222
|
current = child;
|
|
4174
4223
|
}
|
|
4175
|
-
return current;
|
|
4224
|
+
if (tail === void 0) return current;
|
|
4225
|
+
if (current.replace) return void 0;
|
|
4226
|
+
let child = current.children.get(tail);
|
|
4227
|
+
if (!child) {
|
|
4228
|
+
child = createDocumentDirty();
|
|
4229
|
+
current.children.set(tail, child);
|
|
4230
|
+
}
|
|
4231
|
+
return child;
|
|
4176
4232
|
};
|
|
4177
|
-
const
|
|
4178
|
-
const current =
|
|
4233
|
+
const replaceAt = (dirty, path, start, tail) => {
|
|
4234
|
+
const current = locateRange(dirty, path, start, tail);
|
|
4179
4235
|
if (!current) return;
|
|
4180
4236
|
current.replace = true;
|
|
4181
4237
|
current.order = false;
|
|
@@ -4183,15 +4239,18 @@ const markDocumentReplace = (dirty, path) => {
|
|
|
4183
4239
|
current.treeNodes.clear();
|
|
4184
4240
|
current.children.clear();
|
|
4185
4241
|
};
|
|
4186
|
-
const
|
|
4187
|
-
|
|
4242
|
+
const markDocumentReplace = (dirty, path) => {
|
|
4243
|
+
replaceAt(dirty, path, 0);
|
|
4244
|
+
};
|
|
4245
|
+
const markDocumentOrderRange = (dirty, path, start) => {
|
|
4246
|
+
const current = locateRange(dirty, path, start);
|
|
4188
4247
|
if (current && !current.replace) current.order = true;
|
|
4189
4248
|
};
|
|
4190
|
-
const markDocumentTree = (dirty, path, root, nodes) => {
|
|
4191
|
-
const current =
|
|
4249
|
+
const markDocumentTree = (dirty, path, start, root, nodes) => {
|
|
4250
|
+
const current = locateRange(dirty, path, start);
|
|
4192
4251
|
if (!current || current.replace) return;
|
|
4193
4252
|
current.treeRoot ||= root;
|
|
4194
|
-
for (const
|
|
4253
|
+
for (const node of nodes) current.treeNodes.add(node.id);
|
|
4195
4254
|
};
|
|
4196
4255
|
const createCollectionPending = () => ({
|
|
4197
4256
|
reset: false,
|
|
@@ -4221,19 +4280,19 @@ const mergeValueChanges = (selector, dirty, changes) => {
|
|
|
4221
4280
|
const at = selector.address;
|
|
4222
4281
|
for (const change of changes.changes) {
|
|
4223
4282
|
if (change.kind === "reset") {
|
|
4224
|
-
|
|
4283
|
+
replaceAt(dirty, at, at.length);
|
|
4225
4284
|
return;
|
|
4226
4285
|
}
|
|
4227
4286
|
if (change.kind === "members") {
|
|
4228
4287
|
for (const member of change.members) {
|
|
4229
|
-
const
|
|
4230
|
-
if (
|
|
4231
|
-
else if (
|
|
4288
|
+
const compared = compareExtended(change.at, member.key, at);
|
|
4289
|
+
if (compared === "ancestor" || compared === "equal") replaceAt(dirty, at, at.length);
|
|
4290
|
+
else if (compared === "descendant") replaceAt(dirty, change.at, at.length, member.key);
|
|
4232
4291
|
}
|
|
4233
|
-
if (change.order && contains(at, change.at))
|
|
4292
|
+
if (change.order && contains(at, change.at)) markDocumentOrderRange(dirty, change.at, at.length);
|
|
4234
4293
|
continue;
|
|
4235
4294
|
}
|
|
4236
|
-
if (contains(at, change.at)) markDocumentTree(dirty, change.at
|
|
4295
|
+
if (contains(at, change.at)) markDocumentTree(dirty, change.at, at.length, change.before !== change.after, change.nodes);
|
|
4237
4296
|
}
|
|
4238
4297
|
};
|
|
4239
4298
|
const mergeCollectionChanges = (selector, pending, changes) => {
|
|
@@ -4245,13 +4304,15 @@ const mergeCollectionChanges = (selector, pending, changes) => {
|
|
|
4245
4304
|
return;
|
|
4246
4305
|
}
|
|
4247
4306
|
if (selector.tree?.kind === "nodes") {
|
|
4248
|
-
if (change.kind === "members") {
|
|
4249
|
-
|
|
4307
|
+
if (change.kind === "members") for (const member of change.members) {
|
|
4308
|
+
const compared = compareExtended(change.at, member.key, at);
|
|
4309
|
+
if (compared === "ancestor" || compared === "equal") {
|
|
4250
4310
|
resetCollectionPending(pending);
|
|
4251
4311
|
return;
|
|
4252
4312
|
}
|
|
4253
|
-
}
|
|
4254
|
-
|
|
4313
|
+
}
|
|
4314
|
+
else if (change.at.length === at.length && contains(change.at, at)) for (const node of change.nodes) {
|
|
4315
|
+
replaceAt(dirtyEntry(pending, node.id), at, at.length);
|
|
4255
4316
|
pending.order ||= node.kind !== "updated";
|
|
4256
4317
|
}
|
|
4257
4318
|
else if (contains(change.at, at)) {
|
|
@@ -4262,34 +4323,27 @@ const mergeCollectionChanges = (selector, pending, changes) => {
|
|
|
4262
4323
|
}
|
|
4263
4324
|
if (change.kind === "members") {
|
|
4264
4325
|
for (const member of change.members) {
|
|
4265
|
-
const
|
|
4266
|
-
if (
|
|
4267
|
-
resetCollectionPending(pending);
|
|
4268
|
-
return;
|
|
4269
|
-
}
|
|
4270
|
-
if (!contains(at, changed)) continue;
|
|
4271
|
-
const relative = changed.slice(at.length);
|
|
4272
|
-
if (!relative.length) {
|
|
4326
|
+
const compared = compareExtended(change.at, member.key, at);
|
|
4327
|
+
if (compared === "ancestor" || compared === "equal") {
|
|
4273
4328
|
resetCollectionPending(pending);
|
|
4274
4329
|
return;
|
|
4275
4330
|
}
|
|
4276
|
-
|
|
4277
|
-
if (
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
if (!relative.length) pending.order = true;
|
|
4282
|
-
else markDocumentOrder(dirtyEntry(pending, relative[0]), relative.slice(1));
|
|
4331
|
+
if (compared !== "descendant") continue;
|
|
4332
|
+
if (at.length === change.at.length) {
|
|
4333
|
+
replaceAt(dirtyEntry(pending, member.key), change.at, change.at.length);
|
|
4334
|
+
if (member.kind !== "updated") pending.order = true;
|
|
4335
|
+
} else replaceAt(dirtyEntry(pending, change.at[at.length]), change.at, at.length + 1, member.key);
|
|
4283
4336
|
}
|
|
4337
|
+
if (change.order && contains(at, change.at)) if (change.at.length === at.length) pending.order = true;
|
|
4338
|
+
else markDocumentOrderRange(dirtyEntry(pending, change.at[at.length]), change.at, at.length + 1);
|
|
4284
4339
|
continue;
|
|
4285
4340
|
}
|
|
4286
4341
|
if (!contains(at, change.at)) continue;
|
|
4287
|
-
|
|
4288
|
-
if (!relative.length) {
|
|
4342
|
+
if (change.at.length === at.length) {
|
|
4289
4343
|
resetCollectionPending(pending);
|
|
4290
4344
|
return;
|
|
4291
4345
|
}
|
|
4292
|
-
markDocumentTree(dirtyEntry(pending,
|
|
4346
|
+
markDocumentTree(dirtyEntry(pending, change.at[at.length]), change.at, at.length + 1, change.before !== change.after, change.nodes);
|
|
4293
4347
|
}
|
|
4294
4348
|
};
|
|
4295
4349
|
//#endregion
|
|
@@ -4418,16 +4472,29 @@ const stageCollectionRead = (state, read, active, options) => {
|
|
|
4418
4472
|
evaluation.output.order(ids);
|
|
4419
4473
|
} else {
|
|
4420
4474
|
const previous = state.current();
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
for (const key of
|
|
4475
|
+
let currentIds;
|
|
4476
|
+
const ids = () => currentIds ??= read.ids();
|
|
4477
|
+
if (options.candidates) for (const key of options.candidates) if (read.has(key)) {
|
|
4424
4478
|
require_transform.profile.collectionView.mapped();
|
|
4425
4479
|
evaluation.output.set(key, read.get(key));
|
|
4426
4480
|
} else evaluation.output.remove(key);
|
|
4481
|
+
else {
|
|
4482
|
+
const previousIds = previous.ids();
|
|
4483
|
+
const nextIds = ids();
|
|
4484
|
+
require_transform.profile.collectionView.idsScanned(previousIds.length + nextIds.length);
|
|
4485
|
+
for (const key of previousIds) if (read.has(key)) {
|
|
4486
|
+
require_transform.profile.collectionView.mapped();
|
|
4487
|
+
evaluation.output.set(key, read.get(key));
|
|
4488
|
+
} else evaluation.output.remove(key);
|
|
4489
|
+
for (const key of nextIds) if (!previous.has(key)) {
|
|
4490
|
+
require_transform.profile.collectionView.mapped();
|
|
4491
|
+
evaluation.output.set(key, read.get(key));
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
4427
4494
|
if (options.orderMayChange || !options.candidates) {
|
|
4428
|
-
const
|
|
4429
|
-
if (options.candidates) require_transform.profile.collectionView.idsScanned(
|
|
4430
|
-
evaluation.output.order(
|
|
4495
|
+
const nextIds = ids();
|
|
4496
|
+
if (options.candidates) require_transform.profile.collectionView.idsScanned(nextIds.length);
|
|
4497
|
+
evaluation.output.order(nextIds);
|
|
4431
4498
|
}
|
|
4432
4499
|
}
|
|
4433
4500
|
return state.seal(options.reset, options.isEqual ?? Object.is);
|
|
@@ -4721,13 +4788,15 @@ const createDocumentSourceRegistry = (scheduler) => {
|
|
|
4721
4788
|
const snapshots = /* @__PURE__ */ new Map();
|
|
4722
4789
|
const replacement = createDocumentDirty();
|
|
4723
4790
|
if (pending.reset) markDocumentReplace(replacement, []);
|
|
4791
|
+
let cachedIds;
|
|
4724
4792
|
const ids = () => {
|
|
4725
4793
|
require_transform.assertScope(active);
|
|
4726
|
-
if (
|
|
4727
|
-
if (node?.kind === "
|
|
4728
|
-
if (node?.kind === "
|
|
4729
|
-
if (node?.kind === "
|
|
4730
|
-
return Object.freeze(
|
|
4794
|
+
if (cachedIds) return cachedIds;
|
|
4795
|
+
if (treeNodes) return cachedIds = node?.kind === "tree" && require_record.isRecord(value) && require_record.isRecord(value.nodes) ? Object.freeze(Object.keys(value.nodes)) : Object.freeze([]);
|
|
4796
|
+
if (node?.kind === "map" && require_record.isRecord(value)) return cachedIds = Object.freeze(Object.keys(value));
|
|
4797
|
+
if (node?.kind === "table" && require_record.isRecord(value) && Array.isArray(value.ids)) return cachedIds = Object.freeze([...value.ids]);
|
|
4798
|
+
if (node?.kind === "list" && Array.isArray(value)) return cachedIds = Object.freeze(toArray(indexedKeys(value, node.keyOf)));
|
|
4799
|
+
return cachedIds = Object.freeze([]);
|
|
4731
4800
|
};
|
|
4732
4801
|
const has = (key) => {
|
|
4733
4802
|
require_transform.assertScope(active);
|
|
@@ -5215,7 +5284,6 @@ const createSourceRegistry = (scheduler) => {
|
|
|
5215
5284
|
};
|
|
5216
5285
|
//#endregion
|
|
5217
5286
|
//#region core/src/projection/readable/keyed.ts
|
|
5218
|
-
const sameKeys = (previous, next) => previous.length === next.length && previous.every((key, index) => key === next[index]);
|
|
5219
5287
|
/** Runtime-owned keyed consumer family over one materialized collection output. */
|
|
5220
5288
|
const createProjectionItems = (source, checkOwner) => {
|
|
5221
5289
|
if (source.kind !== "collection") throw new TypeError("Projection items require a keyed collection projection.");
|
|
@@ -5235,7 +5303,11 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
5235
5303
|
for (const listener of listeners) notifications.push(listener);
|
|
5236
5304
|
};
|
|
5237
5305
|
const flushNotifications = () => {
|
|
5238
|
-
|
|
5306
|
+
try {
|
|
5307
|
+
notifyProjectionListenerSnapshot(notifications, "Projection item listeners failed.");
|
|
5308
|
+
} finally {
|
|
5309
|
+
notifications.length = 0;
|
|
5310
|
+
}
|
|
5239
5311
|
};
|
|
5240
5312
|
const unregisterWaiting = (state) => {
|
|
5241
5313
|
const states = waiting.get(state.key);
|
|
@@ -5278,16 +5350,11 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
5278
5350
|
publishState(state, void 0);
|
|
5279
5351
|
state.ended = true;
|
|
5280
5352
|
};
|
|
5281
|
-
const
|
|
5282
|
-
const result = [];
|
|
5353
|
+
const terminateKey = (key) => {
|
|
5283
5354
|
const canonical = active.get(key);
|
|
5284
|
-
if (canonical)
|
|
5355
|
+
if (canonical) terminateState(canonical);
|
|
5285
5356
|
const extra = followers.get(key);
|
|
5286
|
-
if (extra)
|
|
5287
|
-
return result;
|
|
5288
|
-
};
|
|
5289
|
-
const terminateKey = (key) => {
|
|
5290
|
-
for (const state of statesFor(key)) terminateState(state);
|
|
5357
|
+
if (extra) for (const state of extra) terminateState(state);
|
|
5291
5358
|
active.delete(key);
|
|
5292
5359
|
followers.delete(key);
|
|
5293
5360
|
};
|
|
@@ -5298,12 +5365,14 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
5298
5365
|
for (const state of states) attachActive(state, value);
|
|
5299
5366
|
};
|
|
5300
5367
|
const updateKey = (key, value) => {
|
|
5301
|
-
|
|
5368
|
+
const canonical = active.get(key);
|
|
5369
|
+
if (canonical) publishState(canonical, value);
|
|
5370
|
+
const extra = followers.get(key);
|
|
5371
|
+
if (extra) for (const state of extra) publishState(state, value);
|
|
5302
5372
|
};
|
|
5303
5373
|
const updateKeys = (current) => {
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
keysValue = next;
|
|
5374
|
+
if (require_transform.iterableMatchesArray(current.keys(), keysValue)) return;
|
|
5375
|
+
keysValue = Object.freeze([...current.keys()]);
|
|
5307
5376
|
keysRevision++;
|
|
5308
5377
|
notify(keyListeners);
|
|
5309
5378
|
};
|
|
@@ -5346,9 +5415,9 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
5346
5415
|
return state;
|
|
5347
5416
|
};
|
|
5348
5417
|
const reconcile = (current) => {
|
|
5349
|
-
for (const key of
|
|
5418
|
+
for (const key of active.keys()) if (!current.has(key)) terminateKey(key);
|
|
5350
5419
|
else updateKey(key, current.get(key));
|
|
5351
|
-
for (const key of
|
|
5420
|
+
for (const key of waiting.keys()) if (current.has(key)) activateWaiting(key, current.get(key));
|
|
5352
5421
|
updateKeys(current);
|
|
5353
5422
|
};
|
|
5354
5423
|
const onChange = (change) => {
|