@outbuild-company/schedule-core 1.8.0 → 1.9.1

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/index.cjs CHANGED
@@ -401,16 +401,10 @@ var FIELD_REGISTRY = {
401
401
  valueKind: "reference",
402
402
  extract: (activity) => activity.calendarId === null ? null : String(activity.calendarId)
403
403
  },
404
- // Normalized to string like calendarId. It is stored as a number, so it used
405
- // to reach compareValues through the numeric branch while its sibling
406
- // reference went through the string one — the same field kind comparing two
407
- // different ways. localeCompare with numeric:true keeps the digit ordering.
408
404
  subcontractId: {
409
405
  valueKind: "reference",
410
406
  extract: (activity) => activity.subcontractId === null ? null : String(activity.subcontractId)
411
407
  },
412
- // Declared boolean, not enum: it is one, and saying so is what lets the enum
413
- // branch demand an order without inventing one for true/false.
414
408
  isCritical: {
415
409
  valueKind: "boolean",
416
410
  extract: (activity) => activity.isCritical
@@ -546,7 +540,6 @@ function evaluateVisibleIds(input) {
546
540
  function seedFilterProjection(input) {
547
541
  const { activities, parentOf, filter, context } = input;
548
542
  const matchedIds = /* @__PURE__ */ new Set();
549
- const pinnedVisibleIds = /* @__PURE__ */ new Set();
550
543
  const visibleReferenceCounts = /* @__PURE__ */ new Map();
551
544
  const parentIds = /* @__PURE__ */ new Map();
552
545
  const remainingChildren = /* @__PURE__ */ new Map();
@@ -562,17 +555,11 @@ function seedFilterProjection(input) {
562
555
  );
563
556
  }
564
557
  const isMatch = matchesFilter(activity, filter, context);
565
- const isPinned = input.pinnedVisibleIds?.has(activityId) === true;
566
- visibleReferenceCounts.set(
567
- activityId,
568
- (isMatch ? 1 : 0) + (isPinned ? 1 : 0)
569
- );
558
+ visibleReferenceCounts.set(activityId, isMatch ? 1 : 0);
570
559
  if (isMatch) matchedIds.add(activityId);
571
- if (isPinned) pinnedVisibleIds.add(activityId);
572
560
  }
573
561
  return {
574
562
  matchedIds,
575
- pinnedVisibleIds,
576
563
  visibleReferenceCounts,
577
564
  parentIds,
578
565
  remainingChildren
@@ -614,7 +601,6 @@ function buildFilterProjection(input) {
614
601
  filter: input.filter,
615
602
  context: input.context,
616
603
  matchedIds: seed2.matchedIds,
617
- pinnedVisibleIds: seed2.pinnedVisibleIds,
618
604
  visibleIds,
619
605
  visibleReferenceCounts: seed2.visibleReferenceCounts
620
606
  };
@@ -672,8 +658,6 @@ var OPERATORS_BY_KIND = {
672
658
  date: /* @__PURE__ */ new Set(["after", "before"]),
673
659
  "id-array": /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
674
660
  enum: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
675
- // Same membership operators as enum: splitting the kinds was about ordering,
676
- // not about filtering, and these two filter exactly like an enum.
677
661
  boolean: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
678
662
  reference: /* @__PURE__ */ new Set(["someOf", "notSomeOf"])
679
663
  };
@@ -853,7 +837,7 @@ function getChildrenInVisualOrder(parentId, adapter) {
853
837
  children.sort(
854
838
  userOrder === null ? compareActivitiesInVisualOrder : (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
855
839
  );
856
- return children.map((a) => String(a.id));
840
+ return children.map((activity) => String(activity.id));
857
841
  }
858
842
  function iterateInVisualOrder(adapter) {
859
843
  const result = [];
@@ -974,107 +958,61 @@ function dispatchSortSet(action, deps) {
974
958
  return { ok: true, changes };
975
959
  }
976
960
 
977
- // src/columns/text/constants.ts
978
- var TEXT = "text";
979
-
980
- // src/columns/description/constants.ts
981
- var DESCRIPTION = "description";
982
-
983
- // src/columns/duration/constants.ts
984
- var DURATION = "duration";
985
-
986
- // src/columns/progress/constants.ts
987
- var PROGRESS = "progress";
988
-
989
- // src/columns/cost/constants.ts
990
- var COST = "cost";
991
-
992
- // src/columns/used-cost/constants.ts
993
- var USED_COST = "used_cost";
994
-
995
- // src/columns/hh-work-time/constants.ts
996
- var HH_WORK_TIME = "hhWorkTime";
997
-
998
- // src/columns/start-date/constants.ts
999
- var START_DATE = "start_date";
1000
-
1001
- // src/columns/end-date/constants.ts
1002
- var END_DATE = "end_date";
1003
-
1004
- // src/columns/constraint-type/constants.ts
1005
- var CONSTRAINT_TYPE = "constraint_type";
1006
-
1007
- // src/columns/constraint-date/constants.ts
1008
- var CONSTRAINT_DATE = "constraint_date";
1009
-
1010
- // src/columns/calendar-id/constants.ts
1011
- var CALENDAR_ID = "calendar_id";
1012
-
1013
- // src/columns/custom-id/constants.ts
1014
- var CUSTOM_ID = "custom_id";
1015
-
1016
- // src/columns/subcontract-id/constants.ts
1017
- var SUBCONTRACT_ID = "subcontractId";
1018
-
1019
- // src/columns/responsables/constants.ts
1020
- var RESPONSABLES = "responsables";
1021
-
1022
- // src/columns/tags/constants.ts
1023
- var TAGS = "tags";
1024
-
1025
- // src/columns/predecessors/constants.ts
1026
- var CUSTOM_PREDECESSORS = "custom_predecessors";
1027
-
1028
- // src/columns/successors/constants.ts
1029
- var CUSTOM_SUCESSORS = "custom_sucessors";
1030
-
1031
- // src/columns/real-work/constants.ts
1032
- var REAL_WORK = "real_work";
1033
-
1034
- // src/columns/real-cost/constants.ts
1035
- var REAL_COST = "real_cost";
1036
-
1037
- // src/columns/expected-progress/constants.ts
1038
- var EXPECTED_PROGRESS = "expected_progress";
1039
-
1040
- // src/columns/expected-progress-base/constants.ts
1041
- var EXPECTED_PROGRESS_BASE = "expected_progress_base";
1042
-
1043
- // src/columns/start-base/constants.ts
1044
- var START_BASE = "start_base";
1045
-
1046
- // src/columns/end-base/constants.ts
1047
- var END_BASE = "end_base";
1048
-
1049
- // src/columns/duration-base/constants.ts
1050
- var DURATION_BASE = "duration_base";
1051
-
1052
- // src/columns/cost-base/constants.ts
1053
- var COST_BASE = "cost_base";
1054
-
1055
- // src/columns/work-base/constants.ts
1056
- var WORK_BASE = "work_base";
1057
-
1058
- // src/columns/calendar-duration/constants.ts
1059
- var CALENDAR_DURATION = "calendarDuration";
1060
-
1061
- // src/columns/critical-path/constants.ts
1062
- var IS_CRITICAL = "is_critical";
1063
- var EARLY_START = "earlyStart";
1064
- var EARLY_FINISH = "earlyFinish";
1065
- var LATE_START = "lateStart";
1066
- var LATE_FINISH = "lateFinish";
1067
- var FREE_SLACK = "freeSlack";
1068
- var TOTAL_SLACK = "totalSlack";
1069
-
1070
- // src/columns/correlative-id/constants.ts
1071
- var CORRELATIVE_ID = "correlative_id";
961
+ // src/constants/columns.ts
962
+ var EDITABLE = {
963
+ TEXT: "text",
964
+ DESCRIPTION: "description",
965
+ DURATION: "duration",
966
+ PROGRESS: "progress",
967
+ COST: "cost",
968
+ USED_COST: "used_cost",
969
+ HH_WORK_TIME: "hhWorkTime",
970
+ START_DATE: "start_date",
971
+ END_DATE: "end_date",
972
+ CONSTRAINT_TYPE: "constraint_type",
973
+ CONSTRAINT_DATE: "constraint_date",
974
+ CALENDAR_ID: "calendar_id",
975
+ CUSTOM_ID: "custom_id",
976
+ SUBCONTRACT_ID: "subcontractId",
977
+ RESPONSABLES: "responsables",
978
+ TAGS: "tags",
979
+ CUSTOM_PREDECESSORS: "custom_predecessors",
980
+ CUSTOM_SUCESSORS: "custom_sucessors"
981
+ };
982
+ var READ_ONLY = {
983
+ REAL_WORK: "real_work",
984
+ REAL_COST: "real_cost",
985
+ EXPECTED_PROGRESS: "expected_progress",
986
+ EXPECTED_PROGRESS_BASE: "expected_progress_base",
987
+ START_BASE: "start_base",
988
+ END_BASE: "end_base",
989
+ DURATION_BASE: "duration_base",
990
+ COST_BASE: "cost_base",
991
+ WORK_BASE: "work_base",
992
+ CALENDAR_DURATION: "calendarDuration",
993
+ IS_CRITICAL: "is_critical",
994
+ EARLY_START: "earlyStart",
995
+ EARLY_FINISH: "earlyFinish",
996
+ LATE_START: "lateStart",
997
+ LATE_FINISH: "lateFinish",
998
+ FREE_SLACK: "freeSlack",
999
+ TOTAL_SLACK: "totalSlack",
1000
+ CORRELATIVE_ID: "correlative_id",
1001
+ UNIQUE_CORRELATIVE_ID: "unique_correlative_id",
1002
+ PONDERATOR: "ponderator",
1003
+ STATUS: "status"
1004
+ };
1005
+ var COLUMN = { ...EDITABLE, ...READ_ONLY };
1072
1006
 
1073
- // src/columns/unique-correlative-id/constants.ts
1074
- var UNIQUE_CORRELATIVE_ID = "unique_correlative_id";
1007
+ // src/shared/assert-never.ts
1008
+ function assertNever(value, message) {
1009
+ throw new Error(message);
1010
+ }
1075
1011
 
1076
- // src/columns/ponderator/constants.ts
1077
- var PONDERATOR = "ponderator";
1012
+ // src/autoscheduler/utils/cancellation.ts
1013
+ function createIsCurrent(id, getCurrentId) {
1014
+ return () => getCurrentId() === id;
1015
+ }
1078
1016
 
1079
1017
  // src/types.ts
1080
1018
  var WORK_TIME_DIRECTION = {
@@ -1093,71 +1031,8 @@ var STATUS = {
1093
1031
  DOING: "Doing"
1094
1032
  };
1095
1033
 
1096
- // src/columns/status/constants.ts
1097
- var STATUS_COLUMN = "status";
1098
- var DEFAULT_STATUS_CRITERIA = "Baseline";
1099
- function resolveStatusCriteria(value) {
1100
- return value === "Actual" ? "Actual" : DEFAULT_STATUS_CRITERIA;
1101
- }
1102
-
1103
- // src/constants/columns.ts
1104
- var EDITABLE = {
1105
- TEXT,
1106
- DESCRIPTION,
1107
- DURATION,
1108
- PROGRESS,
1109
- COST,
1110
- USED_COST,
1111
- HH_WORK_TIME,
1112
- START_DATE,
1113
- END_DATE,
1114
- CONSTRAINT_TYPE,
1115
- CONSTRAINT_DATE,
1116
- CALENDAR_ID,
1117
- CUSTOM_ID,
1118
- SUBCONTRACT_ID,
1119
- RESPONSABLES,
1120
- TAGS,
1121
- CUSTOM_PREDECESSORS,
1122
- CUSTOM_SUCESSORS
1123
- };
1124
- var READ_ONLY = {
1125
- REAL_WORK,
1126
- REAL_COST,
1127
- EXPECTED_PROGRESS,
1128
- EXPECTED_PROGRESS_BASE,
1129
- START_BASE,
1130
- END_BASE,
1131
- DURATION_BASE,
1132
- COST_BASE,
1133
- WORK_BASE,
1134
- CALENDAR_DURATION,
1135
- IS_CRITICAL,
1136
- EARLY_START,
1137
- EARLY_FINISH,
1138
- LATE_START,
1139
- LATE_FINISH,
1140
- FREE_SLACK,
1141
- TOTAL_SLACK,
1142
- CORRELATIVE_ID,
1143
- UNIQUE_CORRELATIVE_ID,
1144
- PONDERATOR,
1145
- STATUS: STATUS_COLUMN
1146
- };
1147
- var COLUMN = { ...EDITABLE, ...READ_ONLY };
1148
-
1149
- // src/shared/assert-never.ts
1150
- function assertNever(value, message) {
1151
- throw new Error(message);
1152
- }
1153
-
1154
- // src/autoscheduler/utils/cancellation.ts
1155
- function createIsCurrent(id, getCurrentId) {
1156
- return () => getCurrentId() === id;
1157
- }
1158
-
1159
1034
  // src/constraints/index.ts
1160
- var CONSTRAINT_TYPE2 = {
1035
+ var CONSTRAINT_TYPE = {
1161
1036
  ASAP: "asap",
1162
1037
  ALAP: "alap",
1163
1038
  SNET: "snet",
@@ -2074,7 +1949,7 @@ function processConstraints(activityIds, adapter, plans) {
2074
1949
  const activity = adapter.getActivity(id);
2075
1950
  if (!activity) continue;
2076
1951
  const type = activity.constraintType;
2077
- if (!type || type === CONSTRAINT_TYPE2.ASAP || type === CONSTRAINT_TYPE2.ALAP) {
1952
+ if (!type || type === CONSTRAINT_TYPE.ASAP || type === CONSTRAINT_TYPE.ALAP) {
2078
1953
  continue;
2079
1954
  }
2080
1955
  const bounds = computeConstraintBounds(activity, adapter);
@@ -2123,14 +1998,14 @@ function validateMilestoneConstraint(activity, successorStart) {
2123
1998
  const { constraintType, constraintDate } = activity;
2124
1999
  if (!constraintType || !constraintDate) return successorStart;
2125
2000
  switch (constraintType) {
2126
- case CONSTRAINT_TYPE2.MSO:
2127
- case CONSTRAINT_TYPE2.MFO:
2001
+ case CONSTRAINT_TYPE.MSO:
2002
+ case CONSTRAINT_TYPE.MFO:
2128
2003
  return new Date(constraintDate);
2129
- case CONSTRAINT_TYPE2.SNET:
2130
- case CONSTRAINT_TYPE2.FNET:
2004
+ case CONSTRAINT_TYPE.SNET:
2005
+ case CONSTRAINT_TYPE.FNET:
2131
2006
  return constraintDate > successorStart ? new Date(constraintDate) : successorStart;
2132
- case CONSTRAINT_TYPE2.SNLT:
2133
- case CONSTRAINT_TYPE2.FNLT:
2007
+ case CONSTRAINT_TYPE.SNLT:
2008
+ case CONSTRAINT_TYPE.FNLT:
2134
2009
  return constraintDate < successorStart ? new Date(constraintDate) : successorStart;
2135
2010
  default:
2136
2011
  return successorStart;
@@ -2259,7 +2134,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2259
2134
  });
2260
2135
  plan.earliestSchedulingStart = linkStart;
2261
2136
  plan.earliestSchedulingEnd = plan.endDate;
2262
- } else if (activity.constraintType === CONSTRAINT_TYPE2.MSO) {
2137
+ } else if (activity.constraintType === CONSTRAINT_TYPE.MSO) {
2263
2138
  if (plan.earliestStart) {
2264
2139
  plan.startDate = plan.earliestStart;
2265
2140
  plan.endDate = plan.earliestEnd ?? adapter.calculateEndDate({
@@ -2268,7 +2143,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2268
2143
  task: activity
2269
2144
  });
2270
2145
  }
2271
- } else if (activity.constraintType === CONSTRAINT_TYPE2.MFO) {
2146
+ } else if (activity.constraintType === CONSTRAINT_TYPE.MFO) {
2272
2147
  if (plan.latestStart) {
2273
2148
  plan.startDate = plan.latestStart;
2274
2149
  plan.endDate = plan.latestEnd ?? adapter.calculateEndDate({
@@ -2294,7 +2169,7 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2294
2169
  const activityCount = allActivities.length;
2295
2170
  const alapActivityIds = [];
2296
2171
  for (const activity of allActivities) {
2297
- if (activity.constraintType === CONSTRAINT_TYPE2.ALAP) {
2172
+ if (activity.constraintType === CONSTRAINT_TYPE.ALAP) {
2298
2173
  alapActivityIds.push(activity.id);
2299
2174
  }
2300
2175
  }
@@ -2341,7 +2216,7 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2341
2216
  sliceStart = yieldResult.newSliceStart;
2342
2217
  const activity = adapter.getActivity(activityId);
2343
2218
  if (!activity) continue;
2344
- if (activity.constraintType !== CONSTRAINT_TYPE2.ALAP) continue;
2219
+ if (activity.constraintType !== CONSTRAINT_TYPE.ALAP) continue;
2345
2220
  if (!activity.autoScheduling) continue;
2346
2221
  if (activity.progress === COMPLETED_PROGRESS) continue;
2347
2222
  if (isSummary(activity.type, adapter.getChildren(activityId).length > 0))
@@ -2850,9 +2725,7 @@ function applyLinkCreates(links, deps) {
2850
2725
  break;
2851
2726
  }
2852
2727
  duplicateKeys.set(key, linkId);
2853
- if (existingGraphHasCycle && // ponytail: preserve legacy sequential semantics; optimize with dynamic
2854
- // SCC reachability only if corrupt cyclic schedules become measurable.
2855
- wouldIntroduceCycle(edges, {
2728
+ if (existingGraphHasCycle && wouldIntroduceCycle(edges, {
2856
2729
  source: operation.source,
2857
2730
  target: operation.target
2858
2731
  })) {
@@ -3330,7 +3203,7 @@ function widenScopeToAlapActivities(group, allLinks, adapter) {
3330
3203
  const widenedAlapKeys = /* @__PURE__ */ new Set();
3331
3204
  for (const activity of adapter.getAllActivities()) {
3332
3205
  const activityKey = String(activity.id);
3333
- const isOutOfComponentAlap = activity.constraintType === CONSTRAINT_TYPE2.ALAP && !idSet.has(activityKey);
3206
+ const isOutOfComponentAlap = activity.constraintType === CONSTRAINT_TYPE.ALAP && !idSet.has(activityKey);
3334
3207
  if (!isOutOfComponentAlap) continue;
3335
3208
  widenedAlapKeys.add(activityKey);
3336
3209
  idSet.add(activityKey);
@@ -3692,7 +3565,7 @@ var descriptionPipeline = {
3692
3565
 
3693
3566
  // src/columns/shared/activity-predicates.ts
3694
3567
  function effectiveConstraintType(activity) {
3695
- return activity.constraintType ?? CONSTRAINT_TYPE2.ASAP;
3568
+ return activity.constraintType ?? CONSTRAINT_TYPE.ASAP;
3696
3569
  }
3697
3570
  var PROGRESS_COMPLETE = COMPLETED_PROGRESS;
3698
3571
  function isCompletedActivity(activity) {
@@ -4086,8 +3959,8 @@ var costPipeline = {
4086
3959
  }
4087
3960
  return canEdit();
4088
3961
  },
4089
- parseInput(rawValue, activity) {
4090
- if (String(rawValue).trim() === "") return parsed(activity.cost);
3962
+ parseInput(rawValue) {
3963
+ if (String(rawValue).trim() === "") return parsed(0);
4091
3964
  const numericValue = parseFloat(String(rawValue));
4092
3965
  if (Number.isNaN(numericValue)) return parseError("not_a_number");
4093
3966
  return parsed(numericValue);
@@ -4136,8 +4009,8 @@ var usedCostPipeline = {
4136
4009
  }
4137
4010
  return canEdit();
4138
4011
  },
4139
- parseInput(rawValue, activity) {
4140
- if (String(rawValue).trim() === "") return parsed(activity.usedCost);
4012
+ parseInput(rawValue) {
4013
+ if (String(rawValue).trim() === "") return parsed(0);
4141
4014
  const numericValue = parseFloat(String(rawValue));
4142
4015
  if (Number.isNaN(numericValue)) return parseError("not_a_number");
4143
4016
  return parsed(numericValue);
@@ -4430,7 +4303,7 @@ function checkIsWorkingDay(newDate, activity, ctx) {
4430
4303
  return null;
4431
4304
  }
4432
4305
  function detectEndDateConstraintWarning(activity, newEndDate) {
4433
- const cannotViolateStartPin = effectiveConstraintType(activity) === CONSTRAINT_TYPE2.MSO;
4306
+ const cannotViolateStartPin = effectiveConstraintType(activity) === CONSTRAINT_TYPE.MSO;
4434
4307
  if (cannotViolateStartPin) return void 0;
4435
4308
  const projectedDate = pickProjectedDateForConstraint(
4436
4309
  effectiveConstraintType(activity),
@@ -4480,7 +4353,7 @@ function calculateNewDuration(activity, newEndDate, ctx) {
4480
4353
 
4481
4354
  // src/columns/constraint-type/constraint-type-pipeline.ts
4482
4355
  var VALID_CONSTRAINT_TYPES = new Set(
4483
- Object.values(CONSTRAINT_TYPE2)
4356
+ Object.values(CONSTRAINT_TYPE)
4484
4357
  );
4485
4358
  var constraintTypePipeline = {
4486
4359
  targetField: "constraintType",
@@ -5261,6 +5134,12 @@ function runExpectedProgressBase(state, now, defaultBaseCalendarId = null) {
5261
5134
  return computeExpectedProgress(rootIds, now, adapter, defaultBaseCalendarId);
5262
5135
  }
5263
5136
 
5137
+ // src/columns/status/constants.ts
5138
+ var DEFAULT_STATUS_CRITERIA = "Baseline";
5139
+ function resolveStatusCriteria(value) {
5140
+ return value === "Actual" ? "Actual" : DEFAULT_STATUS_CRITERIA;
5141
+ }
5142
+
5264
5143
  // src/columns/status/compute.ts
5265
5144
  var roundToTwoDecimals = (value) => Math.round(value * 100) / 100;
5266
5145
  function resolveExpectedForStatus(activity, criteria) {
@@ -5288,7 +5167,7 @@ function applyStatusPass(state, criteria) {
5288
5167
  resolveExpectedForStatus(activity, criteria)
5289
5168
  );
5290
5169
  if (activity.status !== status) {
5291
- setActivityFieldDynamic(state, id, STATUS_COLUMN, status);
5170
+ setActivityFieldDynamic(state, id, COLUMN.STATUS, status);
5292
5171
  changed.push(id);
5293
5172
  }
5294
5173
  });
@@ -9061,10 +8940,10 @@ var FreeFloat = class {
9061
8940
  this.durationCache = /* @__PURE__ */ new Map();
9062
8941
  }
9063
8942
  getFreeFloat() {
9064
- const PROGRESS2 = Number(this.activity.progress);
8943
+ const PROGRESS = Number(this.activity.progress);
9065
8944
  const CONSTRAINT = this.getConstraintType();
9066
8945
  this.calculateFreeFloatOfLink(CONSTRAINT);
9067
- const activityFreeFloat = PROGRESS2 === 100 ? 0 : this.getFreeFloatBaseConstraint(CONSTRAINT);
8946
+ const activityFreeFloat = PROGRESS === 100 ? 0 : this.getFreeFloatBaseConstraint(CONSTRAINT);
9068
8947
  return {
9069
8948
  activityFreeFloat,
9070
8949
  linksFreeFloat: this.linksFreeFloatObject
@@ -9223,11 +9102,11 @@ var FreeFloat = class {
9223
9102
  };
9224
9103
  }
9225
9104
  calculateMsoMfo(constraint) {
9226
- const CONSTRAINT_DATE2 = this.activity.constraint_date || /* @__PURE__ */ new Date();
9105
+ const CONSTRAINT_DATE = this.activity.constraint_date || /* @__PURE__ */ new Date();
9227
9106
  const calculation = this.forwardMap.get(this.activity.id);
9228
9107
  const DATE_TO_CALCULATE = constraint === CONSTRAINT_TYPES.MSO ? calculation?.es : calculation?.ef;
9229
9108
  const freeSlack = this.calculationWithCalendar(
9230
- CONSTRAINT_DATE2,
9109
+ CONSTRAINT_DATE,
9231
9110
  DATE_TO_CALCULATE
9232
9111
  );
9233
9112
  return Math.max(0, this.parseHoursToDays(freeSlack));
@@ -11290,7 +11169,7 @@ function buildParentMutations(input) {
11290
11169
  if (wasPromotableLeaf) {
11291
11170
  fields.type = PROMOTION_TARGET_TYPE;
11292
11171
  if ((input.promotionSource ?? "create") === "create") {
11293
- fields.constraintType = CONSTRAINT_TYPE2.ASAP;
11172
+ fields.constraintType = CONSTRAINT_TYPE.ASAP;
11294
11173
  fields.constraintDate = null;
11295
11174
  fields.progress = 0;
11296
11175
  }
@@ -12431,8 +12310,6 @@ function dispatchSirSync(action, deps) {
12431
12310
  id,
12432
12311
  kind: "updated",
12433
12312
  fields: { pendingRequestIds: { before, after } },
12434
- // ISSUE-025: `after` must be the COMPLETE post-change entity; a partial
12435
- // object crashes any consumer that projects the full snapshot.
12436
12313
  after: structuredCloneActivity(updated)
12437
12314
  };
12438
12315
  return {
@@ -17911,16 +17788,6 @@ var ScheduleState = class _ScheduleState {
17911
17788
  this._viewState.setActiveOrder(nextOrder);
17912
17789
  this.invalidateDerivedOrder();
17913
17790
  }
17914
- /**
17915
- * Rebuild-on-demand, memoized: at most one build per invalidation, never one
17916
- * per comparison. getChildrenInVisualOrder asks for this once and then sorts a
17917
- * whole sibling group with it, and collectBranchOrder walks every branch, so a
17918
- * build per read would be thousands per dispatch.
17919
- *
17920
- * The factory reads hoursPerDay and the collation locale at build time, so a
17921
- * rebuilt comparator always reflects the current context — that is what keeps
17922
- * ordering and filtering from seeing two different hoursPerDay.
17923
- */
17924
17791
  getOrderComparator() {
17925
17792
  const activeOrder = this._viewState.getActiveOrder();
17926
17793
  if (activeOrder === null) {
@@ -17931,12 +17798,6 @@ var ScheduleState = class _ScheduleState {
17931
17798
  this._cache.orderComparator = this._buildOrderComparator(activeOrder);
17932
17799
  return this._cache.orderComparator;
17933
17800
  }
17934
- /**
17935
- * Both order caches, always together. The comparator decides the sequence, so
17936
- * a rebuilt comparator with a surviving sequence would paint the old order.
17937
- * invalidateVisualOrderIds stays separate on purpose: a structural change
17938
- * moves rows without touching the rules, so the comparator is still valid.
17939
- */
17940
17801
  invalidateDerivedOrder() {
17941
17802
  this._cache.orderComparator = null;
17942
17803
  this._cache.visualOrderIds = null;
@@ -18119,8 +17980,8 @@ var ScheduleState = class _ScheduleState {
18119
17980
  const key = String(activityId);
18120
17981
  if (this._viewState.isChecked(key) || !this._viewState.isVisible(key)) {
18121
17982
  this._captureViewStateOnce();
18122
- this._viewState.forget(key);
18123
17983
  }
17984
+ this._viewState.forget(key);
18124
17985
  this._activities.delete(activityId);
18125
17986
  if (this._lastStartDate.has(String(activityId))) {
18126
17987
  this._captureLastStartDateOnce();
@@ -21045,29 +20906,6 @@ var ScheduleCore = class _ScheduleCore {
21045
20906
  _undo = new UndoRecorder();
21046
20907
  _opQueue = Promise.resolve();
21047
20908
  _scheduleRevision = 0;
21048
- /**
21049
- * Revision counting mutations that have been ADMITTED, whether or not they
21050
- * have changed anything yet. `_scheduleRevision` counts the ones that
21051
- * actually did.
21052
- *
21053
- * INVARIANT: `_pendingScheduleRevision >= _scheduleRevision`, and equality
21054
- * means no mutation is in flight.
21055
- *
21056
- * The two exist separately because the useful instant and the knowable
21057
- * instant are not the same one. A critical-path calculation becomes garbage
21058
- * the moment the next mutation is admitted, but whether that mutation is
21059
- * substantive is only knowable once its ChangeSet exists, which is hundreds
21060
- * of milliseconds later at project scale. Measured live on a 12268-activity
21061
- * project: the cancellation flag flipped 929 ms into a 930 ms calculation,
21062
- * 812 into 812 and 785 into 785, because the job's apply block queues behind
21063
- * the very dispatch whose completion cancels it. Cancellation and job end
21064
- * were the same event, so every discarded job ran the whole calculation.
21065
- *
21066
- * Splitting the counter buys the early signal without moving the meaning of
21067
- * `_scheduleRevision`, whose three readers (`isCriticalPathSettled`,
21068
- * `createDateGesturePreview` and the job's own `isCurrent`) are all written
21069
- * against "the state actually changed".
21070
- */
21071
20909
  _pendingScheduleRevision = 0;
21072
20910
  _criticalPathRevision = -1;
21073
20911
  _activeCriticalPath = null;
@@ -21180,13 +21018,6 @@ var ScheduleCore = class _ScheduleCore {
21180
21018
  this.assertReady();
21181
21019
  return readAllActivities(this.coreRuntime.state);
21182
21020
  }
21183
- /**
21184
- * Read del plan de indent (ISSUE-080): los padres destino DISTINTOS bajo los
21185
- * que quedarían las actividades si se indentaran ahora. Es exactamente la
21186
- * planificación que ejecuta el handler (`planIndentMoves`, autoridad única),
21187
- * expuesta para que la frontera pueda correr el protocolo de conversión a
21188
- * madre (chequeo backend + modal) ANTES de despachar. Solo lecturas.
21189
- */
21190
21021
  getIndentTargetParentIds(activityIds) {
21191
21022
  this.assertReady();
21192
21023
  const plan = planIndentMoves(
@@ -21339,7 +21170,6 @@ var ScheduleCore = class _ScheduleCore {
21339
21170
  this.assertReady();
21340
21171
  return this._saveTracker.hasUnsavedChanges();
21341
21172
  }
21342
- /** Read-only revision; moves once per substantive mutation. */
21343
21173
  getScheduleRevision() {
21344
21174
  return this._scheduleRevision;
21345
21175
  }
@@ -21385,24 +21215,10 @@ var ScheduleCore = class _ScheduleCore {
21385
21215
  );
21386
21216
  return workPromise;
21387
21217
  }
21388
- /**
21389
- * Marks a mutation as admitted and invalidates the calculation in flight.
21390
- *
21391
- * Called BEFORE `_enqueue`, which is the point of the whole thing: the wait
21392
- * in the operation queue is part of the window a running calculation wastes,
21393
- * and it is the longest part of it when several mutations are already
21394
- * queued.
21395
- *
21396
- * `dispatchChangesSchedulingState` is a pure function of the action, so this
21397
- * decision needs no state and cannot be wrong about the action's nature. What
21398
- * it cannot know yet is whether the mutation will produce anything, which is
21399
- * what `_settleScheduleMutation` reconciles afterwards.
21400
- */
21401
21218
  _beginScheduleMutation(action) {
21402
21219
  if (!dispatchChangesSchedulingState(action)) return false;
21403
21220
  return this._admitScheduleMutation();
21404
21221
  }
21405
- /** Undo and redo have no action to classify: reaching them IS the mutation. */
21406
21222
  _admitScheduleMutation() {
21407
21223
  this._pendingScheduleRevision++;
21408
21224
  if (this._activeCriticalPath) {
@@ -21410,30 +21226,6 @@ var ScheduleCore = class _ScheduleCore {
21410
21226
  }
21411
21227
  return true;
21412
21228
  }
21413
- /**
21414
- * Closes a mutation admitted by `_beginScheduleMutation`, on EVERY exit path.
21415
- *
21416
- * `changedState` false means the mutation was admitted and produced nothing
21417
- * (rejected, non-substantive, or rolled back). The pending revision walks
21418
- * back so the invariant holds and `isCriticalPathSettled` keeps telling the
21419
- * truth, and the calculation this mutation killed for nothing is re-armed.
21420
- *
21421
- * The re-arm goes through the queue and that is not incidental. Started
21422
- * outside it, the calculation would run immediately while the next queued
21423
- * mutation is still waiting, and that mutation would kill it again on
21424
- * admission: a cancel-and-restart treadmill burning a fresh project-wide deep
21425
- * copy per lap. Inside the queue the restart cannot happen until the queue
21426
- * drains, so at most one calculation is armed per settled mutation. The burst
21427
- * scenario will NOT catch a regression here, because there every dispatch
21428
- * succeeds and this path is never taken.
21429
- *
21430
- * It re-arms through `recomputeCriticalPath` rather than enqueueing the job
21431
- * directly, because the queue slot must NOT await the job: the job's own
21432
- * apply block needs a later slot on this same queue, so awaiting it from
21433
- * inside a slot deadlocks the core. `recomputeCriticalPath` already has the
21434
- * shape that returns the job's promise out of the slot instead of awaiting
21435
- * it, and it keeps `_criticalPathReady` pointing at the live calculation.
21436
- */
21437
21229
  _settleScheduleMutation(admitted, changedState) {
21438
21230
  if (!admitted) return;
21439
21231
  if (changedState) return;
@@ -21579,11 +21371,7 @@ var ScheduleCore = class _ScheduleCore {
21579
21371
  return operation;
21580
21372
  }
21581
21373
  isCriticalPathSettled() {
21582
- return this._criticalPathRevision === this._scheduleRevision && // An admitted mutation has not landed yet, so whatever is applied now is
21583
- // about to be stale. Without this term `whenCriticalPathSettled` would
21584
- // spin: it would keep arming calculations that `isCurrent` kills on their
21585
- // first check, each one paying the project-wide deep copy first.
21586
- this._pendingScheduleRevision === this._scheduleRevision && this._activeCriticalPath === null;
21374
+ return this._criticalPathRevision === this._scheduleRevision && this._pendingScheduleRevision === this._scheduleRevision && this._activeCriticalPath === null;
21587
21375
  }
21588
21376
  async whenCriticalPathSettled() {
21589
21377
  while (!this.isCriticalPathSettled()) {
@@ -21599,21 +21387,6 @@ var ScheduleCore = class _ScheduleCore {
21599
21387
  const merged = this._reapplyViewState(result.changes);
21600
21388
  return merged === null ? result : { ...result, changes: merged };
21601
21389
  }
21602
- /**
21603
- * The single place the two view-state passes are chained. Dispatch, undo and
21604
- * redo all route through here: when this existed only inside the dispatch
21605
- * path, undo and redo reapplied the filter and forgot the order, so an edit
21606
- * that moved a row and was then undone left the row in its new position.
21607
- *
21608
- * The sequence between the passes is indifferent. Filter and order are
21609
- * orthogonal projections over the same tree — the filter decides which rows
21610
- * exist on screen and never reads the order; the order sequences every
21611
- * sibling group from the hierarchy index and never reads visibility. Either
21612
- * sequence produces the same ChangeSet.
21613
- *
21614
- * Both passes answer null while their state is inactive, so an unfiltered,
21615
- * unsorted schedule pays two property reads.
21616
- */
21617
21390
  _reapplyViewState(changes) {
21618
21391
  const withFilter = this._reapplyActiveFilter(changes);
21619
21392
  const sequenced = this._emitTouchedBranchOrder(withFilter ?? changes);
@@ -21621,58 +21394,8 @@ var ScheduleCore = class _ScheduleCore {
21621
21394
  sequenced.changes ?? withFilter ?? changes,
21622
21395
  sequenced.touchedParents
21623
21396
  );
21624
- const reapplied = withOrder ?? sequenced.changes ?? withFilter;
21625
- const finalChanges = reapplied ?? changes;
21626
- const createdIds = finalChanges.activities.filter((change) => change.kind === "created").map((change) => String(change.id));
21627
- if (createdIds.length === 0) return reapplied;
21628
- const createdAndAncestors = new Set(createdIds);
21629
- const filterProjection = this.coreRuntime.state.getFilterProjection();
21630
- for (const createdId of createdIds) {
21631
- if (filterProjection !== null) {
21632
- filterProjection.pinnedVisibleIds.add(createdId);
21633
- }
21634
- let activityId = createdId;
21635
- while (activityId !== null && activityId !== ROOT_PARENT_ID) {
21636
- createdAndAncestors.add(activityId);
21637
- if (filterProjection !== null) {
21638
- filterProjection.visibleIds.add(activityId);
21639
- filterProjection.visibleReferenceCounts.set(
21640
- activityId,
21641
- (filterProjection.visibleReferenceCounts.get(activityId) ?? 0) + 1
21642
- );
21643
- }
21644
- activityId = this.coreRuntime.state.getParentId(activityId);
21645
- }
21646
- }
21647
- const createdVisibility = applyVisibleSet(
21648
- this.coreRuntime.state,
21649
- createdAndAncestors,
21650
- createdAndAncestors
21651
- );
21652
- if (createdVisibility.length === 0) return reapplied;
21653
- return {
21654
- ...finalChanges,
21655
- viewState: [...finalChanges.viewState ?? [], ...createdVisibility]
21656
- };
21397
+ return withOrder ?? sequenced.changes ?? withFilter;
21657
21398
  }
21658
- /**
21659
- * Emits `order` for the branches this mutation resequenced, when no user order
21660
- * is active.
21661
- *
21662
- * The contract is that `order` reports a CHANGED SEQUENCE, not the presence of
21663
- * a sort. Tying emission to the cause instead of the effect is what produced
21664
- * the undo bug and, later, the reparent ones: without an active order a move,
21665
- * an indent, an outdent or the undo of any of them rearranged rows and said
21666
- * nothing, so an incremental consumer kept the old sequence. The undo of a
21667
- * reparent was the worst of them — it carried neither `order` nor a single
21668
- * correlativeId, so the position was not recoverable by any consumer.
21669
- *
21670
- * The touched branches are derived from the ChangeSet rather than accumulated
21671
- * in the state: an entity whose parentId or correlativeId moved, plus the
21672
- * parents of created and deleted rows, is exactly the set of branches whose
21673
- * sequence can differ. That keeps this linear in the blast radius, adds
21674
- * nothing to the write path, and cannot leak across dispatches.
21675
- */
21676
21399
  _emitTouchedBranchOrder(changes) {
21677
21400
  const adapter = this.coreRuntime.state;
21678
21401
  const touchedParents = collectResequencedParents(
@@ -21689,15 +21412,6 @@ var ScheduleCore = class _ScheduleCore {
21689
21412
  if (order.length === 0) return { changes: null, touchedParents };
21690
21413
  return { changes: { ...changes, order }, touchedParents };
21691
21414
  }
21692
- /**
21693
- * Re-sequences the grid after any mutation that could have changed a value the
21694
- * active order sorts by. Ordering is a view over the data, so an edit that
21695
- * moves a row past its sibling must move the row, exactly as the filter makes
21696
- * a no-longer-matching row disappear.
21697
- *
21698
- * Production only re-sorts after a bar drag; diverging from that is a
21699
- * deliberate product decision, not an oversight.
21700
- */
21701
21415
  _reapplyActiveOrder(changes, resequencedParents) {
21702
21416
  const adapter = this.coreRuntime.state;
21703
21417
  if (adapter.getActiveOrder() === null) return null;
@@ -21740,8 +21454,7 @@ var ScheduleCore = class _ScheduleCore {
21740
21454
  activities: adapter.getAllActivities(),
21741
21455
  parentOf: (activityId) => adapter.getParentId(activityId),
21742
21456
  filter,
21743
- context,
21744
- ...projectionIsCurrent ? { pinnedVisibleIds: projection.pinnedVisibleIds } : {}
21457
+ context
21745
21458
  });
21746
21459
  adapter.setFilterProjection(rebuiltProjection);
21747
21460
  visibleIds = rebuiltProjection.visibleIds;
@@ -21797,11 +21510,7 @@ var ScheduleCore = class _ScheduleCore {
21797
21510
  this.coreRuntime.baseCalendars
21798
21511
  )
21799
21512
  );
21800
- const isCurrent = () => !cancellation.cancelled && this._status !== SCHEDULE_CORE_STATUS.DESTROYED && this._scheduleRevision === revision && // A mutation admitted but not yet settled is enough to make this result
21801
- // garbage. Without this term the calculation only learns it is obsolete
21802
- // when the mutation finishes, which measured live is the same instant the
21803
- // job itself ends.
21804
- this._pendingScheduleRevision === this._scheduleRevision;
21513
+ const isCurrent = () => !cancellation.cancelled && this._status !== SCHEDULE_CORE_STATUS.DESTROYED && this._scheduleRevision === revision && this._pendingScheduleRevision === this._scheduleRevision;
21805
21514
  const promise = (async () => {
21806
21515
  const calculatedFields = await computeCriticalPathFields(
21807
21516
  isolatedState,
@@ -22154,7 +21863,7 @@ var CREATION_KIND = {
22154
21863
  exports.ACTIVITY_TYPE = ACTIVITY_TYPE;
22155
21864
  exports.CALENDAR_UNIT = CALENDAR_UNIT;
22156
21865
  exports.COLUMN = COLUMN;
22157
- exports.CONSTRAINT_TYPE = CONSTRAINT_TYPE2;
21866
+ exports.CONSTRAINT_TYPE = CONSTRAINT_TYPE;
22158
21867
  exports.CONSTRAINT_TYPE_TO_LABEL = CONSTRAINT_TYPE_TO_LABEL;
22159
21868
  exports.CREATION_KIND = CREATION_KIND;
22160
21869
  exports.DEFAULT_HOURS_PER_DAY = DEFAULT_HOURS_PER_DAY;