orizu 0.5.52 → 0.5.53
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/auth-commands.js +2 -2
- package/dist/cli-console-output.d.ts +7 -1
- package/dist/cli-console-output.d.ts.map +1 -1
- package/dist/cli-console-output.js +16 -3
- package/dist/cli-stops.d.ts +14 -0
- package/dist/cli-stops.d.ts.map +1 -0
- package/dist/cli-stops.js +22 -0
- package/dist/egress-allowlist-cli.d.ts +29 -2
- package/dist/egress-allowlist-cli.d.ts.map +1 -1
- package/dist/egress-allowlist-cli.js +16 -89
- package/dist/egress-allowlist-workflow.d.ts +17 -0
- package/dist/egress-allowlist-workflow.d.ts.map +1 -0
- package/dist/egress-allowlist-workflow.js +183 -0
- package/dist/instruction-delivery.d.ts +4 -4
- package/dist/instruction-delivery.d.ts.map +1 -1
- package/dist/instruction-delivery.js +32 -46
- package/dist/instruction-prune.d.ts +24 -0
- package/dist/instruction-prune.d.ts.map +1 -0
- package/dist/instruction-prune.js +33 -0
- package/dist/instruction-set-sync/index.d.ts +0 -2
- package/dist/instruction-set-sync/index.d.ts.map +1 -1
- package/dist/instruction-set-sync/index.js +3 -36
- package/dist/instruction-set-update/index.d.ts +41 -3
- package/dist/instruction-set-update/index.d.ts.map +1 -1
- package/dist/instruction-set-update/index.js +156 -132
- package/dist/instruction-sets-cli.d.ts.map +1 -1
- package/dist/instruction-sets-cli.js +21 -2
- package/dist/instruction-sync-lock.d.ts +9 -0
- package/dist/instruction-sync-lock.d.ts.map +1 -0
- package/dist/instruction-sync-lock.js +24 -0
- package/dist/json-output-scrub.d.ts +3 -0
- package/dist/json-output-scrub.d.ts.map +1 -0
- package/dist/json-output-scrub.js +70 -0
- package/dist/one-request-write.d.ts.map +1 -1
- package/dist/one-request-write.js +2 -9
- package/dist/workbench-cli.d.ts +2 -1
- package/dist/workbench-cli.d.ts.map +1 -1
- package/dist/workbench-cli.js +79 -593
- package/dist/workbench-workflows.d.ts +56 -0
- package/dist/workbench-workflows.d.ts.map +1 -0
- package/dist/workbench-workflows.js +665 -0
- package/dist/workspace-sync-workflow.d.ts +115 -0
- package/dist/workspace-sync-workflow.d.ts.map +1 -0
- package/dist/workspace-sync-workflow.js +642 -0
- package/dist/workspace-sync.d.ts +45 -97
- package/dist/workspace-sync.d.ts.map +1 -1
- package/dist/workspace-sync.js +53 -494
- package/package.json +1 -1
- package/src/auth-commands.ts +2 -2
- package/src/cli-console-output.ts +16 -2
- package/src/cli-stops.ts +27 -0
- package/src/egress-allowlist-cli.ts +18 -90
- package/src/egress-allowlist-workflow.ts +198 -0
- package/src/instruction-delivery.ts +31 -47
- package/src/instruction-prune.ts +59 -0
- package/src/instruction-set-sync/index.ts +3 -43
- package/src/instruction-set-update/index.ts +173 -122
- package/src/instruction-sets-cli.ts +23 -2
- package/src/instruction-sync-lock.ts +27 -0
- package/src/json-output-scrub.ts +73 -0
- package/src/one-request-write.ts +2 -10
- package/src/workbench-cli.ts +83 -684
- package/src/workbench-workflows.ts +815 -0
- package/src/workspace-sync-workflow.ts +838 -0
- package/src/workspace-sync.ts +63 -630
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
1
2
|
import { Cause, Effect, Exit } from 'effect';
|
|
3
|
+
import { runWithStops } from './cli-stops.js';
|
|
2
4
|
import { authedFetch } from './http.js';
|
|
3
5
|
import { responsePayload } from './json-response.js';
|
|
4
|
-
import { stageSyncPayload
|
|
5
|
-
import { applyUpdate, lockedProfileIdentity, makeUpdatePlan, readUpdateLock } from './instruction-set-update/index.js';
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
|
|
6
|
+
import { stageSyncPayload } from './instruction-set-sync/index.js';
|
|
7
|
+
import { applyUpdate, lockedProfileIdentity, makeUpdatePlan, publishNoSyncUpdate, readUpdateLock } from './instruction-set-update/index.js';
|
|
8
|
+
import { attempt, holdSyncLock } from './instruction-sync-lock.js';
|
|
9
|
+
// Loaded only through `await import(...)` from instruction-sets-cli, so CLI
|
|
10
|
+
// startup and the published loader never load Effect.
|
|
9
11
|
function readPayload(path, action) {
|
|
10
12
|
return Effect.tryPromise({
|
|
11
13
|
// The body stays unchecked here, as before: stageSyncPayload and makeUpdatePlan validate it.
|
|
@@ -14,51 +16,29 @@ function readPayload(path, action) {
|
|
|
14
16
|
catch: cause => cause,
|
|
15
17
|
});
|
|
16
18
|
}
|
|
17
|
-
//
|
|
18
|
-
// is
|
|
19
|
-
|
|
20
|
-
const acquire = Effect.gen(function* () {
|
|
21
|
-
const claim = yield* attempt(() => startSyncLockClaim(appRoot));
|
|
22
|
-
while (true) {
|
|
23
|
-
const claimed = yield* attempt(() => tryClaimSyncLock(claim));
|
|
24
|
-
if (typeof claimed === 'function')
|
|
25
|
-
return claimed;
|
|
26
|
-
yield* Effect.interruptible(Effect.sleep(claimed));
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
return Effect.acquireUseRelease(acquire, () => use, release => Effect.sync(release));
|
|
30
|
-
}
|
|
31
|
-
// Stage the version, publish it under the lock, and always remove an
|
|
32
|
-
// unpublished stage, including after Ctrl-C or SIGTERM.
|
|
19
|
+
// Stage the version, publish it under the lock (to completion once the lock
|
|
20
|
+
// is ours), and always remove an unpublished stage, including after Ctrl-C or
|
|
21
|
+
// SIGTERM.
|
|
33
22
|
function deliverPayload(...args) {
|
|
34
23
|
return Effect.acquireUseRelease(attempt(() => stageSyncPayload(...args)), staged => holdSyncLock(staged.appRoot, attempt(staged.publish)).pipe(Effect.map(warnings => ({ destination: staged.destination, wasPresent: staged.wasPresent, warnings }))), staged => Effect.sync(staged.discard));
|
|
35
24
|
}
|
|
25
|
+
/** Stages and publishes one version under the folder lock (tests and the fixture script). */
|
|
26
|
+
export function syncPayloadToDisk(...args) {
|
|
27
|
+
return runOrThrow(deliverPayload(...args), new AbortController().signal);
|
|
28
|
+
}
|
|
36
29
|
async function runOrThrow(program, signal) {
|
|
37
30
|
const exit = await Effect.runPromiseExit(program, { signal });
|
|
38
31
|
if (Exit.isSuccess(exit))
|
|
39
32
|
return exit.value;
|
|
40
33
|
throw Cause.squash(exit.cause);
|
|
41
34
|
}
|
|
42
|
-
// `once`: a second signal falls through to Node's default kill.
|
|
43
35
|
async function runDelivery(program) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
return await runOrThrow(program(controller.signal), controller.signal);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
if (interrupted !== undefined)
|
|
55
|
-
return { interrupted };
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
finally {
|
|
59
|
-
process.removeListener('SIGINT', handleInterrupt);
|
|
60
|
-
process.removeListener('SIGTERM', handleTerminate);
|
|
61
|
-
}
|
|
36
|
+
const { exit, interrupted } = await runWithStops(program);
|
|
37
|
+
if (Exit.isSuccess(exit))
|
|
38
|
+
return exit.value;
|
|
39
|
+
if (interrupted !== undefined)
|
|
40
|
+
return { interrupted };
|
|
41
|
+
throw Cause.squash(exit.cause);
|
|
62
42
|
}
|
|
63
43
|
export function syncInstructionSet(out, project, plan, options) {
|
|
64
44
|
return runDelivery(() => Effect.gen(function* () {
|
|
@@ -84,12 +64,18 @@ export function updateInstructionSets(out, project, isApproved, noSync) {
|
|
|
84
64
|
const plan = yield* attempt(() => makeUpdatePlan(project, lock, payloads));
|
|
85
65
|
if (!isApproved)
|
|
86
66
|
return { plan, result: { absent: [], warnings: [] } };
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
67
|
+
// --no-sync writes the Lock under the folder lock. Otherwise applyUpdate's
|
|
68
|
+
// own steps are not interruptible; each version it syncs is a nested
|
|
69
|
+
// delivery that the shared signal interrupts and cleans up.
|
|
70
|
+
const result = noSync
|
|
71
|
+
? yield* holdSyncLock(join(out, 'orizu'), Effect.uninterruptible(Effect.tryPromise({
|
|
72
|
+
try: () => publishNoSyncUpdate(out, project, plan),
|
|
73
|
+
catch: cause => cause,
|
|
74
|
+
})))
|
|
75
|
+
: yield* Effect.uninterruptible(Effect.tryPromise({
|
|
76
|
+
try: () => applyUpdate(out, project, plan, () => new Date(), (...args) => runOrThrow(deliverPayload(...args), signal)),
|
|
77
|
+
catch: cause => cause,
|
|
78
|
+
}));
|
|
93
79
|
return { plan, result };
|
|
94
80
|
});
|
|
95
81
|
// --no-sync stages nothing to clean up, so keep Node's default signal
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Interrupted } from './cli-stops.js';
|
|
2
|
+
import { type PrunePlan, type PruneResult } from './instruction-set-update/index.js';
|
|
3
|
+
/** What the removal step did before a stop was handled. */
|
|
4
|
+
export type PruneOutcome = {
|
|
5
|
+
kind: 'not started';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'removed';
|
|
8
|
+
count: number;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'rolled back';
|
|
11
|
+
error: unknown;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'rollback failed';
|
|
14
|
+
};
|
|
15
|
+
export type PruneStopped = Interrupted & {
|
|
16
|
+
outcome: PruneOutcome;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Removes the approved Versions under the folder lock. Waiting for the lock
|
|
20
|
+
* and planning again can be stopped and change nothing. The removal itself
|
|
21
|
+
* always settles once it starts: applied and verified, or fully rolled back.
|
|
22
|
+
*/
|
|
23
|
+
export declare function pruneInstructionSets(out: string, plan: PrunePlan, keepSpecifiers: string[]): Promise<PruneResult | PruneStopped>;
|
|
24
|
+
//# sourceMappingURL=instruction-prune.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction-prune.d.ts","sourceRoot":"","sources":["../src/instruction-prune.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC/D,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,mCAAmC,CAAA;AAM1C,2DAA2D;AAC3D,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAA;AAE/B,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAA;AAElE;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC,CAwBtI"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { Cause, Effect, Exit } from 'effect';
|
|
3
|
+
import { runWithStops } from './cli-stops.js';
|
|
4
|
+
import { finishPrune, rollBackPrune, selectPruneRemovals, stagePruneRemovals, startPrune, verifyPrunedTree, } from './instruction-set-update/index.js';
|
|
5
|
+
import { attempt, holdSyncLock } from './instruction-sync-lock.js';
|
|
6
|
+
/**
|
|
7
|
+
* Removes the approved Versions under the folder lock. Waiting for the lock
|
|
8
|
+
* and planning again can be stopped and change nothing. The removal itself
|
|
9
|
+
* always settles once it starts: applied and verified, or fully rolled back.
|
|
10
|
+
*/
|
|
11
|
+
export async function pruneInstructionSets(out, plan, keepSpecifiers) {
|
|
12
|
+
const state = { outcome: { kind: 'not started' } };
|
|
13
|
+
const program = holdSyncLock(join(out, 'orizu'), Effect.gen(function* () {
|
|
14
|
+
const selection = yield* Effect.tryPromise({ try: () => selectPruneRemovals(out, plan, keepSpecifiers), catch: cause => cause });
|
|
15
|
+
yield* Effect.uninterruptible(Effect.gen(function* () {
|
|
16
|
+
const prune = yield* attempt(() => startPrune(out));
|
|
17
|
+
yield* Effect.gen(function* () {
|
|
18
|
+
yield* attempt(() => stagePruneRemovals(out, prune, selection));
|
|
19
|
+
yield* Effect.tryPromise({ try: () => verifyPrunedTree(out), catch: cause => cause });
|
|
20
|
+
yield* attempt(() => finishPrune(prune));
|
|
21
|
+
}).pipe(Effect.catch(error => attempt(() => rollBackPrune(prune)).pipe(Effect.tapError(() => Effect.sync(() => { state.outcome = { kind: 'rollback failed' }; })), Effect.andThen(Effect.sync(() => { state.outcome = { kind: 'rolled back', error }; })), Effect.andThen(Effect.fail(error)))));
|
|
22
|
+
state.outcome = { kind: 'removed', count: selection.removals.length };
|
|
23
|
+
}));
|
|
24
|
+
return { skipped: selection.skipped };
|
|
25
|
+
}));
|
|
26
|
+
const { exit, interrupted } = await runWithStops(() => program);
|
|
27
|
+
// A failed rollback always surfaces its error, stop or not.
|
|
28
|
+
if (interrupted !== undefined && state.outcome.kind !== 'rollback failed')
|
|
29
|
+
return { interrupted, outcome: state.outcome };
|
|
30
|
+
if (Exit.isSuccess(exit))
|
|
31
|
+
return exit.value;
|
|
32
|
+
throw Cause.squash(exit.cause);
|
|
33
|
+
}
|
|
@@ -51,7 +51,6 @@ export interface SyncLockClaim {
|
|
|
51
51
|
}
|
|
52
52
|
export declare function startSyncLockClaim(appRoot: string): SyncLockClaim;
|
|
53
53
|
export declare function tryClaimSyncLock({ lockPath, metadata, deadline }: SyncLockClaim): (() => void) | number;
|
|
54
|
-
export declare function withSyncLock<T>(appRoot: string, operation: () => T): T;
|
|
55
54
|
export interface SyncDiskResult {
|
|
56
55
|
destination: string;
|
|
57
56
|
wasPresent: boolean;
|
|
@@ -73,6 +72,5 @@ export interface StagedSync {
|
|
|
73
72
|
/** Removes the staged version if it was not published. Safe to call more than once. */
|
|
74
73
|
discard: () => void;
|
|
75
74
|
}
|
|
76
|
-
export declare function syncPayloadToDisk(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): SyncDiskResult;
|
|
77
75
|
export declare function stageSyncPayload(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): StagedSync;
|
|
78
76
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACrB,MAAM,kCAAkC,CAAA;AAIzC,eAAO,MAAM,iBAAiB,OAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,6 @@ const SYNC_LOCK_STALE_MS = 60_000;
|
|
|
10
10
|
function isNodeError(error) {
|
|
11
11
|
return error instanceof Error;
|
|
12
12
|
}
|
|
13
|
-
function sleepSync(milliseconds) {
|
|
14
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
15
|
-
}
|
|
16
13
|
export function parseSyncTarget(value) {
|
|
17
14
|
const target = value ?? 'ts';
|
|
18
15
|
if (target !== 'ts')
|
|
@@ -421,7 +418,7 @@ export function startSyncLockClaim(appRoot) {
|
|
|
421
418
|
};
|
|
422
419
|
}
|
|
423
420
|
// One claim attempt: returns the release function, or how long to wait before
|
|
424
|
-
// trying again.
|
|
421
|
+
// trying again. The caller waits without blocking (instruction-sync-lock.ts).
|
|
425
422
|
export function tryClaimSyncLock({ lockPath, metadata, deadline }) {
|
|
426
423
|
while (true) {
|
|
427
424
|
try {
|
|
@@ -462,27 +459,6 @@ export function tryClaimSyncLock({ lockPath, metadata, deadline }) {
|
|
|
462
459
|
}
|
|
463
460
|
};
|
|
464
461
|
}
|
|
465
|
-
export function withSyncLock(appRoot, operation) {
|
|
466
|
-
const claim = startSyncLockClaim(appRoot);
|
|
467
|
-
let release = tryClaimSyncLock(claim);
|
|
468
|
-
while (typeof release === 'number') {
|
|
469
|
-
sleepSync(release);
|
|
470
|
-
release = tryClaimSyncLock(claim);
|
|
471
|
-
}
|
|
472
|
-
let result;
|
|
473
|
-
try {
|
|
474
|
-
result = operation();
|
|
475
|
-
}
|
|
476
|
-
catch (error) {
|
|
477
|
-
release();
|
|
478
|
-
throw error;
|
|
479
|
-
}
|
|
480
|
-
if (result && typeof result.then === 'function') {
|
|
481
|
-
return Promise.resolve(result).finally(release);
|
|
482
|
-
}
|
|
483
|
-
release();
|
|
484
|
-
return result;
|
|
485
|
-
}
|
|
486
462
|
// Test-only process boundary hooks. Production behavior is unchanged unless a
|
|
487
463
|
// test child explicitly supplies one of the bounded ORIZU_TEST_SYNC_* values.
|
|
488
464
|
function processTestMilliseconds(name, minimum, maximum) {
|
|
@@ -497,21 +473,12 @@ function processTestMilliseconds(name, minimum, maximum) {
|
|
|
497
473
|
}
|
|
498
474
|
return milliseconds;
|
|
499
475
|
}
|
|
476
|
+
// Holds the real step in place, as a slow disk would, so a test can act mid-step.
|
|
500
477
|
function holdForProcessTest(name) {
|
|
501
478
|
const milliseconds = processTestMilliseconds(name, 0, 10_000);
|
|
502
479
|
if (milliseconds === undefined)
|
|
503
480
|
return;
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
|
|
507
|
-
const staged = stageSyncPayload(out, project, plan, payload, options);
|
|
508
|
-
try {
|
|
509
|
-
const warnings = withSyncLock(staged.appRoot, staged.publish);
|
|
510
|
-
return { destination: staged.destination, wasPresent: staged.wasPresent, warnings };
|
|
511
|
-
}
|
|
512
|
-
finally {
|
|
513
|
-
staged.discard();
|
|
514
|
-
}
|
|
481
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
515
482
|
}
|
|
516
483
|
export function stageSyncPayload(out, project, plan, payload, options = {}) {
|
|
517
484
|
const target = parseSyncTarget(options.target);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type InstructionSetLockV1 } from '../instruction-set-lock/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { type SyncDiskOptions, type SyncDiskResult, type SyncPayload, type SyncRequestPlan } from '../instruction-set-sync/index.js';
|
|
3
3
|
export interface UpdateResolution {
|
|
4
4
|
payload: SyncPayload;
|
|
5
5
|
profileIdentity: string;
|
|
@@ -16,7 +16,11 @@ export interface UpdateResult {
|
|
|
16
16
|
absent: string[];
|
|
17
17
|
warnings: string[];
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/** --no-sync: records the planned Pointers in the Lock. The caller holds the folder lock. */
|
|
20
|
+
export declare function publishNoSyncUpdate(out: string, project: string, plan: UpdatePlan, now?: () => Date): Promise<UpdateResult>;
|
|
21
|
+
export type SyncStep = (out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options: SyncDiskOptions) => Promise<SyncDiskResult>;
|
|
22
|
+
/** Syncs every newly referenced Version; `sync` takes the folder lock for each one. */
|
|
23
|
+
export declare function applyUpdate(out: string, project: string, plan: UpdatePlan, now: () => Date, sync: SyncStep): Promise<UpdateResult>;
|
|
20
24
|
export interface PrunePlan {
|
|
21
25
|
lock: InstructionSetLockV1;
|
|
22
26
|
removals: Array<{
|
|
@@ -38,5 +42,39 @@ export declare function planPrune(out: string, keepSpecifiers: string[]): Promis
|
|
|
38
42
|
export interface PruneResult {
|
|
39
43
|
skipped: PrunePlan['removals'];
|
|
40
44
|
}
|
|
41
|
-
export
|
|
45
|
+
export interface PruneSelection {
|
|
46
|
+
lock: InstructionSetLockV1;
|
|
47
|
+
removals: PrunePlan['removals'];
|
|
48
|
+
skipped: PrunePlan['removals'];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Plans again under the folder lock: keeps only approved removals that are
|
|
52
|
+
* still unreferenced (never adds one) and skips profiles holding unmanaged
|
|
53
|
+
* files. Reads only.
|
|
54
|
+
*/
|
|
55
|
+
export declare function selectPruneRemovals(out: string, plan: PrunePlan, keepSpecifiers: string[]): Promise<PruneSelection>;
|
|
56
|
+
/** A prune in progress: what it moved aside and what it must restore on failure. */
|
|
57
|
+
export interface StagedPrune {
|
|
58
|
+
lockPath: string;
|
|
59
|
+
importMapPath: string;
|
|
60
|
+
priorLock: string;
|
|
61
|
+
priorImportMap: string | null;
|
|
62
|
+
stagingRoot: string;
|
|
63
|
+
staged: Array<{
|
|
64
|
+
removal: PrunePlan['removals'][number];
|
|
65
|
+
stagedPath: string;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
export declare function startPrune(out: string): StagedPrune;
|
|
69
|
+
/**
|
|
70
|
+
* Moves each removal into the staging folder, then writes the new Lock and
|
|
71
|
+
* generated index. Records each move as it happens so a failure part-way can
|
|
72
|
+
* be rolled back.
|
|
73
|
+
*/
|
|
74
|
+
export declare function stagePruneRemovals(out: string, prune: StagedPrune, selection: PruneSelection): void;
|
|
75
|
+
/** Verifies the pruned tree; the error names the first failure. */
|
|
76
|
+
export declare function verifyPrunedTree(out: string): Promise<void>;
|
|
77
|
+
export declare function finishPrune(prune: StagedPrune): void;
|
|
78
|
+
/** Puts back every moved folder, the prior Lock and the prior generated index. */
|
|
79
|
+
export declare function rollBackPrune(prune: StagedPrune): void;
|
|
42
80
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAA;AAEzC,OAAO,EAA4C,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"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"}
|