@outbuild-company/schedule-core 1.1.2 → 1.2.0

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.d.cts CHANGED
@@ -29,16 +29,32 @@ interface LinkSnapshot {
29
29
  * duration (`_targetLag = -summary.duration`) and the per-leaf offset from
30
30
  * the summary's start (`_trueLag = userLag + off_tgt(leaf)`), matching legacy
31
31
  * `_getImplicitLinks`/`_convertToFinishToStartLink` under
32
- * `auto_scheduling_move_projects`. Computed ONCE at expansion time
33
- * (`parent-link-expansion.ts`), never per scheduling tick.
32
+ * `auto_scheduling_move_projects`. `_targetLag`/`_trueLag` are computed once
33
+ * at expansion time, matching legacy relations frozen per run, and the
34
+ * per-leaf offset in `_trueLag` applies only to leaves with no incoming
35
+ * links (legacy `!c.$target.length` — a leaf with its own driver keeps
36
+ * offset 0, otherwise the frozen offset compounds on every settle).
37
+ * `_sourceLag` is the expansion-time fallback: when `_summarySourceId` is
38
+ * present (SS/SF out of a summary), the ASAP calculator re-derives it at
39
+ * evaluation time from the summary's CURRENT derived bounds so the virtual
40
+ * constraint stays anchored at the summary start even after the anchor leaf
41
+ * moves within the same run.
34
42
  *
35
- * All three must be set together (or none): a half-populated link would mix
36
- * precomputed and derived components. Only the FF/SF-into-summary path emits
37
- * them; every other link leaves them undefined and hits the fast path.
43
+ * `_summaryTargetId` marks a virtual link whose `_trueLag` bakes a NON-ZERO
44
+ * leaf offset measured from the target summary's expansion-time bounds: the
45
+ * ASAP pass refuses to pull the leaf back through such a link unless the
46
+ * predecessor itself moved in the run (a stale frozen offset must never
47
+ * drag its own leaf earlier — that is the summary-link drift bug).
48
+ *
49
+ * The three lag components must be set together (or none): a half-populated
50
+ * link would mix precomputed and derived components. Every non-virtual link
51
+ * leaves them undefined and hits the fast path.
38
52
  */
39
53
  _sourceLag?: number;
40
54
  _targetLag?: number;
41
55
  _trueLag?: number;
56
+ _summarySourceId?: ActivityId$1;
57
+ _summaryTargetId?: ActivityId$1;
42
58
  ganttId?: number;
43
59
  sectorId?: number;
44
60
  /** BE row id (distinct from the schedule-level `id`). */
@@ -269,17 +285,6 @@ interface CoreActivity {
269
285
  expectedProgressBaseline: number | null;
270
286
  status: ActivityStatus | null;
271
287
  criticalPath: CriticalPathResult | null;
272
- /** Internal reversible leaf→project promotion state; never serialized. */
273
- promotionRestore: {
274
- type: 'task' | 'milestone';
275
- startDate: Date;
276
- endDate: Date;
277
- durationHours: number;
278
- expectedProgressBaseline: number | null;
279
- constraintType: ConstraintType;
280
- constraintDate: Date | null;
281
- progress: number;
282
- } | null;
283
288
  }
284
289
  interface Link {
285
290
  id: LinkId;
@@ -888,6 +893,8 @@ type DispatchResult = {
888
893
  * rechazados.
889
894
  */
890
895
  verdicts?: ReadonlyArray<DatesBatchVerdict>;
896
+ activityVerdicts?: ReadonlyArray<DatesBatchVerdict>;
897
+ linkVerdicts?: ReadonlyArray<LinkBatchVerdict>;
891
898
  /**
892
899
  * INTERNAL (undo / B4). Full pre-mutation snapshot of every
893
900
  * deleted/structurally-removed activity row, keyed by STRING id. The
@@ -917,6 +924,17 @@ type DatesBatchVerdict = {
917
924
  reason: string;
918
925
  alertKey?: string | undefined;
919
926
  };
927
+ type LinkBatchVerdict = {
928
+ operationIndex: number;
929
+ kind: LinksBatchOperation['kind'];
930
+ ok: true;
931
+ linkId: string;
932
+ } | {
933
+ operationIndex: number;
934
+ kind: LinksBatchOperation['kind'];
935
+ ok: false;
936
+ reason: string;
937
+ };
920
938
 
921
939
  interface TrackingEvent {
922
940
  name: string;
@@ -1211,7 +1229,7 @@ declare class ScheduleCore {
1211
1229
  get ready(): Promise<void>;
1212
1230
  get criticalPathReady(): Promise<{
1213
1231
  changes: ChangeSet;
1214
- }>;
1232
+ } | null>;
1215
1233
  get status(): ScheduleCoreStatus;
1216
1234
  getSector(): Readonly<SectorMetadata>;
1217
1235
  getActivityView(id: ActivityId): Readonly<CoreActivity> | null;
@@ -1278,7 +1296,7 @@ declare class ScheduleCore {
1278
1296
  private _resyncCustomIdTrackerFromModel;
1279
1297
  destroy(): void;
1280
1298
  private readonly _initPromise;
1281
- private readonly _criticalPathReady;
1299
+ private _criticalPathReady;
1282
1300
  private readonly _ready;
1283
1301
  private readonly _saveTracker;
1284
1302
  private assertReady;
package/dist/index.d.ts CHANGED
@@ -29,16 +29,32 @@ interface LinkSnapshot {
29
29
  * duration (`_targetLag = -summary.duration`) and the per-leaf offset from
30
30
  * the summary's start (`_trueLag = userLag + off_tgt(leaf)`), matching legacy
31
31
  * `_getImplicitLinks`/`_convertToFinishToStartLink` under
32
- * `auto_scheduling_move_projects`. Computed ONCE at expansion time
33
- * (`parent-link-expansion.ts`), never per scheduling tick.
32
+ * `auto_scheduling_move_projects`. `_targetLag`/`_trueLag` are computed once
33
+ * at expansion time, matching legacy relations frozen per run, and the
34
+ * per-leaf offset in `_trueLag` applies only to leaves with no incoming
35
+ * links (legacy `!c.$target.length` — a leaf with its own driver keeps
36
+ * offset 0, otherwise the frozen offset compounds on every settle).
37
+ * `_sourceLag` is the expansion-time fallback: when `_summarySourceId` is
38
+ * present (SS/SF out of a summary), the ASAP calculator re-derives it at
39
+ * evaluation time from the summary's CURRENT derived bounds so the virtual
40
+ * constraint stays anchored at the summary start even after the anchor leaf
41
+ * moves within the same run.
34
42
  *
35
- * All three must be set together (or none): a half-populated link would mix
36
- * precomputed and derived components. Only the FF/SF-into-summary path emits
37
- * them; every other link leaves them undefined and hits the fast path.
43
+ * `_summaryTargetId` marks a virtual link whose `_trueLag` bakes a NON-ZERO
44
+ * leaf offset measured from the target summary's expansion-time bounds: the
45
+ * ASAP pass refuses to pull the leaf back through such a link unless the
46
+ * predecessor itself moved in the run (a stale frozen offset must never
47
+ * drag its own leaf earlier — that is the summary-link drift bug).
48
+ *
49
+ * The three lag components must be set together (or none): a half-populated
50
+ * link would mix precomputed and derived components. Every non-virtual link
51
+ * leaves them undefined and hits the fast path.
38
52
  */
39
53
  _sourceLag?: number;
40
54
  _targetLag?: number;
41
55
  _trueLag?: number;
56
+ _summarySourceId?: ActivityId$1;
57
+ _summaryTargetId?: ActivityId$1;
42
58
  ganttId?: number;
43
59
  sectorId?: number;
44
60
  /** BE row id (distinct from the schedule-level `id`). */
@@ -269,17 +285,6 @@ interface CoreActivity {
269
285
  expectedProgressBaseline: number | null;
270
286
  status: ActivityStatus | null;
271
287
  criticalPath: CriticalPathResult | null;
272
- /** Internal reversible leaf→project promotion state; never serialized. */
273
- promotionRestore: {
274
- type: 'task' | 'milestone';
275
- startDate: Date;
276
- endDate: Date;
277
- durationHours: number;
278
- expectedProgressBaseline: number | null;
279
- constraintType: ConstraintType;
280
- constraintDate: Date | null;
281
- progress: number;
282
- } | null;
283
288
  }
284
289
  interface Link {
285
290
  id: LinkId;
@@ -888,6 +893,8 @@ type DispatchResult = {
888
893
  * rechazados.
889
894
  */
890
895
  verdicts?: ReadonlyArray<DatesBatchVerdict>;
896
+ activityVerdicts?: ReadonlyArray<DatesBatchVerdict>;
897
+ linkVerdicts?: ReadonlyArray<LinkBatchVerdict>;
891
898
  /**
892
899
  * INTERNAL (undo / B4). Full pre-mutation snapshot of every
893
900
  * deleted/structurally-removed activity row, keyed by STRING id. The
@@ -917,6 +924,17 @@ type DatesBatchVerdict = {
917
924
  reason: string;
918
925
  alertKey?: string | undefined;
919
926
  };
927
+ type LinkBatchVerdict = {
928
+ operationIndex: number;
929
+ kind: LinksBatchOperation['kind'];
930
+ ok: true;
931
+ linkId: string;
932
+ } | {
933
+ operationIndex: number;
934
+ kind: LinksBatchOperation['kind'];
935
+ ok: false;
936
+ reason: string;
937
+ };
920
938
 
921
939
  interface TrackingEvent {
922
940
  name: string;
@@ -1211,7 +1229,7 @@ declare class ScheduleCore {
1211
1229
  get ready(): Promise<void>;
1212
1230
  get criticalPathReady(): Promise<{
1213
1231
  changes: ChangeSet;
1214
- }>;
1232
+ } | null>;
1215
1233
  get status(): ScheduleCoreStatus;
1216
1234
  getSector(): Readonly<SectorMetadata>;
1217
1235
  getActivityView(id: ActivityId): Readonly<CoreActivity> | null;
@@ -1278,7 +1296,7 @@ declare class ScheduleCore {
1278
1296
  private _resyncCustomIdTrackerFromModel;
1279
1297
  destroy(): void;
1280
1298
  private readonly _initPromise;
1281
- private readonly _criticalPathReady;
1299
+ private _criticalPathReady;
1282
1300
  private readonly _ready;
1283
1301
  private readonly _saveTracker;
1284
1302
  private assertReady;