@outbuild-company/schedule-core 1.9.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.js CHANGED
@@ -399,16 +399,10 @@ var FIELD_REGISTRY = {
399
399
  valueKind: "reference",
400
400
  extract: (activity) => activity.calendarId === null ? null : String(activity.calendarId)
401
401
  },
402
- // Normalized to string like calendarId. It is stored as a number, so it used
403
- // to reach compareValues through the numeric branch while its sibling
404
- // reference went through the string one — the same field kind comparing two
405
- // different ways. localeCompare with numeric:true keeps the digit ordering.
406
402
  subcontractId: {
407
403
  valueKind: "reference",
408
404
  extract: (activity) => activity.subcontractId === null ? null : String(activity.subcontractId)
409
405
  },
410
- // Declared boolean, not enum: it is one, and saying so is what lets the enum
411
- // branch demand an order without inventing one for true/false.
412
406
  isCritical: {
413
407
  valueKind: "boolean",
414
408
  extract: (activity) => activity.isCritical
@@ -418,107 +412,6 @@ function getFieldDescriptor(field) {
418
412
  return FIELD_REGISTRY[field] ?? null;
419
413
  }
420
414
 
421
- // src/internal/state/view-state.ts
422
- function isRelativePlacementPinValid(activityId, pin, parentOf) {
423
- const branchParentId = String(pin.branchParentId);
424
- const currentParentId = String(parentOf(activityId) ?? "0");
425
- if (currentParentId !== branchParentId) return false;
426
- const referenceId = String(pin.referenceId);
427
- return referenceId === branchParentId || String(parentOf(referenceId) ?? "0") === branchParentId;
428
- }
429
- var ViewStateStore = class {
430
- checkedSet = /* @__PURE__ */ new Set();
431
- hiddenSet = /* @__PURE__ */ new Set();
432
- activeFilter = null;
433
- activeOrder = null;
434
- relativePlacementPins = /* @__PURE__ */ new Map();
435
- isChecked(activityId) {
436
- return this.checkedSet.has(activityId);
437
- }
438
- isVisible(activityId) {
439
- return !this.hiddenSet.has(activityId);
440
- }
441
- hiddenIds() {
442
- return [...this.hiddenSet];
443
- }
444
- getActiveFilter() {
445
- return this.activeFilter;
446
- }
447
- setActiveFilter(nextFilter) {
448
- this.activeFilter = nextFilter;
449
- }
450
- getActiveOrder() {
451
- return this.activeOrder;
452
- }
453
- setActiveOrder(nextOrder) {
454
- this.activeOrder = nextOrder;
455
- }
456
- setRelativePlacementPin(activityId, pin) {
457
- this.relativePlacementPins.set(String(activityId), {
458
- referenceId: String(pin.referenceId),
459
- branchParentId: String(pin.branchParentId),
460
- side: pin.side
461
- });
462
- }
463
- getRelativePlacementPins() {
464
- return this.relativePlacementPins;
465
- }
466
- restoreRelativePlacementPins(pins) {
467
- this.relativePlacementPins = new Map(pins);
468
- }
469
- checkedIds() {
470
- return [...this.checkedSet];
471
- }
472
- checkedCount() {
473
- return this.checkedSet.size;
474
- }
475
- setChecked(activityId, nextChecked) {
476
- if (nextChecked === this.checkedSet.has(activityId)) return false;
477
- if (nextChecked) this.checkedSet.add(activityId);
478
- else this.checkedSet.delete(activityId);
479
- return true;
480
- }
481
- setVisible(activityId, nextVisible) {
482
- if (nextVisible === !this.hiddenSet.has(activityId)) return false;
483
- if (nextVisible) this.hiddenSet.delete(activityId);
484
- else this.hiddenSet.add(activityId);
485
- return true;
486
- }
487
- forget(activityId) {
488
- this.checkedSet.delete(activityId);
489
- this.hiddenSet.delete(activityId);
490
- this.relativePlacementPins.delete(activityId);
491
- for (const [pinnedId, pin] of this.relativePlacementPins) {
492
- if (pin.referenceId === activityId) {
493
- this.relativePlacementPins.delete(pinnedId);
494
- }
495
- }
496
- }
497
- hydrate(seed2) {
498
- this.checkedSet = new Set(seed2.checkedIds ?? []);
499
- this.hiddenSet = new Set(seed2.hiddenIds ?? []);
500
- this.activeFilter = null;
501
- this.activeOrder = null;
502
- this.relativePlacementPins = /* @__PURE__ */ new Map();
503
- }
504
- snapshot() {
505
- return {
506
- checked: new Set(this.checkedSet),
507
- hidden: new Set(this.hiddenSet),
508
- activeFilter: this.activeFilter,
509
- activeOrder: this.activeOrder,
510
- relativePlacementPins: new Map(this.relativePlacementPins)
511
- };
512
- }
513
- restore(snapshot) {
514
- this.checkedSet = new Set(snapshot.checked);
515
- this.hiddenSet = new Set(snapshot.hidden);
516
- this.activeFilter = snapshot.activeFilter;
517
- this.activeOrder = snapshot.activeOrder;
518
- this.relativePlacementPins = new Map(snapshot.relativePlacementPins);
519
- }
520
- };
521
-
522
415
  // src/internal/filter/evaluate-filter.ts
523
416
  function toTargetDate(value) {
524
417
  if (value instanceof Date) return value;
@@ -645,7 +538,6 @@ function evaluateVisibleIds(input) {
645
538
  function seedFilterProjection(input) {
646
539
  const { activities, parentOf, filter, context } = input;
647
540
  const matchedIds = /* @__PURE__ */ new Set();
648
- const pinnedVisibleIds = /* @__PURE__ */ new Set();
649
541
  const visibleReferenceCounts = /* @__PURE__ */ new Map();
650
542
  const parentIds = /* @__PURE__ */ new Map();
651
543
  const remainingChildren = /* @__PURE__ */ new Map();
@@ -666,35 +558,11 @@ function seedFilterProjection(input) {
666
558
  }
667
559
  return {
668
560
  matchedIds,
669
- pinnedVisibleIds,
670
561
  visibleReferenceCounts,
671
562
  parentIds,
672
563
  remainingChildren
673
564
  };
674
565
  }
675
- function applyRelativePlacementPins(seed2, pins) {
676
- if (pins === void 0) return;
677
- for (const [activityId, pin] of pins) {
678
- const pinnedId = String(activityId);
679
- const referenceId = String(pin.referenceId);
680
- if (!seed2.parentIds.has(pinnedId) || !seed2.parentIds.has(referenceId) || !isRelativePlacementPinValid(
681
- pinnedId,
682
- pin,
683
- (activityId2) => seed2.parentIds.get(activityId2) ?? null
684
- ) || (seed2.visibleReferenceCounts.get(referenceId) ?? 0) === 0) {
685
- continue;
686
- }
687
- seed2.pinnedVisibleIds.add(pinnedId);
688
- let currentId = pinnedId;
689
- while (currentId !== null) {
690
- seed2.visibleReferenceCounts.set(
691
- currentId,
692
- (seed2.visibleReferenceCounts.get(currentId) ?? 0) + 1
693
- );
694
- currentId = seed2.parentIds.get(currentId) ?? null;
695
- }
696
- }
697
- }
698
566
  function propagateVisibleReferenceCounts(seed2) {
699
567
  const { visibleReferenceCounts, parentIds, remainingChildren } = seed2;
700
568
  const pendingIds = [];
@@ -726,13 +594,11 @@ function collectVisibleIds(visibleReferenceCounts) {
726
594
  function buildFilterProjection(input) {
727
595
  const seed2 = seedFilterProjection(input);
728
596
  propagateVisibleReferenceCounts(seed2);
729
- applyRelativePlacementPins(seed2, input.relativePlacementPins);
730
597
  const visibleIds = collectVisibleIds(seed2.visibleReferenceCounts);
731
598
  return {
732
599
  filter: input.filter,
733
600
  context: input.context,
734
601
  matchedIds: seed2.matchedIds,
735
- pinnedVisibleIds: seed2.pinnedVisibleIds,
736
602
  visibleIds,
737
603
  visibleReferenceCounts: seed2.visibleReferenceCounts
738
604
  };
@@ -790,8 +656,6 @@ var OPERATORS_BY_KIND = {
790
656
  date: /* @__PURE__ */ new Set(["after", "before"]),
791
657
  "id-array": /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
792
658
  enum: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
793
- // Same membership operators as enum: splitting the kinds was about ordering,
794
- // not about filtering, and these two filter exactly like an enum.
795
659
  boolean: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
796
660
  reference: /* @__PURE__ */ new Set(["someOf", "notSomeOf"])
797
661
  };
@@ -914,8 +778,7 @@ function resolveFilter(adapter, filter, hoursPerDay) {
914
778
  activities,
915
779
  parentOf: (activityId) => adapter.getParentId(activityId),
916
780
  filter,
917
- context: buildFilterContext(hoursPerDay),
918
- relativePlacementPins: adapter.getRelativePlacementPins()
781
+ context: buildFilterContext(hoursPerDay)
919
782
  });
920
783
  return { visibleIds: projection.visibleIds, projection };
921
784
  }
@@ -966,118 +829,25 @@ function normalizeParentKey(parent) {
966
829
 
967
830
  // src/internal/hierarchy/visual-order.ts
968
831
  var NOT_SET_SORT_VALUE = Number.MAX_SAFE_INTEGER;
969
- var EMPTY_RELATIVE_PLACEMENT_PINS = /* @__PURE__ */ new Map();
970
- function buildRelativePlacementPinIndex(adapter) {
971
- const index = /* @__PURE__ */ new Map();
972
- for (const [activityId, pin] of adapter.getRelativePlacementPins?.() ?? []) {
973
- const pinnedId = String(activityId);
974
- const referenceId = String(pin.referenceId);
975
- if (adapter.getActivity(pinnedId) === null || adapter.getActivity(referenceId) === null || !isRelativePlacementPinValid(
976
- pinnedId,
977
- pin,
978
- (activityId2) => adapter.getParentId(activityId2)
979
- )) {
980
- continue;
981
- }
982
- const targetParentId = String(pin.branchParentId);
983
- const branchPins = index.get(targetParentId) ?? /* @__PURE__ */ new Map();
984
- branchPins.set(pinnedId, pin);
985
- index.set(targetParentId, branchPins);
986
- }
987
- return index;
988
- }
989
- function getChildrenInVisualOrder(parentId, adapter, pinIndex = buildRelativePlacementPinIndex(adapter)) {
832
+ function getChildrenInVisualOrder(parentId, adapter) {
990
833
  const children = collectChildrenSnapshots(parentId, adapter);
991
834
  const userOrder = adapter.getOrderComparator?.() ?? null;
992
835
  children.sort(
993
836
  userOrder === null ? compareActivitiesInVisualOrder : (a, b) => userOrder(a, b) || compareActivitiesInVisualOrder(a, b)
994
837
  );
995
- return applyRelativePlacementPins2(
996
- children.map((activity) => String(activity.id)),
997
- parentId,
998
- pinIndex.get(String(parentId)) ?? EMPTY_RELATIVE_PLACEMENT_PINS
999
- );
1000
- }
1001
- function applyRelativePlacementPins2(orderedIds, parentId, pins) {
1002
- const order = buildLinkedActivityOrder(orderedIds);
1003
- for (const [activityId, pin] of pins) {
1004
- const pinnedId = String(activityId);
1005
- const referenceId = String(pin.referenceId);
1006
- const isFirstChild = referenceId === String(parentId);
1007
- if (!order.previous.has(pinnedId) || !isFirstChild && (!order.previous.has(referenceId) || pinnedId === referenceId)) {
1008
- continue;
1009
- }
1010
- detachActivity(order, pinnedId);
1011
- if (isFirstChild) insertActivityFirst(order, pinnedId);
1012
- else insertActivityBeside(order, pinnedId, referenceId, pin.side);
1013
- }
1014
- return materializeActivityOrder(order);
1015
- }
1016
- function buildLinkedActivityOrder(orderedIds) {
1017
- const previous = /* @__PURE__ */ new Map();
1018
- const next = /* @__PURE__ */ new Map();
1019
- for (let index = 0; index < orderedIds.length; index++) {
1020
- const activityId = orderedIds[index];
1021
- if (activityId === void 0) continue;
1022
- previous.set(activityId, orderedIds[index - 1] ?? null);
1023
- next.set(activityId, orderedIds[index + 1] ?? null);
1024
- }
1025
- return { previous, next, head: orderedIds[0] ?? null };
1026
- }
1027
- function detachActivity(order, activityId) {
1028
- const before = order.previous.get(activityId) ?? null;
1029
- const after = order.next.get(activityId) ?? null;
1030
- if (before === null) order.head = after;
1031
- else order.next.set(before, after);
1032
- if (after !== null) order.previous.set(after, before);
1033
- }
1034
- function insertActivityFirst(order, activityId) {
1035
- order.previous.set(activityId, null);
1036
- order.next.set(activityId, order.head);
1037
- if (order.head !== null) order.previous.set(order.head, activityId);
1038
- order.head = activityId;
1039
- }
1040
- function insertActivityBeside(order, activityId, referenceId, side) {
1041
- if (side === "before") {
1042
- const before = order.previous.get(referenceId) ?? null;
1043
- order.previous.set(activityId, before);
1044
- order.next.set(activityId, referenceId);
1045
- order.previous.set(referenceId, activityId);
1046
- if (before === null) order.head = activityId;
1047
- else order.next.set(before, activityId);
1048
- return;
1049
- }
1050
- const after = order.next.get(referenceId) ?? null;
1051
- order.previous.set(activityId, referenceId);
1052
- order.next.set(activityId, after);
1053
- order.next.set(referenceId, activityId);
1054
- if (after !== null) order.previous.set(after, activityId);
1055
- }
1056
- function materializeActivityOrder(order) {
1057
- const result = [];
1058
- let activityId = order.head;
1059
- while (activityId !== null) {
1060
- result.push(activityId);
1061
- activityId = order.next.get(activityId) ?? null;
1062
- }
1063
- return result;
838
+ return children.map((activity) => String(activity.id));
1064
839
  }
1065
840
  function iterateInVisualOrder(adapter) {
1066
841
  const result = [];
1067
- const pinIndex = buildRelativePlacementPinIndex(adapter);
1068
842
  const visit = (activity) => {
1069
843
  result.push(activity);
1070
- const childIds = getChildrenInVisualOrder(
1071
- String(activity.id),
1072
- adapter,
1073
- pinIndex
1074
- );
844
+ const childIds = getChildrenInVisualOrder(String(activity.id), adapter);
1075
845
  for (const childId of childIds) {
1076
846
  const child = adapter.getActivity(childId);
1077
847
  if (child) visit(child);
1078
848
  }
1079
849
  };
1080
- const rootIds = getChildrenInVisualOrder(ROOT_PARENT_ID, adapter, pinIndex);
850
+ const rootIds = getChildrenInVisualOrder(ROOT_PARENT_ID, adapter);
1081
851
  for (const rootId of rootIds) {
1082
852
  const root = adapter.getActivity(rootId);
1083
853
  if (root) visit(root);
@@ -1138,9 +908,8 @@ function setHas(set, id) {
1138
908
  // src/dispatch/shared/collect-branch-order.ts
1139
909
  function collectBranchOrder(adapter) {
1140
910
  const branches = [];
1141
- const pinIndex = buildRelativePlacementPinIndex(adapter);
1142
911
  const visit = (parentId) => {
1143
- const childIds = getChildrenInVisualOrder(parentId, adapter, pinIndex);
912
+ const childIds = getChildrenInVisualOrder(parentId, adapter);
1144
913
  if (childIds.length > 1) {
1145
914
  branches.push({ parentId, childIds });
1146
915
  }
@@ -1153,9 +922,8 @@ function collectBranchOrder(adapter) {
1153
922
  }
1154
923
  function collectBranchOrderForParents(adapter, parentIds) {
1155
924
  const branches = [];
1156
- const pinIndex = buildRelativePlacementPinIndex(adapter);
1157
925
  for (const parentId of parentIds) {
1158
- const childIds = getChildrenInVisualOrder(parentId, adapter, pinIndex);
926
+ const childIds = getChildrenInVisualOrder(parentId, adapter);
1159
927
  if (childIds.length > 1) branches.push({ parentId, childIds });
1160
928
  }
1161
929
  return branches;
@@ -1188,107 +956,61 @@ function dispatchSortSet(action, deps) {
1188
956
  return { ok: true, changes };
1189
957
  }
1190
958
 
1191
- // src/columns/text/constants.ts
1192
- var TEXT = "text";
1193
-
1194
- // src/columns/description/constants.ts
1195
- var DESCRIPTION = "description";
1196
-
1197
- // src/columns/duration/constants.ts
1198
- var DURATION = "duration";
1199
-
1200
- // src/columns/progress/constants.ts
1201
- var PROGRESS = "progress";
1202
-
1203
- // src/columns/cost/constants.ts
1204
- var COST = "cost";
1205
-
1206
- // src/columns/used-cost/constants.ts
1207
- var USED_COST = "used_cost";
1208
-
1209
- // src/columns/hh-work-time/constants.ts
1210
- var HH_WORK_TIME = "hhWorkTime";
1211
-
1212
- // src/columns/start-date/constants.ts
1213
- var START_DATE = "start_date";
1214
-
1215
- // src/columns/end-date/constants.ts
1216
- var END_DATE = "end_date";
1217
-
1218
- // src/columns/constraint-type/constants.ts
1219
- var CONSTRAINT_TYPE = "constraint_type";
1220
-
1221
- // src/columns/constraint-date/constants.ts
1222
- var CONSTRAINT_DATE = "constraint_date";
1223
-
1224
- // src/columns/calendar-id/constants.ts
1225
- var CALENDAR_ID = "calendar_id";
1226
-
1227
- // src/columns/custom-id/constants.ts
1228
- var CUSTOM_ID = "custom_id";
1229
-
1230
- // src/columns/subcontract-id/constants.ts
1231
- var SUBCONTRACT_ID = "subcontractId";
1232
-
1233
- // src/columns/responsables/constants.ts
1234
- var RESPONSABLES = "responsables";
1235
-
1236
- // src/columns/tags/constants.ts
1237
- var TAGS = "tags";
1238
-
1239
- // src/columns/predecessors/constants.ts
1240
- var CUSTOM_PREDECESSORS = "custom_predecessors";
1241
-
1242
- // src/columns/successors/constants.ts
1243
- var CUSTOM_SUCESSORS = "custom_sucessors";
1244
-
1245
- // src/columns/real-work/constants.ts
1246
- var REAL_WORK = "real_work";
1247
-
1248
- // src/columns/real-cost/constants.ts
1249
- var REAL_COST = "real_cost";
1250
-
1251
- // src/columns/expected-progress/constants.ts
1252
- var EXPECTED_PROGRESS = "expected_progress";
1253
-
1254
- // src/columns/expected-progress-base/constants.ts
1255
- var EXPECTED_PROGRESS_BASE = "expected_progress_base";
1256
-
1257
- // src/columns/start-base/constants.ts
1258
- var START_BASE = "start_base";
1259
-
1260
- // src/columns/end-base/constants.ts
1261
- var END_BASE = "end_base";
1262
-
1263
- // src/columns/duration-base/constants.ts
1264
- var DURATION_BASE = "duration_base";
1265
-
1266
- // src/columns/cost-base/constants.ts
1267
- var COST_BASE = "cost_base";
1268
-
1269
- // src/columns/work-base/constants.ts
1270
- var WORK_BASE = "work_base";
1271
-
1272
- // src/columns/calendar-duration/constants.ts
1273
- var CALENDAR_DURATION = "calendarDuration";
1274
-
1275
- // src/columns/critical-path/constants.ts
1276
- var IS_CRITICAL = "is_critical";
1277
- var EARLY_START = "earlyStart";
1278
- var EARLY_FINISH = "earlyFinish";
1279
- var LATE_START = "lateStart";
1280
- var LATE_FINISH = "lateFinish";
1281
- var FREE_SLACK = "freeSlack";
1282
- var TOTAL_SLACK = "totalSlack";
1283
-
1284
- // src/columns/correlative-id/constants.ts
1285
- var CORRELATIVE_ID = "correlative_id";
959
+ // src/constants/columns.ts
960
+ var EDITABLE = {
961
+ TEXT: "text",
962
+ DESCRIPTION: "description",
963
+ DURATION: "duration",
964
+ PROGRESS: "progress",
965
+ COST: "cost",
966
+ USED_COST: "used_cost",
967
+ HH_WORK_TIME: "hhWorkTime",
968
+ START_DATE: "start_date",
969
+ END_DATE: "end_date",
970
+ CONSTRAINT_TYPE: "constraint_type",
971
+ CONSTRAINT_DATE: "constraint_date",
972
+ CALENDAR_ID: "calendar_id",
973
+ CUSTOM_ID: "custom_id",
974
+ SUBCONTRACT_ID: "subcontractId",
975
+ RESPONSABLES: "responsables",
976
+ TAGS: "tags",
977
+ CUSTOM_PREDECESSORS: "custom_predecessors",
978
+ CUSTOM_SUCESSORS: "custom_sucessors"
979
+ };
980
+ var READ_ONLY = {
981
+ REAL_WORK: "real_work",
982
+ REAL_COST: "real_cost",
983
+ EXPECTED_PROGRESS: "expected_progress",
984
+ EXPECTED_PROGRESS_BASE: "expected_progress_base",
985
+ START_BASE: "start_base",
986
+ END_BASE: "end_base",
987
+ DURATION_BASE: "duration_base",
988
+ COST_BASE: "cost_base",
989
+ WORK_BASE: "work_base",
990
+ CALENDAR_DURATION: "calendarDuration",
991
+ IS_CRITICAL: "is_critical",
992
+ EARLY_START: "earlyStart",
993
+ EARLY_FINISH: "earlyFinish",
994
+ LATE_START: "lateStart",
995
+ LATE_FINISH: "lateFinish",
996
+ FREE_SLACK: "freeSlack",
997
+ TOTAL_SLACK: "totalSlack",
998
+ CORRELATIVE_ID: "correlative_id",
999
+ UNIQUE_CORRELATIVE_ID: "unique_correlative_id",
1000
+ PONDERATOR: "ponderator",
1001
+ STATUS: "status"
1002
+ };
1003
+ var COLUMN = { ...EDITABLE, ...READ_ONLY };
1286
1004
 
1287
- // src/columns/unique-correlative-id/constants.ts
1288
- var UNIQUE_CORRELATIVE_ID = "unique_correlative_id";
1005
+ // src/shared/assert-never.ts
1006
+ function assertNever(value, message) {
1007
+ throw new Error(message);
1008
+ }
1289
1009
 
1290
- // src/columns/ponderator/constants.ts
1291
- var PONDERATOR = "ponderator";
1010
+ // src/autoscheduler/utils/cancellation.ts
1011
+ function createIsCurrent(id, getCurrentId) {
1012
+ return () => getCurrentId() === id;
1013
+ }
1292
1014
 
1293
1015
  // src/types.ts
1294
1016
  var WORK_TIME_DIRECTION = {
@@ -1307,71 +1029,8 @@ var STATUS = {
1307
1029
  DOING: "Doing"
1308
1030
  };
1309
1031
 
1310
- // src/columns/status/constants.ts
1311
- var STATUS_COLUMN = "status";
1312
- var DEFAULT_STATUS_CRITERIA = "Baseline";
1313
- function resolveStatusCriteria(value) {
1314
- return value === "Actual" ? "Actual" : DEFAULT_STATUS_CRITERIA;
1315
- }
1316
-
1317
- // src/constants/columns.ts
1318
- var EDITABLE = {
1319
- TEXT,
1320
- DESCRIPTION,
1321
- DURATION,
1322
- PROGRESS,
1323
- COST,
1324
- USED_COST,
1325
- HH_WORK_TIME,
1326
- START_DATE,
1327
- END_DATE,
1328
- CONSTRAINT_TYPE,
1329
- CONSTRAINT_DATE,
1330
- CALENDAR_ID,
1331
- CUSTOM_ID,
1332
- SUBCONTRACT_ID,
1333
- RESPONSABLES,
1334
- TAGS,
1335
- CUSTOM_PREDECESSORS,
1336
- CUSTOM_SUCESSORS
1337
- };
1338
- var READ_ONLY = {
1339
- REAL_WORK,
1340
- REAL_COST,
1341
- EXPECTED_PROGRESS,
1342
- EXPECTED_PROGRESS_BASE,
1343
- START_BASE,
1344
- END_BASE,
1345
- DURATION_BASE,
1346
- COST_BASE,
1347
- WORK_BASE,
1348
- CALENDAR_DURATION,
1349
- IS_CRITICAL,
1350
- EARLY_START,
1351
- EARLY_FINISH,
1352
- LATE_START,
1353
- LATE_FINISH,
1354
- FREE_SLACK,
1355
- TOTAL_SLACK,
1356
- CORRELATIVE_ID,
1357
- UNIQUE_CORRELATIVE_ID,
1358
- PONDERATOR,
1359
- STATUS: STATUS_COLUMN
1360
- };
1361
- var COLUMN = { ...EDITABLE, ...READ_ONLY };
1362
-
1363
- // src/shared/assert-never.ts
1364
- function assertNever(value, message) {
1365
- throw new Error(message);
1366
- }
1367
-
1368
- // src/autoscheduler/utils/cancellation.ts
1369
- function createIsCurrent(id, getCurrentId) {
1370
- return () => getCurrentId() === id;
1371
- }
1372
-
1373
1032
  // src/constraints/index.ts
1374
- var CONSTRAINT_TYPE2 = {
1033
+ var CONSTRAINT_TYPE = {
1375
1034
  ASAP: "asap",
1376
1035
  ALAP: "alap",
1377
1036
  SNET: "snet",
@@ -2288,7 +1947,7 @@ function processConstraints(activityIds, adapter, plans) {
2288
1947
  const activity = adapter.getActivity(id);
2289
1948
  if (!activity) continue;
2290
1949
  const type = activity.constraintType;
2291
- if (!type || type === CONSTRAINT_TYPE2.ASAP || type === CONSTRAINT_TYPE2.ALAP) {
1950
+ if (!type || type === CONSTRAINT_TYPE.ASAP || type === CONSTRAINT_TYPE.ALAP) {
2292
1951
  continue;
2293
1952
  }
2294
1953
  const bounds = computeConstraintBounds(activity, adapter);
@@ -2337,14 +1996,14 @@ function validateMilestoneConstraint(activity, successorStart) {
2337
1996
  const { constraintType, constraintDate } = activity;
2338
1997
  if (!constraintType || !constraintDate) return successorStart;
2339
1998
  switch (constraintType) {
2340
- case CONSTRAINT_TYPE2.MSO:
2341
- case CONSTRAINT_TYPE2.MFO:
1999
+ case CONSTRAINT_TYPE.MSO:
2000
+ case CONSTRAINT_TYPE.MFO:
2342
2001
  return new Date(constraintDate);
2343
- case CONSTRAINT_TYPE2.SNET:
2344
- case CONSTRAINT_TYPE2.FNET:
2002
+ case CONSTRAINT_TYPE.SNET:
2003
+ case CONSTRAINT_TYPE.FNET:
2345
2004
  return constraintDate > successorStart ? new Date(constraintDate) : successorStart;
2346
- case CONSTRAINT_TYPE2.SNLT:
2347
- case CONSTRAINT_TYPE2.FNLT:
2005
+ case CONSTRAINT_TYPE.SNLT:
2006
+ case CONSTRAINT_TYPE.FNLT:
2348
2007
  return constraintDate < successorStart ? new Date(constraintDate) : successorStart;
2349
2008
  default:
2350
2009
  return successorStart;
@@ -2473,7 +2132,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2473
2132
  });
2474
2133
  plan.earliestSchedulingStart = linkStart;
2475
2134
  plan.earliestSchedulingEnd = plan.endDate;
2476
- } else if (activity.constraintType === CONSTRAINT_TYPE2.MSO) {
2135
+ } else if (activity.constraintType === CONSTRAINT_TYPE.MSO) {
2477
2136
  if (plan.earliestStart) {
2478
2137
  plan.startDate = plan.earliestStart;
2479
2138
  plan.endDate = plan.earliestEnd ?? adapter.calculateEndDate({
@@ -2482,7 +2141,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2482
2141
  task: activity
2483
2142
  });
2484
2143
  }
2485
- } else if (activity.constraintType === CONSTRAINT_TYPE2.MFO) {
2144
+ } else if (activity.constraintType === CONSTRAINT_TYPE.MFO) {
2486
2145
  if (plan.latestStart) {
2487
2146
  plan.startDate = plan.latestStart;
2488
2147
  plan.endDate = plan.latestEnd ?? adapter.calculateEndDate({
@@ -2508,7 +2167,7 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2508
2167
  const activityCount = allActivities.length;
2509
2168
  const alapActivityIds = [];
2510
2169
  for (const activity of allActivities) {
2511
- if (activity.constraintType === CONSTRAINT_TYPE2.ALAP) {
2170
+ if (activity.constraintType === CONSTRAINT_TYPE.ALAP) {
2512
2171
  alapActivityIds.push(activity.id);
2513
2172
  }
2514
2173
  }
@@ -2555,7 +2214,7 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2555
2214
  sliceStart = yieldResult.newSliceStart;
2556
2215
  const activity = adapter.getActivity(activityId);
2557
2216
  if (!activity) continue;
2558
- if (activity.constraintType !== CONSTRAINT_TYPE2.ALAP) continue;
2217
+ if (activity.constraintType !== CONSTRAINT_TYPE.ALAP) continue;
2559
2218
  if (!activity.autoScheduling) continue;
2560
2219
  if (activity.progress === COMPLETED_PROGRESS) continue;
2561
2220
  if (isSummary(activity.type, adapter.getChildren(activityId).length > 0))
@@ -3064,9 +2723,7 @@ function applyLinkCreates(links, deps) {
3064
2723
  break;
3065
2724
  }
3066
2725
  duplicateKeys.set(key, linkId);
3067
- if (existingGraphHasCycle && // ponytail: preserve legacy sequential semantics; optimize with dynamic
3068
- // SCC reachability only if corrupt cyclic schedules become measurable.
3069
- wouldIntroduceCycle(edges, {
2726
+ if (existingGraphHasCycle && wouldIntroduceCycle(edges, {
3070
2727
  source: operation.source,
3071
2728
  target: operation.target
3072
2729
  })) {
@@ -3544,7 +3201,7 @@ function widenScopeToAlapActivities(group, allLinks, adapter) {
3544
3201
  const widenedAlapKeys = /* @__PURE__ */ new Set();
3545
3202
  for (const activity of adapter.getAllActivities()) {
3546
3203
  const activityKey = String(activity.id);
3547
- const isOutOfComponentAlap = activity.constraintType === CONSTRAINT_TYPE2.ALAP && !idSet.has(activityKey);
3204
+ const isOutOfComponentAlap = activity.constraintType === CONSTRAINT_TYPE.ALAP && !idSet.has(activityKey);
3548
3205
  if (!isOutOfComponentAlap) continue;
3549
3206
  widenedAlapKeys.add(activityKey);
3550
3207
  idSet.add(activityKey);
@@ -3906,7 +3563,7 @@ var descriptionPipeline = {
3906
3563
 
3907
3564
  // src/columns/shared/activity-predicates.ts
3908
3565
  function effectiveConstraintType(activity) {
3909
- return activity.constraintType ?? CONSTRAINT_TYPE2.ASAP;
3566
+ return activity.constraintType ?? CONSTRAINT_TYPE.ASAP;
3910
3567
  }
3911
3568
  var PROGRESS_COMPLETE = COMPLETED_PROGRESS;
3912
3569
  function isCompletedActivity(activity) {
@@ -4644,7 +4301,7 @@ function checkIsWorkingDay(newDate, activity, ctx) {
4644
4301
  return null;
4645
4302
  }
4646
4303
  function detectEndDateConstraintWarning(activity, newEndDate) {
4647
- const cannotViolateStartPin = effectiveConstraintType(activity) === CONSTRAINT_TYPE2.MSO;
4304
+ const cannotViolateStartPin = effectiveConstraintType(activity) === CONSTRAINT_TYPE.MSO;
4648
4305
  if (cannotViolateStartPin) return void 0;
4649
4306
  const projectedDate = pickProjectedDateForConstraint(
4650
4307
  effectiveConstraintType(activity),
@@ -4694,7 +4351,7 @@ function calculateNewDuration(activity, newEndDate, ctx) {
4694
4351
 
4695
4352
  // src/columns/constraint-type/constraint-type-pipeline.ts
4696
4353
  var VALID_CONSTRAINT_TYPES = new Set(
4697
- Object.values(CONSTRAINT_TYPE2)
4354
+ Object.values(CONSTRAINT_TYPE)
4698
4355
  );
4699
4356
  var constraintTypePipeline = {
4700
4357
  targetField: "constraintType",
@@ -5475,6 +5132,12 @@ function runExpectedProgressBase(state, now, defaultBaseCalendarId = null) {
5475
5132
  return computeExpectedProgress(rootIds, now, adapter, defaultBaseCalendarId);
5476
5133
  }
5477
5134
 
5135
+ // src/columns/status/constants.ts
5136
+ var DEFAULT_STATUS_CRITERIA = "Baseline";
5137
+ function resolveStatusCriteria(value) {
5138
+ return value === "Actual" ? "Actual" : DEFAULT_STATUS_CRITERIA;
5139
+ }
5140
+
5478
5141
  // src/columns/status/compute.ts
5479
5142
  var roundToTwoDecimals = (value) => Math.round(value * 100) / 100;
5480
5143
  function resolveExpectedForStatus(activity, criteria) {
@@ -5502,7 +5165,7 @@ function applyStatusPass(state, criteria) {
5502
5165
  resolveExpectedForStatus(activity, criteria)
5503
5166
  );
5504
5167
  if (activity.status !== status) {
5505
- setActivityFieldDynamic(state, id, STATUS_COLUMN, status);
5168
+ setActivityFieldDynamic(state, id, COLUMN.STATUS, status);
5506
5169
  changed.push(id);
5507
5170
  }
5508
5171
  });
@@ -9275,10 +8938,10 @@ var FreeFloat = class {
9275
8938
  this.durationCache = /* @__PURE__ */ new Map();
9276
8939
  }
9277
8940
  getFreeFloat() {
9278
- const PROGRESS2 = Number(this.activity.progress);
8941
+ const PROGRESS = Number(this.activity.progress);
9279
8942
  const CONSTRAINT = this.getConstraintType();
9280
8943
  this.calculateFreeFloatOfLink(CONSTRAINT);
9281
- const activityFreeFloat = PROGRESS2 === 100 ? 0 : this.getFreeFloatBaseConstraint(CONSTRAINT);
8944
+ const activityFreeFloat = PROGRESS === 100 ? 0 : this.getFreeFloatBaseConstraint(CONSTRAINT);
9282
8945
  return {
9283
8946
  activityFreeFloat,
9284
8947
  linksFreeFloat: this.linksFreeFloatObject
@@ -9437,11 +9100,11 @@ var FreeFloat = class {
9437
9100
  };
9438
9101
  }
9439
9102
  calculateMsoMfo(constraint) {
9440
- const CONSTRAINT_DATE2 = this.activity.constraint_date || /* @__PURE__ */ new Date();
9103
+ const CONSTRAINT_DATE = this.activity.constraint_date || /* @__PURE__ */ new Date();
9441
9104
  const calculation = this.forwardMap.get(this.activity.id);
9442
9105
  const DATE_TO_CALCULATE = constraint === CONSTRAINT_TYPES.MSO ? calculation?.es : calculation?.ef;
9443
9106
  const freeSlack = this.calculationWithCalendar(
9444
- CONSTRAINT_DATE2,
9107
+ CONSTRAINT_DATE,
9445
9108
  DATE_TO_CALCULATE
9446
9109
  );
9447
9110
  return Math.max(0, this.parseHoursToDays(freeSlack));
@@ -11504,7 +11167,7 @@ function buildParentMutations(input) {
11504
11167
  if (wasPromotableLeaf) {
11505
11168
  fields.type = PROMOTION_TARGET_TYPE;
11506
11169
  if ((input.promotionSource ?? "create") === "create") {
11507
- fields.constraintType = CONSTRAINT_TYPE2.ASAP;
11170
+ fields.constraintType = CONSTRAINT_TYPE.ASAP;
11508
11171
  fields.constraintDate = null;
11509
11172
  fields.progress = 0;
11510
11173
  }
@@ -12645,8 +12308,6 @@ function dispatchSirSync(action, deps) {
12645
12308
  id,
12646
12309
  kind: "updated",
12647
12310
  fields: { pendingRequestIds: { before, after } },
12648
- // ISSUE-025: `after` must be the COMPLETE post-change entity; a partial
12649
- // object crashes any consumer that projects the full snapshot.
12650
12311
  after: structuredCloneActivity(updated)
12651
12312
  };
12652
12313
  return {
@@ -17876,6 +17537,77 @@ var HierarchyIndex = class {
17876
17537
  }
17877
17538
  };
17878
17539
 
17540
+ // src/internal/state/view-state.ts
17541
+ var ViewStateStore = class {
17542
+ checkedSet = /* @__PURE__ */ new Set();
17543
+ hiddenSet = /* @__PURE__ */ new Set();
17544
+ activeFilter = null;
17545
+ activeOrder = null;
17546
+ isChecked(activityId) {
17547
+ return this.checkedSet.has(activityId);
17548
+ }
17549
+ isVisible(activityId) {
17550
+ return !this.hiddenSet.has(activityId);
17551
+ }
17552
+ hiddenIds() {
17553
+ return [...this.hiddenSet];
17554
+ }
17555
+ getActiveFilter() {
17556
+ return this.activeFilter;
17557
+ }
17558
+ setActiveFilter(nextFilter) {
17559
+ this.activeFilter = nextFilter;
17560
+ }
17561
+ getActiveOrder() {
17562
+ return this.activeOrder;
17563
+ }
17564
+ setActiveOrder(nextOrder) {
17565
+ this.activeOrder = nextOrder;
17566
+ }
17567
+ checkedIds() {
17568
+ return [...this.checkedSet];
17569
+ }
17570
+ checkedCount() {
17571
+ return this.checkedSet.size;
17572
+ }
17573
+ setChecked(activityId, nextChecked) {
17574
+ if (nextChecked === this.checkedSet.has(activityId)) return false;
17575
+ if (nextChecked) this.checkedSet.add(activityId);
17576
+ else this.checkedSet.delete(activityId);
17577
+ return true;
17578
+ }
17579
+ setVisible(activityId, nextVisible) {
17580
+ if (nextVisible === !this.hiddenSet.has(activityId)) return false;
17581
+ if (nextVisible) this.hiddenSet.delete(activityId);
17582
+ else this.hiddenSet.add(activityId);
17583
+ return true;
17584
+ }
17585
+ forget(activityId) {
17586
+ this.checkedSet.delete(activityId);
17587
+ this.hiddenSet.delete(activityId);
17588
+ }
17589
+ hydrate(seed2) {
17590
+ this.checkedSet = new Set(seed2.checkedIds ?? []);
17591
+ this.hiddenSet = new Set(seed2.hiddenIds ?? []);
17592
+ this.activeFilter = null;
17593
+ this.activeOrder = null;
17594
+ }
17595
+ snapshot() {
17596
+ return {
17597
+ checked: new Set(this.checkedSet),
17598
+ hidden: new Set(this.hiddenSet),
17599
+ activeFilter: this.activeFilter,
17600
+ activeOrder: this.activeOrder
17601
+ };
17602
+ }
17603
+ restore(snapshot) {
17604
+ this.checkedSet = new Set(snapshot.checked);
17605
+ this.hiddenSet = new Set(snapshot.hidden);
17606
+ this.activeFilter = snapshot.activeFilter;
17607
+ this.activeOrder = snapshot.activeOrder;
17608
+ }
17609
+ };
17610
+
17879
17611
  // src/internal/state/schedule-state.ts
17880
17612
  var ScheduleState = class _ScheduleState {
17881
17613
  _activities = /* @__PURE__ */ new Map();
@@ -18054,28 +17786,6 @@ var ScheduleState = class _ScheduleState {
18054
17786
  this._viewState.setActiveOrder(nextOrder);
18055
17787
  this.invalidateDerivedOrder();
18056
17788
  }
18057
- setRelativePlacementPin(activityId, pin) {
18058
- this._viewState.setRelativePlacementPin(String(activityId), pin);
18059
- this.invalidateVisualOrderIds();
18060
- }
18061
- getRelativePlacementPins() {
18062
- return this._viewState.getRelativePlacementPins();
18063
- }
18064
- restoreRelativePlacementPins(pins) {
18065
- this._viewState.restoreRelativePlacementPins(pins);
18066
- this._filterProjection = null;
18067
- this.invalidateVisualOrderIds();
18068
- }
18069
- /**
18070
- * Rebuild-on-demand, memoized: at most one build per invalidation, never one
18071
- * per comparison. getChildrenInVisualOrder asks for this once and then sorts a
18072
- * whole sibling group with it, and collectBranchOrder walks every branch, so a
18073
- * build per read would be thousands per dispatch.
18074
- *
18075
- * The factory reads hoursPerDay and the collation locale at build time, so a
18076
- * rebuilt comparator always reflects the current context — that is what keeps
18077
- * ordering and filtering from seeing two different hoursPerDay.
18078
- */
18079
17789
  getOrderComparator() {
18080
17790
  const activeOrder = this._viewState.getActiveOrder();
18081
17791
  if (activeOrder === null) {
@@ -18086,12 +17796,6 @@ var ScheduleState = class _ScheduleState {
18086
17796
  this._cache.orderComparator = this._buildOrderComparator(activeOrder);
18087
17797
  return this._cache.orderComparator;
18088
17798
  }
18089
- /**
18090
- * Both order caches, always together. The comparator decides the sequence, so
18091
- * a rebuilt comparator with a surviving sequence would paint the old order.
18092
- * invalidateVisualOrderIds stays separate on purpose: a structural change
18093
- * moves rows without touching the rules, so the comparator is still valid.
18094
- */
18095
17799
  invalidateDerivedOrder() {
18096
17800
  this._cache.orderComparator = null;
18097
17801
  this._cache.visualOrderIds = null;
@@ -18272,11 +17976,7 @@ var ScheduleState = class _ScheduleState {
18272
17976
  const activity = this.getActivity(activityId);
18273
17977
  if (activity) this._writeCapture.noteRemove(String(activityId), activity);
18274
17978
  const key = String(activityId);
18275
- const relativePlacementPins = this._viewState.getRelativePlacementPins();
18276
- const hasDependentPin = [...relativePlacementPins.values()].some(
18277
- ({ referenceId }) => referenceId === key
18278
- );
18279
- if (this._viewState.isChecked(key) || !this._viewState.isVisible(key) || relativePlacementPins.has(key) || hasDependentPin) {
17979
+ if (this._viewState.isChecked(key) || !this._viewState.isVisible(key)) {
18280
17980
  this._captureViewStateOnce();
18281
17981
  }
18282
17982
  this._viewState.forget(key);
@@ -18537,15 +18237,13 @@ function buildHistoryChangeSet(changes) {
18537
18237
  links: linksWithoutAfter
18538
18238
  });
18539
18239
  }
18540
- function buildUndoEntry(changeSet, beforeSnap, beforeLinks, afterSnap, afterLinks, relativePlacementPinsBefore, relativePlacementPinsAfter) {
18240
+ function buildUndoEntry(changeSet, beforeSnap, beforeLinks, afterSnap, afterLinks) {
18541
18241
  return {
18542
18242
  changeSet,
18543
18243
  beforeSnap,
18544
18244
  beforeLinks: resetDerivedLinkSnapshots(beforeLinks),
18545
18245
  afterSnap,
18546
- afterLinks: resetDerivedLinkSnapshots(afterLinks),
18547
- relativePlacementPinsBefore,
18548
- relativePlacementPinsAfter
18246
+ afterLinks: resetDerivedLinkSnapshots(afterLinks)
18549
18247
  };
18550
18248
  }
18551
18249
  function resetDerivedLinkSnapshots(snapshots) {
@@ -18848,8 +18546,6 @@ function applyChangeSetSide(state, entry, side) {
18848
18546
  );
18849
18547
  }
18850
18548
  }
18851
- const pins = side === "before" ? entry.relativePlacementPinsBefore : entry.relativePlacementPinsAfter;
18852
- if (pins !== void 0) state.restoreRelativePlacementPins(pins);
18853
18549
  }
18854
18550
 
18855
18551
  // src/dispatch/undo/undo-recorder.ts
@@ -21194,41 +20890,12 @@ function collectChangedActivities(changes, adapter) {
21194
20890
  }
21195
20891
  return activities;
21196
20892
  }
21197
- function changesAffectRelativePinProjection(changes, changedActivities, adapter, pins) {
21198
- if (pins.size === 0) return false;
21199
- if (changes.activities.some(
21200
- (change) => change.kind === "created" && pins.has(String(change.id))
21201
- )) {
21202
- return true;
21203
- }
21204
- const referenceIds = new Set(
21205
- [...pins.values()].map(({ referenceId }) => String(referenceId))
21206
- );
21207
- for (const activity of changedActivities) {
21208
- let activityId = String(activity.id);
21209
- while (activityId !== null) {
21210
- if (referenceIds.has(activityId)) return true;
21211
- activityId = adapter.getParentId(activityId);
21212
- }
21213
- }
21214
- return false;
21215
- }
21216
20893
  function isCurrentFilterProjection(projection, filter, context) {
21217
20894
  if (projection === null || projection.filter !== filter) return false;
21218
20895
  const hasCurrentHours = projection.context.hoursPerDay === context.hoursPerDay;
21219
20896
  const hasCurrentLocale = projection.context.locale === context.locale;
21220
20897
  return hasCurrentHours && hasCurrentLocale;
21221
20898
  }
21222
- function relativePlacementPinsEqual(left, right) {
21223
- if (left.size !== right.size) return false;
21224
- for (const [activityId, pin] of left) {
21225
- const other = right.get(activityId);
21226
- if (other === void 0 || other.referenceId !== pin.referenceId || other.branchParentId !== pin.branchParentId || other.side !== pin.side) {
21227
- return false;
21228
- }
21229
- }
21230
- return true;
21231
- }
21232
20899
  var ScheduleCore = class _ScheduleCore {
21233
20900
  _activityClipboard = { value: null };
21234
20901
  _status = SCHEDULE_CORE_STATUS.READY;
@@ -21237,29 +20904,6 @@ var ScheduleCore = class _ScheduleCore {
21237
20904
  _undo = new UndoRecorder();
21238
20905
  _opQueue = Promise.resolve();
21239
20906
  _scheduleRevision = 0;
21240
- /**
21241
- * Revision counting mutations that have been ADMITTED, whether or not they
21242
- * have changed anything yet. `_scheduleRevision` counts the ones that
21243
- * actually did.
21244
- *
21245
- * INVARIANT: `_pendingScheduleRevision >= _scheduleRevision`, and equality
21246
- * means no mutation is in flight.
21247
- *
21248
- * The two exist separately because the useful instant and the knowable
21249
- * instant are not the same one. A critical-path calculation becomes garbage
21250
- * the moment the next mutation is admitted, but whether that mutation is
21251
- * substantive is only knowable once its ChangeSet exists, which is hundreds
21252
- * of milliseconds later at project scale. Measured live on a 12268-activity
21253
- * project: the cancellation flag flipped 929 ms into a 930 ms calculation,
21254
- * 812 into 812 and 785 into 785, because the job's apply block queues behind
21255
- * the very dispatch whose completion cancels it. Cancellation and job end
21256
- * were the same event, so every discarded job ran the whole calculation.
21257
- *
21258
- * Splitting the counter buys the early signal without moving the meaning of
21259
- * `_scheduleRevision`, whose three readers (`isCriticalPathSettled`,
21260
- * `createDateGesturePreview` and the job's own `isCurrent`) are all written
21261
- * against "the state actually changed".
21262
- */
21263
20907
  _pendingScheduleRevision = 0;
21264
20908
  _criticalPathRevision = -1;
21265
20909
  _activeCriticalPath = null;
@@ -21372,13 +21016,6 @@ var ScheduleCore = class _ScheduleCore {
21372
21016
  this.assertReady();
21373
21017
  return readAllActivities(this.coreRuntime.state);
21374
21018
  }
21375
- /**
21376
- * Read del plan de indent (ISSUE-080): los padres destino DISTINTOS bajo los
21377
- * que quedarían las actividades si se indentaran ahora. Es exactamente la
21378
- * planificación que ejecuta el handler (`planIndentMoves`, autoridad única),
21379
- * expuesta para que la frontera pueda correr el protocolo de conversión a
21380
- * madre (chequeo backend + modal) ANTES de despachar. Solo lecturas.
21381
- */
21382
21019
  getIndentTargetParentIds(activityIds) {
21383
21020
  this.assertReady();
21384
21021
  const plan = planIndentMoves(
@@ -21531,7 +21168,6 @@ var ScheduleCore = class _ScheduleCore {
21531
21168
  this.assertReady();
21532
21169
  return this._saveTracker.hasUnsavedChanges();
21533
21170
  }
21534
- /** Read-only revision; moves once per substantive mutation. */
21535
21171
  getScheduleRevision() {
21536
21172
  return this._scheduleRevision;
21537
21173
  }
@@ -21577,24 +21213,10 @@ var ScheduleCore = class _ScheduleCore {
21577
21213
  );
21578
21214
  return workPromise;
21579
21215
  }
21580
- /**
21581
- * Marks a mutation as admitted and invalidates the calculation in flight.
21582
- *
21583
- * Called BEFORE `_enqueue`, which is the point of the whole thing: the wait
21584
- * in the operation queue is part of the window a running calculation wastes,
21585
- * and it is the longest part of it when several mutations are already
21586
- * queued.
21587
- *
21588
- * `dispatchChangesSchedulingState` is a pure function of the action, so this
21589
- * decision needs no state and cannot be wrong about the action's nature. What
21590
- * it cannot know yet is whether the mutation will produce anything, which is
21591
- * what `_settleScheduleMutation` reconciles afterwards.
21592
- */
21593
21216
  _beginScheduleMutation(action) {
21594
21217
  if (!dispatchChangesSchedulingState(action)) return false;
21595
21218
  return this._admitScheduleMutation();
21596
21219
  }
21597
- /** Undo and redo have no action to classify: reaching them IS the mutation. */
21598
21220
  _admitScheduleMutation() {
21599
21221
  this._pendingScheduleRevision++;
21600
21222
  if (this._activeCriticalPath) {
@@ -21602,30 +21224,6 @@ var ScheduleCore = class _ScheduleCore {
21602
21224
  }
21603
21225
  return true;
21604
21226
  }
21605
- /**
21606
- * Closes a mutation admitted by `_beginScheduleMutation`, on EVERY exit path.
21607
- *
21608
- * `changedState` false means the mutation was admitted and produced nothing
21609
- * (rejected, non-substantive, or rolled back). The pending revision walks
21610
- * back so the invariant holds and `isCriticalPathSettled` keeps telling the
21611
- * truth, and the calculation this mutation killed for nothing is re-armed.
21612
- *
21613
- * The re-arm goes through the queue and that is not incidental. Started
21614
- * outside it, the calculation would run immediately while the next queued
21615
- * mutation is still waiting, and that mutation would kill it again on
21616
- * admission: a cancel-and-restart treadmill burning a fresh project-wide deep
21617
- * copy per lap. Inside the queue the restart cannot happen until the queue
21618
- * drains, so at most one calculation is armed per settled mutation. The burst
21619
- * scenario will NOT catch a regression here, because there every dispatch
21620
- * succeeds and this path is never taken.
21621
- *
21622
- * It re-arms through `recomputeCriticalPath` rather than enqueueing the job
21623
- * directly, because the queue slot must NOT await the job: the job's own
21624
- * apply block needs a later slot on this same queue, so awaiting it from
21625
- * inside a slot deadlocks the core. `recomputeCriticalPath` already has the
21626
- * shape that returns the job's promise out of the slot instead of awaiting
21627
- * it, and it keeps `_criticalPathReady` pointing at the live calculation.
21628
- */
21629
21227
  _settleScheduleMutation(admitted, changedState) {
21630
21228
  if (!admitted) return;
21631
21229
  if (changedState) return;
@@ -21676,8 +21274,6 @@ var ScheduleCore = class _ScheduleCore {
21676
21274
  dateFormat: this.coreRuntime.sector.dateFormat
21677
21275
  });
21678
21276
  const historyPolicy = getDispatchHistoryPolicy(action);
21679
- const capturesRelativePlacementPins = action.kind === "activity-create" || action.kind === "activity-delete" || action.kind === "activity-batch" && action.mode === "replace";
21680
- const relativePlacementPinsBefore = capturesRelativePlacementPins ? new Map(this.coreRuntime.state.getRelativePlacementPins()) : void 0;
21681
21277
  const generatorSnapshot = [
21682
21278
  this.coreRuntime.activityIdGenerator.snapshot(),
21683
21279
  this.coreRuntime.linkIdGenerator.snapshot(),
@@ -21714,26 +21310,18 @@ var ScheduleCore = class _ScheduleCore {
21714
21310
  this.coreRuntime.state.endWriteCapture();
21715
21311
  this.coreRuntime.customIdTracker.commitCustomIdTransaction();
21716
21312
  }
21717
- if (result.ok) this._recordRelativePlacementPin(action, result.changes);
21718
21313
  if (result.ok && historyPolicy === "record" && changeSetIsSubstantive(result.changes)) {
21719
21314
  const created = captureCreatedSnapshots(
21720
21315
  this.coreRuntime.state,
21721
21316
  result.changes
21722
21317
  );
21723
- const relativePlacementPinsAfter = capturesRelativePlacementPins ? new Map(this.coreRuntime.state.getRelativePlacementPins()) : void 0;
21724
- const relativePlacementPinsChanged = relativePlacementPinsBefore !== void 0 && relativePlacementPinsAfter !== void 0 && !relativePlacementPinsEqual(
21725
- relativePlacementPinsBefore,
21726
- relativePlacementPinsAfter
21727
- );
21728
21318
  this._undo.record(
21729
21319
  buildUndoEntry(
21730
21320
  buildHistoryChangeSet(result.changes),
21731
21321
  result.__beforeSnap,
21732
21322
  result.__beforeLinks,
21733
21323
  created.afterSnap,
21734
- created.afterLinks,
21735
- relativePlacementPinsChanged ? relativePlacementPinsBefore : void 0,
21736
- relativePlacementPinsChanged ? relativePlacementPinsAfter : void 0
21324
+ created.afterLinks
21737
21325
  ),
21738
21326
  computeCoalesceKey(action),
21739
21327
  Date.now()
@@ -21781,11 +21369,7 @@ var ScheduleCore = class _ScheduleCore {
21781
21369
  return operation;
21782
21370
  }
21783
21371
  isCriticalPathSettled() {
21784
- return this._criticalPathRevision === this._scheduleRevision && // An admitted mutation has not landed yet, so whatever is applied now is
21785
- // about to be stale. Without this term `whenCriticalPathSettled` would
21786
- // spin: it would keep arming calculations that `isCurrent` kills on their
21787
- // first check, each one paying the project-wide deep copy first.
21788
- this._pendingScheduleRevision === this._scheduleRevision && this._activeCriticalPath === null;
21372
+ return this._criticalPathRevision === this._scheduleRevision && this._pendingScheduleRevision === this._scheduleRevision && this._activeCriticalPath === null;
21789
21373
  }
21790
21374
  async whenCriticalPathSettled() {
21791
21375
  while (!this.isCriticalPathSettled()) {
@@ -21801,34 +21385,6 @@ var ScheduleCore = class _ScheduleCore {
21801
21385
  const merged = this._reapplyViewState(result.changes);
21802
21386
  return merged === null ? result : { ...result, changes: merged };
21803
21387
  }
21804
- _recordRelativePlacementPin(action, changes) {
21805
- const state = this.coreRuntime.state;
21806
- if (action.kind !== "activity-create") return;
21807
- const referenceId = action.afterSiblingId ?? action.beforeSiblingId ?? (action.eventSource === "Creation button (+)" && action.parentId !== ROOT_PARENT_ID ? action.parentId : void 0);
21808
- if (referenceId === void 0) return;
21809
- const created = changes.activities.find(({ kind }) => kind === "created");
21810
- if (created === void 0) return;
21811
- state.setRelativePlacementPin(created.id, {
21812
- referenceId,
21813
- branchParentId: action.parentId,
21814
- side: action.beforeSiblingId === void 0 ? "after" : "before"
21815
- });
21816
- }
21817
- /**
21818
- * The single place the two view-state passes are chained. Dispatch, undo and
21819
- * redo all route through here: when this existed only inside the dispatch
21820
- * path, undo and redo reapplied the filter and forgot the order, so an edit
21821
- * that moved a row and was then undone left the row in its new position.
21822
- *
21823
- * The sequence between the passes is indifferent. Filter and order are
21824
- * orthogonal projections over the same tree — the filter decides which rows
21825
- * exist on screen and never reads the order; the order sequences every
21826
- * sibling group from the hierarchy index and never reads visibility. Either
21827
- * sequence produces the same ChangeSet.
21828
- *
21829
- * Both passes answer null while their state is inactive, so an unfiltered,
21830
- * unsorted schedule pays two property reads.
21831
- */
21832
21388
  _reapplyViewState(changes) {
21833
21389
  const withFilter = this._reapplyActiveFilter(changes);
21834
21390
  const sequenced = this._emitTouchedBranchOrder(withFilter ?? changes);
@@ -21838,24 +21394,6 @@ var ScheduleCore = class _ScheduleCore {
21838
21394
  );
21839
21395
  return withOrder ?? sequenced.changes ?? withFilter;
21840
21396
  }
21841
- /**
21842
- * Emits `order` for the branches this mutation resequenced, when no user order
21843
- * is active.
21844
- *
21845
- * The contract is that `order` reports a CHANGED SEQUENCE, not the presence of
21846
- * a sort. Tying emission to the cause instead of the effect is what produced
21847
- * the undo bug and, later, the reparent ones: without an active order a move,
21848
- * an indent, an outdent or the undo of any of them rearranged rows and said
21849
- * nothing, so an incremental consumer kept the old sequence. The undo of a
21850
- * reparent was the worst of them — it carried neither `order` nor a single
21851
- * correlativeId, so the position was not recoverable by any consumer.
21852
- *
21853
- * The touched branches are derived from the ChangeSet rather than accumulated
21854
- * in the state: an entity whose parentId or correlativeId moved, plus the
21855
- * parents of created and deleted rows, is exactly the set of branches whose
21856
- * sequence can differ. That keeps this linear in the blast radius, adds
21857
- * nothing to the write path, and cannot leak across dispatches.
21858
- */
21859
21397
  _emitTouchedBranchOrder(changes) {
21860
21398
  const adapter = this.coreRuntime.state;
21861
21399
  const touchedParents = collectResequencedParents(
@@ -21872,15 +21410,6 @@ var ScheduleCore = class _ScheduleCore {
21872
21410
  if (order.length === 0) return { changes: null, touchedParents };
21873
21411
  return { changes: { ...changes, order }, touchedParents };
21874
21412
  }
21875
- /**
21876
- * Re-sequences the grid after any mutation that could have changed a value the
21877
- * active order sorts by. Ordering is a view over the data, so an edit that
21878
- * moves a row past its sibling must move the row, exactly as the filter makes
21879
- * a no-longer-matching row disappear.
21880
- *
21881
- * Production only re-sorts after a bar drag; diverging from that is a
21882
- * deliberate product decision, not an oversight.
21883
- */
21884
21413
  _reapplyActiveOrder(changes, resequencedParents) {
21885
21414
  const adapter = this.coreRuntime.state;
21886
21415
  if (adapter.getActiveOrder() === null) return null;
@@ -21915,22 +21444,15 @@ var ScheduleCore = class _ScheduleCore {
21915
21444
  context
21916
21445
  );
21917
21446
  const changedActivities = changesRequireFilterProjectionRebuild(changes) ? null : collectChangedActivities(changes, adapter);
21918
- const relativePlacementPins = adapter.getRelativePlacementPins();
21919
21447
  let affectedIds;
21920
21448
  let visibleIds;
21921
- const needsProjectionRebuild = changedActivities === null || !projectionIsCurrent || changesAffectRelativePinProjection(
21922
- changes,
21923
- changedActivities,
21924
- adapter,
21925
- relativePlacementPins
21926
- );
21449
+ const needsProjectionRebuild = changedActivities === null || !projectionIsCurrent;
21927
21450
  if (needsProjectionRebuild) {
21928
21451
  const rebuiltProjection = buildFilterProjection({
21929
21452
  activities: adapter.getAllActivities(),
21930
21453
  parentOf: (activityId) => adapter.getParentId(activityId),
21931
21454
  filter,
21932
- context,
21933
- relativePlacementPins
21455
+ context
21934
21456
  });
21935
21457
  adapter.setFilterProjection(rebuiltProjection);
21936
21458
  visibleIds = rebuiltProjection.visibleIds;
@@ -21986,11 +21508,7 @@ var ScheduleCore = class _ScheduleCore {
21986
21508
  this.coreRuntime.baseCalendars
21987
21509
  )
21988
21510
  );
21989
- 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
21990
- // garbage. Without this term the calculation only learns it is obsolete
21991
- // when the mutation finishes, which measured live is the same instant the
21992
- // job itself ends.
21993
- this._pendingScheduleRevision === this._scheduleRevision;
21511
+ const isCurrent = () => !cancellation.cancelled && this._status !== SCHEDULE_CORE_STATUS.DESTROYED && this._scheduleRevision === revision && this._pendingScheduleRevision === this._scheduleRevision;
21994
21512
  const promise = (async () => {
21995
21513
  const calculatedFields = await computeCriticalPathFields(
21996
21514
  isolatedState,
@@ -22340,6 +21858,6 @@ var CREATION_KIND = {
22340
21858
  ROOT: "root"
22341
21859
  };
22342
21860
 
22343
- export { ACTIVITY_TYPE, CALENDAR_UNIT, COLUMN, CONSTRAINT_TYPE2 as CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CREATION_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_TRACK_EVENT, LINK_CODE_TO_TYPE, LINK_TYPE, LINK_TYPE_CODE, NEW_ACTIVITY_DEFAULTS, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, STATUS, ScheduleCore, WORK_TIME_DIRECTION, checkNoUpdatedLinks, computeExpectedProgress, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
21861
+ export { ACTIVITY_TYPE, CALENDAR_UNIT, COLUMN, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CREATION_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_TRACK_EVENT, LINK_CODE_TO_TYPE, LINK_TYPE, LINK_TYPE_CODE, NEW_ACTIVITY_DEFAULTS, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, STATUS, ScheduleCore, WORK_TIME_DIRECTION, checkNoUpdatedLinks, computeExpectedProgress, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
22344
21862
  //# sourceMappingURL=index.js.map
22345
21863
  //# sourceMappingURL=index.js.map