@danypops/pi-lector 0.16.0 → 0.17.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.
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import type { MutationHistoryEntry } from "@danypops/lector";
|
|
1
|
+
import type { MutationHistoryEntry, MutationTransactionLookupOutcome } from "@danypops/lector";
|
|
2
2
|
import { withWorkspace, workspaceForPath } from "../lector-client.ts";
|
|
3
3
|
import { invokeLectorVehicleOperation, type LectorVehicleCall } from "../vehicle-client.ts";
|
|
4
4
|
import { toWorkspaceRelativePath } from "../workspace-relative-path.ts";
|
|
5
5
|
|
|
6
6
|
const MAX_INTERNAL_HISTORY_LOOKUP_RESULTS = 2_000;
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export type MutationTransactionRevertOutcome =
|
|
9
|
+
| {
|
|
10
|
+
readonly status: "reverted";
|
|
11
|
+
readonly transactionId: string;
|
|
12
|
+
readonly reverted: readonly { readonly path: string; readonly newHash: string | null }[];
|
|
13
|
+
}
|
|
14
|
+
| { readonly status: "stale"; readonly transactionId: string; readonly stalePaths: readonly string[] }
|
|
15
|
+
| Extract<MutationTransactionLookupOutcome, { readonly status: "evicted" | "wrong-workspace" | "unknown" }>;
|
|
12
16
|
|
|
13
17
|
/** Match MUTATION_HISTORY_READ_PERMISSIONS/MUTATION_HISTORY_WRITE_PERMISSIONS' own declared values server-side (mutation-history/operation-registration.ts). */
|
|
14
18
|
const MUTATION_HISTORY_READ_PERMISSIONS = ["workspace:read"];
|
|
@@ -32,24 +36,14 @@ async function listResolvedHistory(
|
|
|
32
36
|
maxResults: number,
|
|
33
37
|
call: LectorVehicleCall,
|
|
34
38
|
): Promise<readonly MutationHistoryEntry[]> {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
paths.map((path) =>
|
|
42
|
-
invokeLectorVehicleOperation<{ entries: readonly MutationHistoryEntry[] }>(
|
|
43
|
-
"workspace.mutationHistory",
|
|
44
|
-
{ workspaceId, path, maxResults },
|
|
45
|
-
MUTATION_HISTORY_READ_PERMISSIONS,
|
|
46
|
-
call,
|
|
47
|
-
),
|
|
48
|
-
),
|
|
39
|
+
const path = toWorkspaceRelativePath(root, absolutePath);
|
|
40
|
+
const page = await invokeLectorVehicleOperation<{ entries: readonly MutationHistoryEntry[] }>(
|
|
41
|
+
"workspace.mutationHistory",
|
|
42
|
+
{ workspaceId, path, maxResults },
|
|
43
|
+
MUTATION_HISTORY_READ_PERMISSIONS,
|
|
44
|
+
call,
|
|
49
45
|
);
|
|
50
|
-
|
|
51
|
-
for (const page of pages) for (const entry of page.entries) byId.set(entry.id, entry);
|
|
52
|
-
return [...byId.values()].sort((a, b) => b.timestamp - a.timestamp).slice(0, maxResults);
|
|
46
|
+
return page.entries;
|
|
53
47
|
}
|
|
54
48
|
|
|
55
49
|
export function createMutationHistoryOperations(): MutationHistoryOperations {
|
|
@@ -84,13 +78,23 @@ export function createMutationHistoryOperations(): MutationHistoryOperations {
|
|
|
84
78
|
revertTransaction(absolutePath, transactionId, call) {
|
|
85
79
|
return withWorkspace(
|
|
86
80
|
() => workspaceForPath(absolutePath),
|
|
87
|
-
({ workspaceId }) =>
|
|
88
|
-
invokeLectorVehicleOperation<
|
|
81
|
+
async ({ workspaceId }) => {
|
|
82
|
+
const lookup = await invokeLectorVehicleOperation<MutationTransactionLookupOutcome>(
|
|
83
|
+
"workspace.mutationTransaction",
|
|
84
|
+
{ workspaceId, transactionId },
|
|
85
|
+
MUTATION_HISTORY_READ_PERMISSIONS,
|
|
86
|
+
call,
|
|
87
|
+
);
|
|
88
|
+
if (lookup.status === "stale") return { status: "stale", transactionId, stalePaths: lookup.stalePaths };
|
|
89
|
+
if (lookup.status !== "ready") return lookup;
|
|
90
|
+
const reverted = await invokeLectorVehicleOperation<Omit<Extract<MutationTransactionRevertOutcome, { status: "reverted" }>, "status">>(
|
|
89
91
|
"workspace.revertMutationTransaction",
|
|
90
92
|
{ workspaceId, transactionId },
|
|
91
93
|
MUTATION_HISTORY_WRITE_PERMISSIONS,
|
|
92
94
|
call,
|
|
93
|
-
)
|
|
95
|
+
);
|
|
96
|
+
return { status: "reverted", ...reverted };
|
|
97
|
+
},
|
|
94
98
|
);
|
|
95
99
|
},
|
|
96
100
|
};
|
|
@@ -12,9 +12,23 @@ export function formatMutationHistoryList(entries: readonly MutationHistoryEntry
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function formatMutationTransactionRevert(originalTransactionId: string, outcome: MutationTransactionRevertOutcome): string {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
switch (outcome.status) {
|
|
16
|
+
case "reverted":
|
|
17
|
+
return [
|
|
18
|
+
`${originalTransactionId} reverted atomically; revert recorded as transaction ${outcome.transactionId}`,
|
|
19
|
+
...outcome.reverted.map((entry) => `${entry.path} -> ${entry.newHash ?? "(deleted)"}`),
|
|
20
|
+
].join("\n");
|
|
21
|
+
case "stale":
|
|
22
|
+
return `${originalTransactionId} is stale at ${outcome.stalePaths.length} path(s); no files were reverted\n${outcome.stalePaths.join("\n")}`;
|
|
23
|
+
case "evicted":
|
|
24
|
+
return `${originalTransactionId} cannot be reverted because its bounded process-local history was evicted`;
|
|
25
|
+
case "wrong-workspace":
|
|
26
|
+
return `${originalTransactionId} belongs to a different registered workspace; use a path from that workspace`;
|
|
27
|
+
case "unknown":
|
|
28
|
+
return `${originalTransactionId} is unknown; mutation history is process-local and is lost after daemon restart`;
|
|
29
|
+
default: {
|
|
30
|
+
const exhaustive: never = outcome;
|
|
31
|
+
return exhaustive;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danypops/pi-lector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Pi host adapter for Lector: overrides read/write/edit with a daemon-backed, hash-guarded filesystem",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@danypops/vehicle-client-pi": "^0.45.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@danypops/lector": "^0.
|
|
25
|
+
"@danypops/lector": "^0.23.0",
|
|
26
26
|
"@danypops/vehicle-client": "^0.10.8",
|
|
27
27
|
"@danypops/vehicle-core": "^0.19.1",
|
|
28
28
|
"malevich-tui-components": "^0.32.1",
|