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