@teambit/lanes 1.0.1191 → 1.0.1193
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/lane.cmd.d.ts +36 -0
- package/dist/lane.cmd.js +97 -1
- package/dist/lane.cmd.js.map +1 -1
- package/dist/lanes.main.runtime.d.ts +52 -0
- package/dist/lanes.main.runtime.js +127 -15
- package/dist/lanes.main.runtime.js.map +1 -1
- package/dist/lanes.spec.js +157 -0
- package/dist/lanes.spec.js.map +1 -1
- package/dist/{preview-1789507760807.js → preview-1789739547673.js} +2 -2
- package/package.json +36 -35
|
@@ -87,6 +87,13 @@ function _laneId() {
|
|
|
87
87
|
};
|
|
88
88
|
return data;
|
|
89
89
|
}
|
|
90
|
+
function _legacy2() {
|
|
91
|
+
const data = require("@teambit/legacy.scope-api");
|
|
92
|
+
_legacy2 = function () {
|
|
93
|
+
return data;
|
|
94
|
+
};
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
90
97
|
function _bitError() {
|
|
91
98
|
const data = require("@teambit/bit-error");
|
|
92
99
|
_bitError = function () {
|
|
@@ -317,6 +324,11 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
317
324
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
318
325
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
319
326
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* eslint-disable max-lines */
|
|
327
|
+
/**
|
|
328
|
+
* where the entries were read from. the remote lane is the source of truth, so anything else means the
|
|
329
|
+
* local lane object was used instead, and why.
|
|
330
|
+
*/
|
|
331
|
+
|
|
320
332
|
/** where the base was resolved from: `workspace` (already local) or `scope` (fetched from remote). */
|
|
321
333
|
|
|
322
334
|
class LanesMain {
|
|
@@ -1429,24 +1441,123 @@ please create a new lane instead, which will include all components of this lane
|
|
|
1429
1441
|
}
|
|
1430
1442
|
|
|
1431
1443
|
/**
|
|
1432
|
-
*
|
|
1433
|
-
*
|
|
1444
|
+
* the dependents Ripple CI cascaded onto a lane (hidden `lane.updateDependents` entries).
|
|
1445
|
+
* the cascade producer runs on the remote, so the remote lane is the source of truth. the local lane
|
|
1446
|
+
* object is used only when the remote lane can't be fetched (e.g. the lane was never exported).
|
|
1434
1447
|
*/
|
|
1435
|
-
async
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1448
|
+
async getLaneUpdateDependents(laneId) {
|
|
1449
|
+
let remoteError;
|
|
1450
|
+
const remoteLane = this.isLaneLocalOnly(laneId) ? undefined : await this.importLaneObject(laneId, false).catch(err => {
|
|
1451
|
+
remoteError = err;
|
|
1452
|
+
return undefined;
|
|
1453
|
+
});
|
|
1454
|
+
if (remoteLane) {
|
|
1455
|
+
return {
|
|
1456
|
+
laneId,
|
|
1457
|
+
ids: remoteLane.updateDependents || [],
|
|
1458
|
+
source: 'remote'
|
|
1459
|
+
};
|
|
1442
1460
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
});
|
|
1447
|
-
|
|
1461
|
+
const localLane = await this.loadLane(laneId);
|
|
1462
|
+
if (!localLane) {
|
|
1463
|
+
const reason = remoteError ? `, and fetching it from the remote failed: ${remoteError.message}` : '';
|
|
1464
|
+
throw new (_bitError().BitError)(`lane "${laneId.toString()}" was not found locally${reason}`);
|
|
1465
|
+
}
|
|
1466
|
+
// no error means no fetch was attempted, i.e. the lane is local-only. LaneNotFound means the same
|
|
1467
|
+
// thing from the remote's side: either way the remote has no lane to be the source of truth.
|
|
1468
|
+
const source = !remoteError || remoteError instanceof _legacy2().LaneNotFound ? 'no-remote-lane' : 'remote-unavailable';
|
|
1469
|
+
return {
|
|
1470
|
+
laneId,
|
|
1471
|
+
ids: localLane.updateDependents || [],
|
|
1472
|
+
source,
|
|
1473
|
+
remoteError: remoteError?.message
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* remove the dependents Ripple CI cascaded onto a lane.
|
|
1479
|
+
* exporting a lane never removes hidden entries from the remote (the remote-side merge walks the
|
|
1480
|
+
* incoming entries only), so the removal is done directly on the remote, the same way the cloud UI
|
|
1481
|
+
* does. the local lane object is updated as well so it doesn't keep stale entries until the next
|
|
1482
|
+
* import. a lane that was never exported is changed locally only.
|
|
1483
|
+
*/
|
|
1484
|
+
async undoLaneUpdateDependents(laneId, ids) {
|
|
1485
|
+
const current = await this.getLaneUpdateDependents(laneId);
|
|
1486
|
+
if (current.source === 'remote-unavailable') {
|
|
1487
|
+
// the remote is the source of truth for these entries. removing them locally while the remote keeps
|
|
1488
|
+
// them would only be reverted by the next import, so fail instead of pretending it worked.
|
|
1489
|
+
throw new (_bitError().BitError)(`unable to undo the cascaded updates of lane "${laneId.toString()}": the remote lane could not be fetched (${current.remoteError}). the remote is the source of truth for these entries, retry when it's reachable`);
|
|
1448
1490
|
}
|
|
1449
|
-
|
|
1491
|
+
// the remote has no such lane, so there's nothing to remove there: change the local lane only
|
|
1492
|
+
const remoteSkipped = current.source === 'no-remote-lane';
|
|
1493
|
+
const removed = ids?.length ? current.ids.filter(id => ids.some(toRemove => toRemove.isEqualWithoutVersion(id))) : current.ids;
|
|
1494
|
+
if (!removed.length) {
|
|
1495
|
+
// nothing left to remove on the remote, but the local lane can still hold entries the remote already
|
|
1496
|
+
// dropped - e.g. an earlier undo whose local save failed after the remote removal succeeded. reconcile
|
|
1497
|
+
// them here so retrying the command fixes it, instead of the stale entries lingering until the next import.
|
|
1498
|
+
const localChanged = remoteSkipped ? false : await this.pruneStaleUpdateDependents(laneId, current.ids);
|
|
1499
|
+
return {
|
|
1500
|
+
laneId,
|
|
1501
|
+
removed,
|
|
1502
|
+
remoteChanged: false,
|
|
1503
|
+
localChanged,
|
|
1504
|
+
remoteSkipped
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
// remove exactly the resolved entries, on the remote and locally. this keeps local-only entries (e.g. a
|
|
1508
|
+
// workspace cascade that wasn't exported yet) intact instead of wiping them with a remove-all.
|
|
1509
|
+
const removedIdsStr = removed.map(id => id.toString());
|
|
1510
|
+
let remoteChanged = false;
|
|
1511
|
+
if (!remoteSkipped) {
|
|
1512
|
+
const remote = await (0, _scope2().getRemoteByName)(laneId.scope, this.workspace?.consumer);
|
|
1513
|
+
remoteChanged = await remote.removeLaneUpdateDependents(laneId.toString(), removedIdsStr);
|
|
1514
|
+
}
|
|
1515
|
+
const localLane = await this.loadLane(laneId);
|
|
1516
|
+
// the local removal matches by component-id and not by the full versioned id on purpose. when a local
|
|
1517
|
+
// cascade moved ahead of the remote, that entry is still for a component the user just undid: it can't
|
|
1518
|
+
// be exported (the remote refuses new hidden entries without the override flag) and the next import
|
|
1519
|
+
// prunes it anyway. keeping it would leave a hidden entry that "bit lane updates" no longer reports.
|
|
1520
|
+
const localChanged = localLane ? await this.removeUpdateDependents(laneId, removed) : false;
|
|
1521
|
+
return {
|
|
1522
|
+
laneId,
|
|
1523
|
+
removed,
|
|
1524
|
+
remoteChanged,
|
|
1525
|
+
localChanged,
|
|
1526
|
+
remoteSkipped
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* remove local hidden entries whose component-id is absent from `remoteIds`, i.e. entries the remote has
|
|
1532
|
+
* already dropped. matches by component-id and not by version, the same rule the import-side reconciliation
|
|
1533
|
+
* in the lane merge uses, so a local cascade that only moved ahead of the remote survives.
|
|
1534
|
+
* returns true if the local lane has changed.
|
|
1535
|
+
*/
|
|
1536
|
+
async pruneStaleUpdateDependents(laneId, remoteIds) {
|
|
1537
|
+
const localLane = await this.loadLane(laneId);
|
|
1538
|
+
const localIds = localLane?.updateDependents;
|
|
1539
|
+
if (!localIds?.length) return false;
|
|
1540
|
+
const stale = localIds.filter(id => !remoteIds.some(remoteId => remoteId.isEqualWithoutVersion(id)));
|
|
1541
|
+
if (!stale.length) return false;
|
|
1542
|
+
return this.removeUpdateDependents(laneId, stale);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* true when `laneId` is the current lane and it was never exported, i.e. it doesn't exist on the remote yet.
|
|
1547
|
+
*/
|
|
1548
|
+
isLaneLocalOnly(laneId) {
|
|
1549
|
+
if (!this.workspace) return false;
|
|
1550
|
+
const currentLaneId = this.getCurrentLaneId();
|
|
1551
|
+
if (!currentLaneId?.isEqual(laneId)) return false;
|
|
1552
|
+
return !this.workspace.consumer.bitMap.isLaneExported;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
/**
|
|
1556
|
+
* default to remove all of them.
|
|
1557
|
+
* returns true if the lane has changed
|
|
1558
|
+
*/
|
|
1559
|
+
removeUpdateDependents(laneId, ids) {
|
|
1560
|
+
return this.scope.legacyScope.lanes.removeUpdateDependents(laneId, ids);
|
|
1450
1561
|
}
|
|
1451
1562
|
async getLaneDataOfDefaultLane() {
|
|
1452
1563
|
const consumer = this.workspace?.consumer;
|
|
@@ -1490,6 +1601,7 @@ please create a new lane instead, which will include all components of this lane
|
|
|
1490
1601
|
laneCmd.commands.push(new (_lanesModules().LaneHistoryDiffCmd)(lanesMain, workspace, scope, componentCompare));
|
|
1491
1602
|
laneCmd.commands.push(new (_lane().LaneCheckoutCmd)(lanesMain));
|
|
1492
1603
|
laneCmd.commands.push(new (_lane().LaneRevertCmd)(lanesMain));
|
|
1604
|
+
laneCmd.commands.push(new (_lane().LaneUpdatesCmd)(lanesMain));
|
|
1493
1605
|
cli.register(laneCmd, switchCmd, new (_lane().CatLaneHistoryCmd)(lanesMain));
|
|
1494
1606
|
cli.registerOnStart(async () => {
|
|
1495
1607
|
await lanesMain.recreateNewLaneIfDeleted();
|