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