@outbuild-company/schedule-core 1.9.2 → 1.9.3
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 +196 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -6
- package/dist/index.d.ts +60 -6
- package/dist/index.js +196 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -12543,28 +12543,6 @@ function assertValidAssignments(assignments, entityName, readCurrent, ownerByBac
|
|
|
12543
12543
|
);
|
|
12544
12544
|
}
|
|
12545
12545
|
}
|
|
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
12546
|
async function applyReconciledProgress(entries, deps) {
|
|
12569
12547
|
const progressToApply = entries.filter((entry) => {
|
|
12570
12548
|
const current = deps.adapter.getActivity(String(entry.activityId));
|
|
@@ -12595,19 +12573,25 @@ async function applyReconciledProgress(entries, deps) {
|
|
|
12595
12573
|
async function dispatchPersistenceAcknowledge(action, deps) {
|
|
12596
12574
|
const activities = action.activities ?? [];
|
|
12597
12575
|
const links = action.links ?? [];
|
|
12598
|
-
const reconciledProgress = action.reconciledProgress ?? [];
|
|
12599
|
-
assertValidReconciledProgress(reconciledProgress, deps);
|
|
12600
12576
|
const currentActivities = deps.adapter.getAllActivities();
|
|
12601
12577
|
const currentLinks = deps.adapter.getAllLinks();
|
|
12602
|
-
const
|
|
12603
|
-
const
|
|
12578
|
+
const checkpointActivities = action.checkpoint?.activities ?? currentActivities;
|
|
12579
|
+
const checkpointLinks = action.checkpoint?.links ?? currentLinks;
|
|
12580
|
+
const checkpointActivityById = new Map(
|
|
12581
|
+
checkpointActivities.map((activity) => [String(activity.id), activity])
|
|
12582
|
+
);
|
|
12583
|
+
const checkpointLinkById = new Map(
|
|
12584
|
+
checkpointLinks.map((link) => [String(link.id), link])
|
|
12585
|
+
);
|
|
12586
|
+
const activityOwnerByBackendId = persistedOwnersOf(checkpointActivities);
|
|
12587
|
+
const linkOwnerByBackendId = persistedOwnersOf(checkpointLinks);
|
|
12604
12588
|
assertValidAssignments(
|
|
12605
12589
|
activities,
|
|
12606
12590
|
"activity",
|
|
12607
12591
|
(id) => {
|
|
12608
|
-
const activity =
|
|
12592
|
+
const activity = checkpointActivityById.get(id);
|
|
12609
12593
|
return {
|
|
12610
|
-
exists: activity !==
|
|
12594
|
+
exists: activity !== void 0,
|
|
12611
12595
|
current: activity?.proplannerId ?? null
|
|
12612
12596
|
};
|
|
12613
12597
|
},
|
|
@@ -12617,17 +12601,21 @@ async function dispatchPersistenceAcknowledge(action, deps) {
|
|
|
12617
12601
|
links,
|
|
12618
12602
|
"link",
|
|
12619
12603
|
(id) => {
|
|
12620
|
-
const link =
|
|
12621
|
-
return {
|
|
12604
|
+
const link = checkpointLinkById.get(id);
|
|
12605
|
+
return {
|
|
12606
|
+
exists: link !== void 0,
|
|
12607
|
+
current: link?.proplannerId ?? null
|
|
12608
|
+
};
|
|
12622
12609
|
},
|
|
12623
12610
|
linkOwnerByBackendId
|
|
12624
12611
|
);
|
|
12625
|
-
assertAllNewEntitiesAcknowledged(
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
deps
|
|
12612
|
+
assertAllNewEntitiesAcknowledged(
|
|
12613
|
+
checkpointActivities,
|
|
12614
|
+
activities,
|
|
12615
|
+
"activity"
|
|
12630
12616
|
);
|
|
12617
|
+
assertAllNewEntitiesAcknowledged(checkpointLinks, links, "link");
|
|
12618
|
+
const activityChanges = [];
|
|
12631
12619
|
const linkChanges = [];
|
|
12632
12620
|
deps.adapter.batchUpdate(() => {
|
|
12633
12621
|
for (const assignment of activities) {
|
|
@@ -18441,7 +18429,9 @@ function mergeCoalesced(top, next) {
|
|
|
18441
18429
|
return buildUndoEntry(changeSet);
|
|
18442
18430
|
}
|
|
18443
18431
|
function getDispatchHistoryPolicy(action) {
|
|
18444
|
-
if (action.kind === "persistence-acknowledge")
|
|
18432
|
+
if (action.kind === "persistence-acknowledge") {
|
|
18433
|
+
return "checkpoint-on-success";
|
|
18434
|
+
}
|
|
18445
18435
|
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
18436
|
return "skip";
|
|
18447
18437
|
}
|
|
@@ -18697,22 +18687,25 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18697
18687
|
maxDepth;
|
|
18698
18688
|
undoStack = [];
|
|
18699
18689
|
redoStack = [];
|
|
18690
|
+
sequence = 0;
|
|
18700
18691
|
_lastKey = null;
|
|
18701
18692
|
_lastTime = 0;
|
|
18702
18693
|
fork() {
|
|
18703
18694
|
const fork = new _UndoRecorder(this.maxDepth);
|
|
18704
18695
|
fork.undoStack.push(...cloneDomainValue(this.undoStack));
|
|
18705
18696
|
fork.redoStack.push(...cloneDomainValue(this.redoStack));
|
|
18697
|
+
fork.sequence = this.sequence;
|
|
18706
18698
|
fork._lastKey = this._lastKey;
|
|
18707
18699
|
fork._lastTime = this._lastTime;
|
|
18708
18700
|
return fork;
|
|
18709
18701
|
}
|
|
18710
18702
|
record(entry, coalesceKey = null, now = 0) {
|
|
18711
18703
|
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
|
-
|
|
18704
|
+
if (coalesceKey != null && coalesceKey === this._lastKey && now - this._lastTime <= COALESCE_WINDOW_MS && top !== void 0 && canCoalesce(top.entry, entry)) {
|
|
18705
|
+
top.entry = mergeCoalesced(top.entry, entry);
|
|
18706
|
+
top.touchedAt = this.touch();
|
|
18714
18707
|
} else {
|
|
18715
|
-
this.undoStack.push(entry);
|
|
18708
|
+
this.undoStack.push({ entry, touchedAt: this.touch() });
|
|
18716
18709
|
if (this.undoStack.length > this.maxDepth) {
|
|
18717
18710
|
this.undoStack.splice(0, this.undoStack.length - this.maxDepth);
|
|
18718
18711
|
}
|
|
@@ -18725,16 +18718,16 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18725
18718
|
this._lastKey = null;
|
|
18726
18719
|
}
|
|
18727
18720
|
takeUndo() {
|
|
18728
|
-
return this.undoStack.pop() ?? null;
|
|
18721
|
+
return this.undoStack.pop()?.entry ?? null;
|
|
18729
18722
|
}
|
|
18730
18723
|
takeRedo() {
|
|
18731
|
-
return this.redoStack.pop() ?? null;
|
|
18724
|
+
return this.redoStack.pop()?.entry ?? null;
|
|
18732
18725
|
}
|
|
18733
18726
|
pushRedo(entry) {
|
|
18734
|
-
this.redoStack.push(entry);
|
|
18727
|
+
this.redoStack.push({ entry, touchedAt: this.touch() });
|
|
18735
18728
|
}
|
|
18736
18729
|
pushUndo(entry) {
|
|
18737
|
-
this.undoStack.push(entry);
|
|
18730
|
+
this.undoStack.push({ entry, touchedAt: this.touch() });
|
|
18738
18731
|
}
|
|
18739
18732
|
canUndo() {
|
|
18740
18733
|
return this.undoStack.length > 0;
|
|
@@ -18745,11 +18738,64 @@ var UndoRecorder = class _UndoRecorder {
|
|
|
18745
18738
|
undoDepth() {
|
|
18746
18739
|
return this.undoStack.length;
|
|
18747
18740
|
}
|
|
18741
|
+
capturePersistenceBoundary() {
|
|
18742
|
+
this.resetCoalesce();
|
|
18743
|
+
return this.sequence;
|
|
18744
|
+
}
|
|
18745
|
+
discardThrough(boundary) {
|
|
18746
|
+
this.removeEntriesThrough(this.undoStack, boundary);
|
|
18747
|
+
this.removeEntriesThrough(this.redoStack, boundary);
|
|
18748
|
+
this.resetCoalesce();
|
|
18749
|
+
}
|
|
18750
|
+
applyPersistedIdentities(activities, links) {
|
|
18751
|
+
const activityIds = new Map(
|
|
18752
|
+
activities.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
18753
|
+
);
|
|
18754
|
+
const linkIds = new Map(
|
|
18755
|
+
links.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
18756
|
+
);
|
|
18757
|
+
for (const stored of [...this.undoStack, ...this.redoStack]) {
|
|
18758
|
+
stored.entry = this.withPersistedIdentities(
|
|
18759
|
+
stored.entry,
|
|
18760
|
+
activityIds,
|
|
18761
|
+
linkIds
|
|
18762
|
+
);
|
|
18763
|
+
}
|
|
18764
|
+
}
|
|
18748
18765
|
clear() {
|
|
18749
18766
|
this.undoStack.length = 0;
|
|
18750
18767
|
this.redoStack.length = 0;
|
|
18751
18768
|
this.resetCoalesce();
|
|
18752
18769
|
}
|
|
18770
|
+
touch() {
|
|
18771
|
+
this.sequence += 1;
|
|
18772
|
+
return this.sequence;
|
|
18773
|
+
}
|
|
18774
|
+
removeEntriesThrough(stack, boundary) {
|
|
18775
|
+
const retained = stack.filter(({ touchedAt }) => touchedAt > boundary);
|
|
18776
|
+
stack.splice(0, stack.length, ...retained);
|
|
18777
|
+
}
|
|
18778
|
+
withPersistedIdentities(entry, activityIds, linkIds) {
|
|
18779
|
+
const patchActivities = (snapshots) => snapshots === void 0 ? void 0 : new Map(
|
|
18780
|
+
Array.from(snapshots, ([id, activity]) => [
|
|
18781
|
+
id,
|
|
18782
|
+
activityIds.has(id) ? { ...activity, proplannerId: activityIds.get(id) } : activity
|
|
18783
|
+
])
|
|
18784
|
+
);
|
|
18785
|
+
const patchLinks = (snapshots) => snapshots === void 0 ? void 0 : new Map(
|
|
18786
|
+
Array.from(snapshots, ([id, link]) => [
|
|
18787
|
+
id,
|
|
18788
|
+
linkIds.has(id) ? { ...link, proplannerId: linkIds.get(id) } : link
|
|
18789
|
+
])
|
|
18790
|
+
);
|
|
18791
|
+
return {
|
|
18792
|
+
...entry,
|
|
18793
|
+
beforeSnap: patchActivities(entry.beforeSnap),
|
|
18794
|
+
afterSnap: patchActivities(entry.afterSnap),
|
|
18795
|
+
beforeLinks: patchLinks(entry.beforeLinks),
|
|
18796
|
+
afterLinks: patchLinks(entry.afterLinks)
|
|
18797
|
+
};
|
|
18798
|
+
}
|
|
18753
18799
|
};
|
|
18754
18800
|
|
|
18755
18801
|
// src/dispatch/shared/resequenced-parents.ts
|
|
@@ -18907,10 +18953,12 @@ function snapshotFieldValue(field, value) {
|
|
|
18907
18953
|
return value;
|
|
18908
18954
|
}
|
|
18909
18955
|
function activityChangedSince(current, saved) {
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
return
|
|
18956
|
+
return changedPersistableActivityFields(current, saved).length > 0;
|
|
18957
|
+
}
|
|
18958
|
+
function changedPersistableActivityFields(current, saved) {
|
|
18959
|
+
return PERSISTABLE_ACTIVITY_FIELDS.filter(
|
|
18960
|
+
(field) => !fieldEquals(field, current[field], saved[field])
|
|
18961
|
+
);
|
|
18914
18962
|
}
|
|
18915
18963
|
function fieldEquals(field, currentValue, savedValue) {
|
|
18916
18964
|
if (DATE_FIELDS2.has(field)) return dateEquals(currentValue, savedValue);
|
|
@@ -19019,11 +19067,60 @@ var SaveTracker = class _SaveTracker {
|
|
|
19019
19067
|
}
|
|
19020
19068
|
this.initialized = true;
|
|
19021
19069
|
}
|
|
19022
|
-
acknowledge(activities, links) {
|
|
19070
|
+
acknowledge(activities, links, activityIdentities = [], linkIdentities = [], currentActivities, currentLinks) {
|
|
19023
19071
|
if (!this.trackingEnabled) return;
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19072
|
+
const activityIds = new Map(
|
|
19073
|
+
activityIdentities.map(({ id, proplannerId }) => [
|
|
19074
|
+
String(id),
|
|
19075
|
+
proplannerId
|
|
19076
|
+
])
|
|
19077
|
+
);
|
|
19078
|
+
const linkIds = new Map(
|
|
19079
|
+
linkIdentities.map(({ id, proplannerId }) => [String(id), proplannerId])
|
|
19080
|
+
);
|
|
19081
|
+
const persistedActivities = activities.map((activity) => ({
|
|
19082
|
+
...activity,
|
|
19083
|
+
proplannerId: activityIds.get(String(activity.id)) ?? activity.proplannerId
|
|
19084
|
+
}));
|
|
19085
|
+
const persistedLinks = links.map((link) => {
|
|
19086
|
+
const proplannerId = linkIds.get(String(link.id));
|
|
19087
|
+
return proplannerId === void 0 ? { ...link } : { ...link, proplannerId };
|
|
19088
|
+
});
|
|
19089
|
+
assertValidPersistedIdentities(persistedActivities, persistedLinks);
|
|
19090
|
+
this.snapshotActivities(persistedActivities);
|
|
19091
|
+
this.snapshotLinks(persistedLinks);
|
|
19092
|
+
if (!currentActivities || !currentLinks) return;
|
|
19093
|
+
const currentActivityById = new Map(
|
|
19094
|
+
currentActivities.map((activity) => [String(activity.id), activity])
|
|
19095
|
+
);
|
|
19096
|
+
const currentLinkById = new Map(
|
|
19097
|
+
currentLinks.map((link) => [String(link.id), link])
|
|
19098
|
+
);
|
|
19099
|
+
for (const activity of persistedActivities) {
|
|
19100
|
+
const activityId = String(activity.id);
|
|
19101
|
+
if (this.activityIsDirty(
|
|
19102
|
+
activityId,
|
|
19103
|
+
currentActivityById.get(activityId) ?? null
|
|
19104
|
+
)) {
|
|
19105
|
+
this.dirtyActivityIds.add(activityId);
|
|
19106
|
+
}
|
|
19107
|
+
}
|
|
19108
|
+
for (const activity of currentActivities) {
|
|
19109
|
+
const activityId = String(activity.id);
|
|
19110
|
+
if (this.activityIsDirty(activityId, activity)) {
|
|
19111
|
+
this.dirtyActivityIds.add(activityId);
|
|
19112
|
+
}
|
|
19113
|
+
}
|
|
19114
|
+
for (const link of persistedLinks) {
|
|
19115
|
+
const linkId = String(link.id);
|
|
19116
|
+
if (this.linkIsDirty(linkId, currentLinkById.get(linkId) ?? null)) {
|
|
19117
|
+
this.dirtyLinkIds.add(linkId);
|
|
19118
|
+
}
|
|
19119
|
+
}
|
|
19120
|
+
for (const link of currentLinks) {
|
|
19121
|
+
const linkId = String(link.id);
|
|
19122
|
+
if (this.linkIsDirty(linkId, link)) this.dirtyLinkIds.add(linkId);
|
|
19123
|
+
}
|
|
19027
19124
|
}
|
|
19028
19125
|
snapshotActivities(activities) {
|
|
19029
19126
|
if (!this.trackingEnabled) return;
|
|
@@ -19207,6 +19304,21 @@ var SaveTracker = class _SaveTracker {
|
|
|
19207
19304
|
}
|
|
19208
19305
|
return modified;
|
|
19209
19306
|
}
|
|
19307
|
+
modifiedActivityFields(getActivity) {
|
|
19308
|
+
const result = /* @__PURE__ */ new Map();
|
|
19309
|
+
if (!this.trackingEnabled || !this.initialized) return result;
|
|
19310
|
+
for (const activityId of this.dirtyActivityIds) {
|
|
19311
|
+
const current = getActivity(activityId);
|
|
19312
|
+
const saved = this.activitiesAtLastSave.get(activityId);
|
|
19313
|
+
if (!current || !saved) continue;
|
|
19314
|
+
const fields = changedPersistableActivityFields(
|
|
19315
|
+
current,
|
|
19316
|
+
saved.persistable
|
|
19317
|
+
);
|
|
19318
|
+
if (fields.length > 0) result.set(activityId, fields);
|
|
19319
|
+
}
|
|
19320
|
+
return result;
|
|
19321
|
+
}
|
|
19210
19322
|
modifiedLinks(getLink) {
|
|
19211
19323
|
if (!this.trackingEnabled || !this.initialized) return [];
|
|
19212
19324
|
const modified = [];
|
|
@@ -21299,6 +21411,14 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21299
21411
|
(activityId) => this.coreRuntime.state.getActivity(activityId)
|
|
21300
21412
|
).map(cloneDomainValue);
|
|
21301
21413
|
}
|
|
21414
|
+
getModifiedActivityFields() {
|
|
21415
|
+
this.assertReady();
|
|
21416
|
+
return cloneDomainValue(
|
|
21417
|
+
this._saveTracker.modifiedActivityFields(
|
|
21418
|
+
(activityId) => this.coreRuntime.state.getActivity(activityId)
|
|
21419
|
+
)
|
|
21420
|
+
);
|
|
21421
|
+
}
|
|
21302
21422
|
getNewActivities() {
|
|
21303
21423
|
this.assertReady();
|
|
21304
21424
|
return this._saveTracker.newActivities(
|
|
@@ -21312,6 +21432,10 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21312
21432
|
getScheduleRevision() {
|
|
21313
21433
|
return this._scheduleRevision;
|
|
21314
21434
|
}
|
|
21435
|
+
capturePersistenceHistoryBoundary() {
|
|
21436
|
+
this.assertReady();
|
|
21437
|
+
return this._undo.capturePersistenceBoundary();
|
|
21438
|
+
}
|
|
21315
21439
|
getCanonicalDigest() {
|
|
21316
21440
|
this.assertReady();
|
|
21317
21441
|
const byId = (left, right) => String(left.id).localeCompare(String(right.id));
|
|
@@ -21482,12 +21606,29 @@ var ScheduleCore = class _ScheduleCore {
|
|
|
21482
21606
|
);
|
|
21483
21607
|
}
|
|
21484
21608
|
if (result.ok) {
|
|
21485
|
-
if (historyPolicy === "
|
|
21609
|
+
if (historyPolicy === "checkpoint-on-success") {
|
|
21610
|
+
if (action.kind !== "persistence-acknowledge") {
|
|
21611
|
+
throw new Error(
|
|
21612
|
+
"checkpoint-on-success requires persistence acknowledge"
|
|
21613
|
+
);
|
|
21614
|
+
}
|
|
21615
|
+
const currentActivities = this.coreRuntime.state.getAllActivities();
|
|
21616
|
+
const currentLinks = this.coreRuntime.state.getAllLinks();
|
|
21617
|
+
const checkpoint = action.checkpoint;
|
|
21618
|
+
const boundary = checkpoint?.historyBoundary ?? this._undo.capturePersistenceBoundary();
|
|
21486
21619
|
this._saveTracker.acknowledge(
|
|
21487
|
-
|
|
21488
|
-
|
|
21620
|
+
checkpoint?.activities ?? currentActivities,
|
|
21621
|
+
checkpoint?.links ?? currentLinks,
|
|
21622
|
+
action.activities,
|
|
21623
|
+
action.links,
|
|
21624
|
+
currentActivities,
|
|
21625
|
+
currentLinks
|
|
21626
|
+
);
|
|
21627
|
+
this._undo.discardThrough(boundary);
|
|
21628
|
+
this._undo.applyPersistedIdentities(
|
|
21629
|
+
action.activities ?? [],
|
|
21630
|
+
action.links ?? []
|
|
21489
21631
|
);
|
|
21490
|
-
this._undo.clear();
|
|
21491
21632
|
} else if (action.kind === "activity-lookahead-sync" && action.acknowledgePersistedLookahead === true) {
|
|
21492
21633
|
this._saveTracker.acknowledgePersistedLookahead(
|
|
21493
21634
|
result.changes.activities,
|