@outbuild-company/schedule-core 1.9.2 → 1.9.4
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/cdn/schedule-core.global.js +1 -1
- package/dist/cdn/schedule-core.global.js.map +1 -1
- package/dist/index.cjs +256 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -9
- package/dist/index.d.ts +69 -9
- package/dist/index.js +256 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -338,6 +338,10 @@ var FIELD_REGISTRY = {
|
|
|
338
338
|
valueKind: "number",
|
|
339
339
|
extract: (activity) => activity.expectedProgressBaseline
|
|
340
340
|
},
|
|
341
|
+
expectedProgress: {
|
|
342
|
+
valueKind: "number",
|
|
343
|
+
extract: (activity) => activity.expectedProgress
|
|
344
|
+
},
|
|
341
345
|
baselineDurationDays: {
|
|
342
346
|
valueKind: "number",
|
|
343
347
|
extract: (activity) => activity.baselineSnapshot?.durationDays ?? null
|
|
@@ -444,12 +448,20 @@ function matchNumber(value, target, operator) {
|
|
|
444
448
|
if (operator === "lessOrEqual") return value <= target;
|
|
445
449
|
return false;
|
|
446
450
|
}
|
|
451
|
+
function matchNumberBetween(value, minimum, maximum) {
|
|
452
|
+
return typeof value === "number" && value >= minimum && value <= maximum;
|
|
453
|
+
}
|
|
447
454
|
function matchDate(value, target, operator) {
|
|
448
455
|
if (!(value instanceof Date)) return false;
|
|
449
456
|
if (operator === "after") return value.getTime() > target.getTime();
|
|
450
457
|
if (operator === "before") return value.getTime() < target.getTime();
|
|
451
458
|
return false;
|
|
452
459
|
}
|
|
460
|
+
function matchDateBetween(value, minimum, maximum) {
|
|
461
|
+
if (!(value instanceof Date)) return false;
|
|
462
|
+
const time = value.getTime();
|
|
463
|
+
return time >= minimum.getTime() && time <= maximum.getTime();
|
|
464
|
+
}
|
|
453
465
|
function matchIdArray(value, allowed, operator) {
|
|
454
466
|
const ids = Array.isArray(value) ? value : [];
|
|
455
467
|
const intersects = ids.some((id) => allowed.has(String(id)));
|
|
@@ -472,6 +484,23 @@ function matchCriterion(activity, criterion, context) {
|
|
|
472
484
|
if (descriptor === null) return false;
|
|
473
485
|
const value = descriptor.extract(activity, context);
|
|
474
486
|
const { operator } = criterion;
|
|
487
|
+
if (operator === "between") {
|
|
488
|
+
if (descriptor.valueKind === "number") {
|
|
489
|
+
return matchNumberBetween(
|
|
490
|
+
value,
|
|
491
|
+
Number(criterion.value),
|
|
492
|
+
Number(criterion.valueTo)
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
if (descriptor.valueKind === "date") {
|
|
496
|
+
return matchDateBetween(
|
|
497
|
+
value,
|
|
498
|
+
toTargetDate(criterion.value),
|
|
499
|
+
toTargetDate(criterion.valueTo)
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
475
504
|
if (descriptor.valueKind === "string") {
|
|
476
505
|
return matchString(value, String(criterion.value), operator);
|
|
477
506
|
}
|
|
@@ -651,9 +680,10 @@ var OPERATORS_BY_KIND = {
|
|
|
651
680
|
"greaterThan",
|
|
652
681
|
"lessThan",
|
|
653
682
|
"greaterOrEqual",
|
|
654
|
-
"lessOrEqual"
|
|
683
|
+
"lessOrEqual",
|
|
684
|
+
"between"
|
|
655
685
|
]),
|
|
656
|
-
date: /* @__PURE__ */ new Set(["after", "before"]),
|
|
686
|
+
date: /* @__PURE__ */ new Set(["after", "before", "between"]),
|
|
657
687
|
"id-array": /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
|
|
658
688
|
enum: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
|
|
659
689
|
boolean: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
|
|
@@ -684,6 +714,9 @@ function normalizeCriterion(criterion) {
|
|
|
684
714
|
if (!OPERATORS_BY_KIND[descriptor.valueKind].has(criterion.operator)) {
|
|
685
715
|
return { ok: false, reason: "unknown_operator" };
|
|
686
716
|
}
|
|
717
|
+
if (criterion.operator === "between") {
|
|
718
|
+
return normalizeBetweenCriterion(criterion, descriptor.valueKind);
|
|
719
|
+
}
|
|
687
720
|
if (descriptor.valueKind === "number") {
|
|
688
721
|
const value = normalizeNumberValue(criterion.value);
|
|
689
722
|
return value === null ? { ok: false, reason: "invalid_value" } : {
|
|
@@ -724,6 +757,31 @@ function normalizeCriterion(criterion) {
|
|
|
724
757
|
}
|
|
725
758
|
return { ok: true, criterion };
|
|
726
759
|
}
|
|
760
|
+
function normalizeBetweenCriterion(criterion, valueKind) {
|
|
761
|
+
if (valueKind === "number") {
|
|
762
|
+
const value = normalizeNumberValue(criterion.value);
|
|
763
|
+
const valueTo = normalizeNumberValue(criterion.valueTo);
|
|
764
|
+
if (value === null || valueTo === null || value > valueTo) {
|
|
765
|
+
return { ok: false, reason: "invalid_value" };
|
|
766
|
+
}
|
|
767
|
+
return {
|
|
768
|
+
ok: true,
|
|
769
|
+
criterion: { ...criterion, value, valueTo }
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
if (valueKind === "date") {
|
|
773
|
+
const value = normalizeDateValue(criterion.value);
|
|
774
|
+
const valueTo = normalizeDateValue(criterion.valueTo);
|
|
775
|
+
if (value === null || valueTo === null || value.getTime() > valueTo.getTime()) {
|
|
776
|
+
return { ok: false, reason: "invalid_value" };
|
|
777
|
+
}
|
|
778
|
+
return {
|
|
779
|
+
ok: true,
|
|
780
|
+
criterion: { ...criterion, value, valueTo }
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
return { ok: false, reason: "unknown_operator" };
|
|
784
|
+
}
|
|
727
785
|
function validateValueForKind(criterion, valueKind) {
|
|
728
786
|
const { value } = criterion;
|
|
729
787
|
if (valueKind === "boolean") {
|
|
@@ -12541,28 +12599,6 @@ function assertValidAssignments(assignments, entityName, readCurrent, ownerByBac
|
|
|
12541
12599
|
);
|
|
12542
12600
|
}
|
|
12543
12601
|
}
|
|
12544
|
-
function assertValidReconciledProgress(entries, deps) {
|
|
12545
|
-
const seen = /* @__PURE__ */ new Set();
|
|
12546
|
-
for (const entry of entries) {
|
|
12547
|
-
const id = String(entry.activityId);
|
|
12548
|
-
if (id.length === 0 || seen.has(id)) {
|
|
12549
|
-
throw new Error(
|
|
12550
|
-
`persistence-acknowledge: duplicate or empty reconciled activity id "${id}"`
|
|
12551
|
-
);
|
|
12552
|
-
}
|
|
12553
|
-
if (!Number.isFinite(entry.progress) || entry.progress < 0 || entry.progress > 100) {
|
|
12554
|
-
throw new Error(
|
|
12555
|
-
`persistence-acknowledge: invalid reconciled progress ${String(entry.progress)} for "${id}"`
|
|
12556
|
-
);
|
|
12557
|
-
}
|
|
12558
|
-
if (!deps.adapter.getActivity(id)) {
|
|
12559
|
-
throw new Error(
|
|
12560
|
-
`persistence-acknowledge: unknown reconciled activity id "${id}"`
|
|
12561
|
-
);
|
|
12562
|
-
}
|
|
12563
|
-
seen.add(id);
|
|
12564
|
-
}
|
|
12565
|
-
}
|
|
12566
12602
|
async function applyReconciledProgress(entries, deps) {
|
|
12567
12603
|
const progressToApply = entries.filter((entry) => {
|
|
12568
12604
|
const current = deps.adapter.getActivity(String(entry.activityId));
|
|
@@ -12593,19 +12629,25 @@ async function applyReconciledProgress(entries, deps) {
|
|
|
12593
12629
|
async function dispatchPersistenceAcknowledge(action, deps) {
|
|
12594
12630
|
const activities = action.activities ?? [];
|
|
12595
12631
|
const links = action.links ?? [];
|
|
12596
|
-
const reconciledProgress = action.reconciledProgress ?? [];
|
|
12597
|
-
assertValidReconciledProgress(reconciledProgress, deps);
|
|
12598
12632
|
const currentActivities = deps.adapter.getAllActivities();
|
|
12599
12633
|
const currentLinks = deps.adapter.getAllLinks();
|
|
12600
|
-
const
|
|
12601
|
-
const
|
|
12634
|
+
const checkpointActivities = action.checkpoint?.activities ?? currentActivities;
|
|
12635
|
+
const checkpointLinks = action.checkpoint?.links ?? currentLinks;
|
|
12636
|
+
const checkpointActivityById = new Map(
|
|
12637
|
+
checkpointActivities.map((activity) => [String(activity.id), activity])
|
|
12638
|
+
);
|
|
12639
|
+
const checkpointLinkById = new Map(
|
|
12640
|
+
checkpointLinks.map((link) => [String(link.id), link])
|
|
12641
|
+
);
|
|
12642
|
+
const activityOwnerByBackendId = persistedOwnersOf(checkpointActivities);
|
|
12643
|
+
const linkOwnerByBackendId = persistedOwnersOf(checkpointLinks);
|
|
12602
12644
|
assertValidAssignments(
|
|
12603
12645
|
activities,
|
|
12604
12646
|
"activity",
|
|
12605
12647
|
(id) => {
|
|
12606
|
-
const activity =
|
|
12648
|
+
const activity = checkpointActivityById.get(id);
|
|
12607
12649
|
return {
|
|
12608
|
-
exists: activity !==
|
|
12650
|
+
exists: activity !== void 0,
|
|
12609
12651
|
current: activity?.proplannerId ?? null
|
|
12610
12652
|
};
|
|
12611
12653
|
},
|
|
@@ -12615,17 +12657,21 @@ async function dispatchPersistenceAcknowledge(action, deps) {
|
|
|
12615
12657
|
links,
|
|
12616
12658
|
"link",
|
|
12617
12659
|
(id) => {
|
|
12618
|
-
const link =
|
|
12619
|
-
return {
|
|
12660
|
+
const link = checkpointLinkById.get(id);
|
|
12661
|
+
return {
|
|
12662
|
+
exists: link !== void 0,
|
|
12663
|
+
current: link?.proplannerId ?? null
|
|
12664
|
+
};
|
|
12620
12665
|
},
|
|
12621
12666
|
linkOwnerByBackendId
|
|
12622
12667
|
);
|
|
12623
|
-
assertAllNewEntitiesAcknowledged(
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
deps
|
|
12668
|
+
assertAllNewEntitiesAcknowledged(
|
|
12669
|
+
checkpointActivities,
|
|
12670
|
+
activities,
|
|
12671
|
+
"activity"
|
|
12628
12672
|
);
|
|
12673
|
+
assertAllNewEntitiesAcknowledged(checkpointLinks, links, "link");
|
|
12674
|
+
const activityChanges = [];
|
|
12629
12675
|
const linkChanges = [];
|
|
12630
12676
|
deps.adapter.batchUpdate(() => {
|
|
12631
12677
|
for (const assignment of activities) {
|
|
@@ -18439,7 +18485,9 @@ function mergeCoalesced(top, next) {
|
|
|
18439
18485
|
return buildUndoEntry(changeSet);
|
|
18440
18486
|
}
|
|
18441
18487
|
function getDispatchHistoryPolicy(action) {
|
|
18442
|
-
if (action.kind === "persistence-acknowledge")
|
|
18488
|
+
if (action.kind === "persistence-acknowledge") {
|
|
18489
|
+
return "checkpoint-on-success";
|
|
18490
|
+
}
|
|
18443
18491
|
if (action.kind === "sir-sync" || action.kind === "activity-lookahead-sync" || action.kind === "baseline-apply" || action.kind === "ponderator-criterion-set" || action.kind === "status-criteria-set" || action.kind === "activity-clipboard-clear" || action.kind === "activity-copy" || action.kind === "selection-toggle" || action.kind === "selection-replace" || action.kind === "visibility-set" || action.kind === "filter-set" || action.kind === "sort-set") {
|
|
18444
18492
|
return "skip";
|
|
18445
18493
|
}
|
|
@@ -18695,22 +18743,25 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18695
18743
|
maxDepth;
|
|
18696
18744
|
undoStack = [];
|
|
18697
18745
|
redoStack = [];
|
|
18746
|
+
sequence = 0;
|
|
18698
18747
|
_lastKey = null;
|
|
18699
18748
|
_lastTime = 0;
|
|
18700
18749
|
fork() {
|
|
18701
18750
|
const fork = new _UndoRecorder(this.maxDepth);
|
|
18702
18751
|
fork.undoStack.push(...cloneDomainValue(this.undoStack));
|
|
18703
18752
|
fork.redoStack.push(...cloneDomainValue(this.redoStack));
|
|
18753
|
+
fork.sequence = this.sequence;
|
|
18704
18754
|
fork._lastKey = this._lastKey;
|
|
18705
18755
|
fork._lastTime = this._lastTime;
|
|
18706
18756
|
return fork;
|
|
18707
18757
|
}
|
|
18708
18758
|
record(entry, coalesceKey = null, now = 0) {
|
|
18709
18759
|
const top = this.undoStack[this.undoStack.length - 1];
|
|
18710
|
-
if (coalesceKey != null && coalesceKey === this._lastKey && now - this._lastTime <= COALESCE_WINDOW_MS && top !== void 0 && canCoalesce(top, entry)) {
|
|
18711
|
-
|
|
18760
|
+
if (coalesceKey != null && coalesceKey === this._lastKey && now - this._lastTime <= COALESCE_WINDOW_MS && top !== void 0 && canCoalesce(top.entry, entry)) {
|
|
18761
|
+
top.entry = mergeCoalesced(top.entry, entry);
|
|
18762
|
+
top.touchedAt = this.touch();
|
|
18712
18763
|
} else {
|
|
18713
|
-
this.undoStack.push(entry);
|
|
18764
|
+
this.undoStack.push({ entry, touchedAt: this.touch() });
|
|
18714
18765
|
if (this.undoStack.length > this.maxDepth) {
|
|
18715
18766
|
this.undoStack.splice(0, this.undoStack.length - this.maxDepth);
|
|
18716
18767
|
}
|
|
@@ -18723,16 +18774,16 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18723
18774
|
this._lastKey = null;
|
|
18724
18775
|
}
|
|
18725
18776
|
takeUndo() {
|
|
18726
|
-
return this.undoStack.pop() ?? null;
|
|
18777
|
+
return this.undoStack.pop()?.entry ?? null;
|
|
18727
18778
|
}
|
|
18728
18779
|
takeRedo() {
|
|
18729
|
-
return this.redoStack.pop() ?? null;
|
|
18780
|
+
return this.redoStack.pop()?.entry ?? null;
|
|
18730
18781
|
}
|
|
18731
18782
|
pushRedo(entry) {
|
|
18732
|
-
this.redoStack.push(entry);
|
|
18783
|
+
this.redoStack.push({ entry, touchedAt: this.touch() });
|
|
18733
18784
|
}
|
|
18734
18785
|
pushUndo(entry) {
|
|
18735
|
-
this.undoStack.push(entry);
|
|
18786
|
+
this.undoStack.push({ entry, touchedAt: this.touch() });
|
|
18736
18787
|
}
|
|
18737
18788
|
canUndo() {
|
|
18738
18789
|
return this.undoStack.length > 0;
|
|
@@ -18743,11 +18794,64 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18743
18794
|
undoDepth() {
|
|
18744
18795
|
return this.undoStack.length;
|
|
18745
18796
|
}
|
|
18797
|
+
capturePersistenceBoundary() {
|
|
18798
|
+
this.resetCoalesce();
|
|
18799
|
+
return this.sequence;
|
|
18800
|
+
}
|
|
18801
|
+
discardThrough(boundary) {
|
|
18802
|
+
this.removeEntriesThrough(this.undoStack, boundary);
|
|
18803
|
+
this.removeEntriesThrough(this.redoStack, boundary);
|
|
18804
|
+
this.resetCoalesce();
|
|
18805
|
+
}
|
|
18806
|
+
applyPersistedIdentities(activities, links) {
|
|
18807
|
+
const activityIds = new Map(
|
|
18808
|
+
activities.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
18809
|
+
);
|
|
18810
|
+
const linkIds = new Map(
|
|
18811
|
+
links.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
18812
|
+
);
|
|
18813
|
+
for (const stored of [...this.undoStack, ...this.redoStack]) {
|
|
18814
|
+
stored.entry = this.withPersistedIdentities(
|
|
18815
|
+
stored.entry,
|
|
18816
|
+
activityIds,
|
|
18817
|
+
linkIds
|
|
18818
|
+
);
|
|
18819
|
+
}
|
|
18820
|
+
}
|
|
18746
18821
|
clear() {
|
|
18747
18822
|
this.undoStack.length = 0;
|
|
18748
18823
|
this.redoStack.length = 0;
|
|
18749
18824
|
this.resetCoalesce();
|
|
18750
18825
|
}
|
|
18826
|
+
touch() {
|
|
18827
|
+
this.sequence += 1;
|
|
18828
|
+
return this.sequence;
|
|
18829
|
+
}
|
|
18830
|
+
removeEntriesThrough(stack, boundary) {
|
|
18831
|
+
const retained = stack.filter(({ touchedAt }) => touchedAt > boundary);
|
|
18832
|
+
stack.splice(0, stack.length, ...retained);
|
|
18833
|
+
}
|
|
18834
|
+
withPersistedIdentities(entry, activityIds, linkIds) {
|
|
18835
|
+
const patchActivities = (snapshots) => snapshots === void 0 ? void 0 : new Map(
|
|
18836
|
+
Array.from(snapshots, ([id, activity]) => [
|
|
18837
|
+
id,
|
|
18838
|
+
activityIds.has(id) ? { ...activity, proplannerId: activityIds.get(id) } : activity
|
|
18839
|
+
])
|
|
18840
|
+
);
|
|
18841
|
+
const patchLinks = (snapshots) => snapshots === void 0 ? void 0 : new Map(
|
|
18842
|
+
Array.from(snapshots, ([id, link]) => [
|
|
18843
|
+
id,
|
|
18844
|
+
linkIds.has(id) ? { ...link, proplannerId: linkIds.get(id) } : link
|
|
18845
|
+
])
|
|
18846
|
+
);
|
|
18847
|
+
return {
|
|
18848
|
+
...entry,
|
|
18849
|
+
beforeSnap: patchActivities(entry.beforeSnap),
|
|
18850
|
+
afterSnap: patchActivities(entry.afterSnap),
|
|
18851
|
+
beforeLinks: patchLinks(entry.beforeLinks),
|
|
18852
|
+
afterLinks: patchLinks(entry.afterLinks)
|
|
18853
|
+
};
|
|
18854
|
+
}
|
|
18751
18855
|
};
|
|
18752
18856
|
|
|
18753
18857
|
// src/dispatch/shared/resequenced-parents.ts
|
|
@@ -18905,10 +19009,12 @@ function snapshotFieldValue(field, value) {
|
|
|
18905
19009
|
return value;
|
|
18906
19010
|
}
|
|
18907
19011
|
function activityChangedSince(current, saved) {
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
return
|
|
19012
|
+
return changedPersistableActivityFields(current, saved).length > 0;
|
|
19013
|
+
}
|
|
19014
|
+
function changedPersistableActivityFields(current, saved) {
|
|
19015
|
+
return PERSISTABLE_ACTIVITY_FIELDS.filter(
|
|
19016
|
+
(field) => !fieldEquals(field, current[field], saved[field])
|
|
19017
|
+
);
|
|
18912
19018
|
}
|
|
18913
19019
|
function fieldEquals(field, currentValue, savedValue) {
|
|
18914
19020
|
if (DATE_FIELDS2.has(field)) return dateEquals(currentValue, savedValue);
|
|
@@ -19017,11 +19123,60 @@ var SaveTracker = class _SaveTracker {
|
|
|
19017
19123
|
}
|
|
19018
19124
|
this.initialized = true;
|
|
19019
19125
|
}
|
|
19020
|
-
acknowledge(activities, links) {
|
|
19126
|
+
acknowledge(activities, links, activityIdentities = [], linkIdentities = [], currentActivities, currentLinks) {
|
|
19021
19127
|
if (!this.trackingEnabled) return;
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19128
|
+
const activityIds = new Map(
|
|
19129
|
+
activityIdentities.map(({ id, proplannerId }) => [
|
|
19130
|
+
String(id),
|
|
19131
|
+
proplannerId
|
|
19132
|
+
])
|
|
19133
|
+
);
|
|
19134
|
+
const linkIds = new Map(
|
|
19135
|
+
linkIdentities.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
19136
|
+
);
|
|
19137
|
+
const persistedActivities = activities.map((activity) => ({
|
|
19138
|
+
...activity,
|
|
19139
|
+
proplannerId: activityIds.get(String(activity.id)) ?? activity.proplannerId
|
|
19140
|
+
}));
|
|
19141
|
+
const persistedLinks = links.map((link) => {
|
|
19142
|
+
const proplannerId = linkIds.get(String(link.id));
|
|
19143
|
+
return proplannerId === void 0 ? { ...link } : { ...link, proplannerId };
|
|
19144
|
+
});
|
|
19145
|
+
assertValidPersistedIdentities(persistedActivities, persistedLinks);
|
|
19146
|
+
this.snapshotActivities(persistedActivities);
|
|
19147
|
+
this.snapshotLinks(persistedLinks);
|
|
19148
|
+
if (!currentActivities || !currentLinks) return;
|
|
19149
|
+
const currentActivityById = new Map(
|
|
19150
|
+
currentActivities.map((activity) => [String(activity.id), activity])
|
|
19151
|
+
);
|
|
19152
|
+
const currentLinkById = new Map(
|
|
19153
|
+
currentLinks.map((link) => [String(link.id), link])
|
|
19154
|
+
);
|
|
19155
|
+
for (const activity of persistedActivities) {
|
|
19156
|
+
const activityId = String(activity.id);
|
|
19157
|
+
if (this.activityIsDirty(
|
|
19158
|
+
activityId,
|
|
19159
|
+
currentActivityById.get(activityId) ?? null
|
|
19160
|
+
)) {
|
|
19161
|
+
this.dirtyActivityIds.add(activityId);
|
|
19162
|
+
}
|
|
19163
|
+
}
|
|
19164
|
+
for (const activity of currentActivities) {
|
|
19165
|
+
const activityId = String(activity.id);
|
|
19166
|
+
if (this.activityIsDirty(activityId, activity)) {
|
|
19167
|
+
this.dirtyActivityIds.add(activityId);
|
|
19168
|
+
}
|
|
19169
|
+
}
|
|
19170
|
+
for (const link of persistedLinks) {
|
|
19171
|
+
const linkId = String(link.id);
|
|
19172
|
+
if (this.linkIsDirty(linkId, currentLinkById.get(linkId) ?? null)) {
|
|
19173
|
+
this.dirtyLinkIds.add(linkId);
|
|
19174
|
+
}
|
|
19175
|
+
}
|
|
19176
|
+
for (const link of currentLinks) {
|
|
19177
|
+
const linkId = String(link.id);
|
|
19178
|
+
if (this.linkIsDirty(linkId, link)) this.dirtyLinkIds.add(linkId);
|
|
19179
|
+
}
|
|
19025
19180
|
}
|
|
19026
19181
|
snapshotActivities(activities) {
|
|
19027
19182
|
if (!this.trackingEnabled) return;
|
|
@@ -19205,6 +19360,21 @@ var SaveTracker = class _SaveTracker {
|
|
|
19205
19360
|
}
|
|
19206
19361
|
return modified;
|
|
19207
19362
|
}
|
|
19363
|
+
modifiedActivityFields(getActivity) {
|
|
19364
|
+
const result = /* @__PURE__ */ new Map();
|
|
19365
|
+
if (!this.trackingEnabled || !this.initialized) return result;
|
|
19366
|
+
for (const activityId of this.dirtyActivityIds) {
|
|
19367
|
+
const current = getActivity(activityId);
|
|
19368
|
+
const saved = this.activitiesAtLastSave.get(activityId);
|
|
19369
|
+
if (!current || !saved) continue;
|
|
19370
|
+
const fields = changedPersistableActivityFields(
|
|
19371
|
+
current,
|
|
19372
|
+
saved.persistable
|
|
19373
|
+
);
|
|
19374
|
+
if (fields.length > 0) result.set(activityId, fields);
|
|
19375
|
+
}
|
|
19376
|
+
return result;
|
|
19377
|
+
}
|
|
19208
19378
|
modifiedLinks(getLink) {
|
|
19209
19379
|
if (!this.trackingEnabled || !this.initialized) return [];
|
|
19210
19380
|
const modified = [];
|
|
@@ -21297,6 +21467,14 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21297
21467
|
(activityId) => this.coreRuntime.state.getActivity(activityId)
|
|
21298
21468
|
).map(cloneDomainValue);
|
|
21299
21469
|
}
|
|
21470
|
+
getModifiedActivityFields() {
|
|
21471
|
+
this.assertReady();
|
|
21472
|
+
return cloneDomainValue(
|
|
21473
|
+
this._saveTracker.modifiedActivityFields(
|
|
21474
|
+
(activityId) => this.coreRuntime.state.getActivity(activityId)
|
|
21475
|
+
)
|
|
21476
|
+
);
|
|
21477
|
+
}
|
|
21300
21478
|
getNewActivities() {
|
|
21301
21479
|
this.assertReady();
|
|
21302
21480
|
return this._saveTracker.newActivities(
|
|
@@ -21310,6 +21488,10 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21310
21488
|
getScheduleRevision() {
|
|
21311
21489
|
return this._scheduleRevision;
|
|
21312
21490
|
}
|
|
21491
|
+
capturePersistenceHistoryBoundary() {
|
|
21492
|
+
this.assertReady();
|
|
21493
|
+
return this._undo.capturePersistenceBoundary();
|
|
21494
|
+
}
|
|
21313
21495
|
getCanonicalDigest() {
|
|
21314
21496
|
this.assertReady();
|
|
21315
21497
|
const byId = (left, right) => String(left.id).localeCompare(String(right.id));
|
|
@@ -21480,12 +21662,29 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21480
21662
|
);
|
|
21481
21663
|
}
|
|
21482
21664
|
if (result.ok) {
|
|
21483
|
-
if (historyPolicy === "
|
|
21665
|
+
if (historyPolicy === "checkpoint-on-success") {
|
|
21666
|
+
if (action.kind !== "persistence-acknowledge") {
|
|
21667
|
+
throw new Error(
|
|
21668
|
+
"checkpoint-on-success requires persistence acknowledge"
|
|
21669
|
+
);
|
|
21670
|
+
}
|
|
21671
|
+
const currentActivities = this.coreRuntime.state.getAllActivities();
|
|
21672
|
+
const currentLinks = this.coreRuntime.state.getAllLinks();
|
|
21673
|
+
const checkpoint = action.checkpoint;
|
|
21674
|
+
const boundary = checkpoint?.historyBoundary ?? this._undo.capturePersistenceBoundary();
|
|
21484
21675
|
this._saveTracker.acknowledge(
|
|
21485
|
-
|
|
21486
|
-
|
|
21676
|
+
checkpoint?.activities ?? currentActivities,
|
|
21677
|
+
checkpoint?.links ?? currentLinks,
|
|
21678
|
+
action.activities,
|
|
21679
|
+
action.links,
|
|
21680
|
+
currentActivities,
|
|
21681
|
+
currentLinks
|
|
21682
|
+
);
|
|
21683
|
+
this._undo.discardThrough(boundary);
|
|
21684
|
+
this._undo.applyPersistedIdentities(
|
|
21685
|
+
action.activities ?? [],
|
|
21686
|
+
action.links ?? []
|
|
21487
21687
|
);
|
|
21488
|
-
this._undo.clear();
|
|
21489
21688
|
} else if (action.kind === "activity-lookahead-sync" && action.acknowledgePersistedLookahead === true) {
|
|
21490
21689
|
this._saveTracker.acknowledgePersistedLookahead(
|
|
21491
21690
|
result.changes.activities,
|