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