@arden-hq/revisions 0.0.0-stage → 0.1.2
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/LICENSE +202 -0
- package/README.md +84 -2
- package/dist/domain/change-set.d.ts +34 -0
- package/dist/domain/change-set.d.ts.map +1 -0
- package/dist/domain/change-set.js +206 -0
- package/dist/domain/change-set.js.map +1 -0
- package/dist/domain/codec.d.ts +17 -0
- package/dist/domain/codec.d.ts.map +1 -0
- package/dist/domain/codec.js +188 -0
- package/dist/domain/codec.js.map +1 -0
- package/dist/domain/errors.d.ts +61 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/errors.js +44 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/format.d.ts +72 -0
- package/dist/domain/format.d.ts.map +1 -0
- package/dist/domain/format.js +93 -0
- package/dist/domain/format.js.map +1 -0
- package/dist/domain/integrity.d.ts +7 -0
- package/dist/domain/integrity.d.ts.map +1 -0
- package/dist/domain/integrity.js +100 -0
- package/dist/domain/integrity.js.map +1 -0
- package/dist/domain/model.d.ts +114 -0
- package/dist/domain/model.d.ts.map +1 -0
- package/dist/domain/model.js +145 -0
- package/dist/domain/model.js.map +1 -0
- package/dist/domain/query.d.ts +31 -0
- package/dist/domain/query.d.ts.map +1 -0
- package/dist/domain/query.js +168 -0
- package/dist/domain/query.js.map +1 -0
- package/dist/domain/transaction.d.ts +26 -0
- package/dist/domain/transaction.d.ts.map +1 -0
- package/dist/domain/transaction.js +93 -0
- package/dist/domain/transaction.js.map +1 -0
- package/dist/domain/tree.d.ts +6 -0
- package/dist/domain/tree.d.ts.map +1 -0
- package/dist/domain/tree.js +59 -0
- package/dist/domain/tree.js.map +1 -0
- package/dist/effect/index.d.ts +10 -0
- package/dist/effect/index.d.ts.map +1 -0
- package/dist/effect/index.js +4 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/repository/commit.d.ts +12 -0
- package/dist/repository/commit.d.ts.map +1 -0
- package/dist/repository/commit.js +164 -0
- package/dist/repository/commit.js.map +1 -0
- package/dist/repository/history.d.ts +21 -0
- package/dist/repository/history.d.ts.map +1 -0
- package/dist/repository/history.js +152 -0
- package/dist/repository/history.js.map +1 -0
- package/dist/repository/service.d.ts +114 -0
- package/dist/repository/service.d.ts.map +1 -0
- package/dist/repository/service.js +374 -0
- package/dist/repository/service.js.map +1 -0
- package/dist/repository/state.d.ts +27 -0
- package/dist/repository/state.d.ts.map +1 -0
- package/dist/repository/state.js +72 -0
- package/dist/repository/state.js.map +1 -0
- package/dist/repository/transaction.d.ts +27 -0
- package/dist/repository/transaction.d.ts.map +1 -0
- package/dist/repository/transaction.js +372 -0
- package/dist/repository/transaction.js.map +1 -0
- package/dist/storage/files.d.ts +17 -0
- package/dist/storage/files.d.ts.map +1 -0
- package/dist/storage/files.js +179 -0
- package/dist/storage/files.js.map +1 -0
- package/dist/storage/maintenance-adapter.d.ts +5 -0
- package/dist/storage/maintenance-adapter.d.ts.map +1 -0
- package/dist/storage/maintenance-adapter.js +177 -0
- package/dist/storage/maintenance-adapter.js.map +1 -0
- package/dist/storage/maintenance-reader.d.ts +17 -0
- package/dist/storage/maintenance-reader.d.ts.map +1 -0
- package/dist/storage/maintenance-reader.js +82 -0
- package/dist/storage/maintenance-reader.js.map +1 -0
- package/dist/storage/maintenance.d.ts +113 -0
- package/dist/storage/maintenance.d.ts.map +1 -0
- package/dist/storage/maintenance.js +445 -0
- package/dist/storage/maintenance.js.map +1 -0
- package/dist/storage/node.d.ts +7 -0
- package/dist/storage/node.d.ts.map +1 -0
- package/dist/storage/node.js +53 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/storage/service.d.ts +88 -0
- package/dist/storage/service.d.ts.map +1 -0
- package/dist/storage/service.js +506 -0
- package/dist/storage/service.js.map +1 -0
- package/package.json +63 -4
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { Clock, Effect, Result } from "effect";
|
|
2
|
+
import { Commit, ResourceVersion, normalizeRelativePath } from "../domain/model.js";
|
|
3
|
+
import { CorruptRepositoryError, InvalidRevisionInputError, RevisionStorageError, UnsafePathError } from "../domain/errors.js";
|
|
4
|
+
import {} from "../domain/format.js";
|
|
5
|
+
import { corrupt, makeReader, validHash } from "./maintenance-reader.js";
|
|
6
|
+
import { errorMessage } from "@arden-hq/std/errors";
|
|
7
|
+
import { compareCodePoints } from "@arden-hq/std/json";
|
|
8
|
+
import { sha256Hex } from "@arden-hq/std/hash";
|
|
9
|
+
const objectKinds = ["blob", "tree", "commit"];
|
|
10
|
+
const invalidInput = (message) => Effect.fail(new InvalidRevisionInputError({ message }));
|
|
11
|
+
const validateTransaction = Effect.fn("maintenance.validateTransaction")(function* (transaction) {
|
|
12
|
+
if (!validHash(transaction.transactionId) ||
|
|
13
|
+
!validHash(transaction.newHead) ||
|
|
14
|
+
(transaction.oldHead !== null && !validHash(transaction.oldHead)) ||
|
|
15
|
+
!validHash(transaction.treeId))
|
|
16
|
+
return yield* corrupt(`transaction ${transaction.transactionId} has invalid roots`);
|
|
17
|
+
let previousPath = null;
|
|
18
|
+
for (const [index, row] of transaction.rows.entries()) {
|
|
19
|
+
const normalized = yield* normalizeRelativePath(row.path).pipe(Effect.mapError((error) => new CorruptRepositoryError({
|
|
20
|
+
message: `transaction ${transaction.transactionId} row ${index} has an invalid path: ${errorMessage(error)}`
|
|
21
|
+
})));
|
|
22
|
+
if (normalized !== row.path ||
|
|
23
|
+
(previousPath !== null && compareCodePoints(previousPath, row.path) >= 0)) {
|
|
24
|
+
return yield* corrupt(`transaction ${transaction.transactionId} row ${index} is not ordered`);
|
|
25
|
+
}
|
|
26
|
+
if (row.oldBlob === null && row.newBlob === null) {
|
|
27
|
+
return yield* corrupt(`transaction ${transaction.transactionId} row ${index} makes no change`);
|
|
28
|
+
}
|
|
29
|
+
if ((row.oldBlob !== null && !validHash(row.oldBlob)) ||
|
|
30
|
+
(row.newBlob !== null && !validHash(row.newBlob))) {
|
|
31
|
+
return yield* corrupt(`transaction ${transaction.transactionId} row ${index} has an invalid blob`);
|
|
32
|
+
}
|
|
33
|
+
if (row.oldBlob === row.newBlob)
|
|
34
|
+
return yield* corrupt(`transaction ${transaction.transactionId} row ${index} makes no change`);
|
|
35
|
+
previousPath = row.path;
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
});
|
|
39
|
+
const jsonlStem = (filename) => filename.endsWith(".jsonl") ? filename.slice(0, -6) : "";
|
|
40
|
+
const objectIdFromFilenameUnsafe = (filename, jsonl) => {
|
|
41
|
+
const name = jsonl ? jsonlStem(filename) : filename;
|
|
42
|
+
if (!validHash(name))
|
|
43
|
+
throw new CorruptRepositoryError({ message: `object filename is invalid: ${filename}` });
|
|
44
|
+
return name;
|
|
45
|
+
};
|
|
46
|
+
const addResultIssue = (value, issues, target, code = "repository_corrupt") => {
|
|
47
|
+
if (Result.isSuccess(value))
|
|
48
|
+
return value.success;
|
|
49
|
+
issues.push({ code, target, detail: errorMessage(value.failure) });
|
|
50
|
+
return null;
|
|
51
|
+
};
|
|
52
|
+
const listObjectEntries = Effect.fn("maintenance.listObjectEntries")(function* (storage, kind, issues) {
|
|
53
|
+
const result = yield* Effect.result(storage.listObjects(kind));
|
|
54
|
+
return Result.isSuccess(result)
|
|
55
|
+
? result.success
|
|
56
|
+
: (issues.push({
|
|
57
|
+
code: "repository_corrupt",
|
|
58
|
+
target: kind,
|
|
59
|
+
detail: errorMessage(result.failure)
|
|
60
|
+
}),
|
|
61
|
+
[]);
|
|
62
|
+
});
|
|
63
|
+
const validateObjectEntryWithIssues = Effect.fn("maintenance.validateObjectEntryWithIssues")(function* (storage, reader, kind, entry, issues) {
|
|
64
|
+
const jsonl = kind !== "blob";
|
|
65
|
+
const parsed = yield* Effect.result(Effect.try({
|
|
66
|
+
try: () => objectIdFromFilenameUnsafe(entry.name, jsonl),
|
|
67
|
+
catch: (error) => error instanceof CorruptRepositoryError
|
|
68
|
+
? error
|
|
69
|
+
: new CorruptRepositoryError({ message: errorMessage(error) })
|
|
70
|
+
}));
|
|
71
|
+
if (Result.isFailure(parsed)) {
|
|
72
|
+
issues.push({
|
|
73
|
+
code: `${kind}_corrupt`,
|
|
74
|
+
target: entry.name,
|
|
75
|
+
detail: errorMessage(parsed.failure)
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const id = parsed.success;
|
|
80
|
+
const content = yield* Effect.result(storage.readObject(kind, id));
|
|
81
|
+
if (Result.isFailure(content)) {
|
|
82
|
+
issues.push({
|
|
83
|
+
code: `${kind}_corrupt`,
|
|
84
|
+
target: entry.name,
|
|
85
|
+
detail: errorMessage(content.failure)
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (sha256Hex(content.success) !== id) {
|
|
90
|
+
issues.push({
|
|
91
|
+
code: `${kind}_corrupt`,
|
|
92
|
+
target: entry.name,
|
|
93
|
+
detail: `${kind} hash mismatch: ${id}`
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (kind === "blob")
|
|
98
|
+
return;
|
|
99
|
+
const parse = kind === "tree" ? reader.tree(id) : reader.commit(id);
|
|
100
|
+
const parsedObject = yield* Effect.result(parse);
|
|
101
|
+
if (Result.isFailure(parsedObject)) {
|
|
102
|
+
issues.push({
|
|
103
|
+
code: `${kind}_corrupt`,
|
|
104
|
+
target: entry.name,
|
|
105
|
+
detail: errorMessage(parsedObject.failure)
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
/** Validate all immutable objects, reachable history, indexes, and materialized files. */
|
|
110
|
+
export const integrityReport = Effect.fn("integrityReport")(function* (storage) {
|
|
111
|
+
const issues = [];
|
|
112
|
+
const reader = makeReader(storage);
|
|
113
|
+
const entries = new Map();
|
|
114
|
+
let objectCount = 0;
|
|
115
|
+
for (const kind of objectKinds) {
|
|
116
|
+
const values = yield* listObjectEntries(storage, kind, issues);
|
|
117
|
+
entries.set(kind, values);
|
|
118
|
+
objectCount += values.length;
|
|
119
|
+
for (const entry of values) {
|
|
120
|
+
yield* validateObjectEntryWithIssues(storage, reader, kind, entry, issues);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const headResult = yield* Effect.result(storage.readRef);
|
|
124
|
+
const rawHead = addResultIssue(headResult, issues, "current-ref");
|
|
125
|
+
const head = rawHead;
|
|
126
|
+
const publishedResult = yield* Effect.result(storage.listPublished);
|
|
127
|
+
const publishedIds = new Set();
|
|
128
|
+
const published = addResultIssue(publishedResult, issues, "published", "publication_corrupt");
|
|
129
|
+
if (published !== null) {
|
|
130
|
+
for (const marker of published) {
|
|
131
|
+
if (!validHash(marker.commitId)) {
|
|
132
|
+
issues.push({
|
|
133
|
+
code: "publication_corrupt",
|
|
134
|
+
target: marker.commitId,
|
|
135
|
+
detail: "published commit marker is invalid"
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
publishedIds.add(marker.commitId);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
let resources = new Map();
|
|
144
|
+
const reachableCommits = new Set();
|
|
145
|
+
if (head !== null && validHash(head)) {
|
|
146
|
+
if (published !== null && !publishedIds.has(head)) {
|
|
147
|
+
issues.push({
|
|
148
|
+
code: "repository_corrupt",
|
|
149
|
+
target: head,
|
|
150
|
+
detail: "current ref points to an unpublished commit"
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
let cursor = head;
|
|
154
|
+
while (cursor !== null) {
|
|
155
|
+
if (reachableCommits.has(cursor)) {
|
|
156
|
+
issues.push({
|
|
157
|
+
code: "repository_corrupt",
|
|
158
|
+
target: cursor,
|
|
159
|
+
detail: `commit history contains a cycle at ${cursor}`
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
reachableCommits.add(cursor);
|
|
164
|
+
const commitResult = yield* Effect.result(reader.commit(cursor));
|
|
165
|
+
if (Result.isFailure(commitResult)) {
|
|
166
|
+
issues.push({
|
|
167
|
+
code: "repository_corrupt",
|
|
168
|
+
target: cursor,
|
|
169
|
+
detail: errorMessage(commitResult.failure)
|
|
170
|
+
});
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
const transitionResult = yield* Effect.result(reader.transition(commitResult.success));
|
|
174
|
+
if (Result.isFailure(transitionResult)) {
|
|
175
|
+
issues.push({
|
|
176
|
+
code: "repository_corrupt",
|
|
177
|
+
target: cursor,
|
|
178
|
+
detail: errorMessage(transitionResult.failure)
|
|
179
|
+
});
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
if (cursor === head)
|
|
183
|
+
resources = new Map(transitionResult.success);
|
|
184
|
+
cursor = commitResult.success.parentId;
|
|
185
|
+
}
|
|
186
|
+
for (const resource of resources.values()) {
|
|
187
|
+
if (resource.state !== "active")
|
|
188
|
+
continue;
|
|
189
|
+
const working = yield* Effect.result(storage.readWorking(resource.path));
|
|
190
|
+
if (Result.isFailure(working)) {
|
|
191
|
+
issues.push({
|
|
192
|
+
code: "repository_corrupt",
|
|
193
|
+
target: resource.path,
|
|
194
|
+
detail: errorMessage(working.failure)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
const actual = working.success === null ? null : sha256Hex(working.success);
|
|
199
|
+
if (actual !== resource.blobId) {
|
|
200
|
+
issues.push({
|
|
201
|
+
code: "managed_file_mismatch",
|
|
202
|
+
target: resource.path,
|
|
203
|
+
detail: `working file changed: ${resource.path}`
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (head !== null) {
|
|
210
|
+
issues.push({
|
|
211
|
+
code: "repository_corrupt",
|
|
212
|
+
target: "current-ref",
|
|
213
|
+
detail: "current ref has an invalid commit identifier"
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (published !== null) {
|
|
217
|
+
for (const commitId of [...reachableCommits].sort(compareCodePoints)) {
|
|
218
|
+
if (!publishedIds.has(commitId)) {
|
|
219
|
+
issues.push({
|
|
220
|
+
code: "publication_missing",
|
|
221
|
+
target: commitId,
|
|
222
|
+
detail: "reachable commit lacks its publication certificate"
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
for (const commitId of [...publishedIds].sort(compareCodePoints)) {
|
|
227
|
+
if (!reachableCommits.has(commitId)) {
|
|
228
|
+
issues.push({
|
|
229
|
+
code: "publication_corrupt",
|
|
230
|
+
target: commitId,
|
|
231
|
+
detail: "published commit marker points outside current history"
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const idempotencyResult = yield* Effect.result(storage.listIdempotency);
|
|
237
|
+
const idempotency = addResultIssue(idempotencyResult, issues, "idempotency", "idempotency_corrupt");
|
|
238
|
+
if (idempotency !== null) {
|
|
239
|
+
for (const record of idempotency) {
|
|
240
|
+
if (!validHash(record.keyHash) ||
|
|
241
|
+
!validHash(record.requestHash) ||
|
|
242
|
+
!validHash(record.commitId)) {
|
|
243
|
+
issues.push({
|
|
244
|
+
code: "idempotency_corrupt",
|
|
245
|
+
target: record.keyHash,
|
|
246
|
+
detail: "idempotency record has invalid identifiers"
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
else if (!reachableCommits.has(record.commitId)) {
|
|
250
|
+
issues.push({
|
|
251
|
+
code: "idempotency_corrupt",
|
|
252
|
+
target: record.keyHash,
|
|
253
|
+
detail: "idempotency record points outside published history"
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const transactionsResult = yield* Effect.result(storage.listProtectedTransactions);
|
|
259
|
+
const transactions = addResultIssue(transactionsResult, issues, "transactions", "recovery_corrupt");
|
|
260
|
+
if (transactions !== null) {
|
|
261
|
+
for (const transaction of transactions) {
|
|
262
|
+
const checked = yield* Effect.result(validateTransaction(transaction));
|
|
263
|
+
if (Result.isFailure(checked)) {
|
|
264
|
+
issues.push({
|
|
265
|
+
code: "recovery_corrupt",
|
|
266
|
+
target: transaction.transactionId,
|
|
267
|
+
detail: errorMessage(checked.failure)
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
else if (transaction.conflicted === true) {
|
|
271
|
+
issues.push({
|
|
272
|
+
code: "recovery_conflict",
|
|
273
|
+
target: transaction.transactionId,
|
|
274
|
+
detail: "an external write prevented automatic rollback"
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
ok: issues.length === 0,
|
|
281
|
+
headCommit: head,
|
|
282
|
+
resources: resources.size,
|
|
283
|
+
objects: objectCount,
|
|
284
|
+
issues
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
const countResources = (resources) => {
|
|
288
|
+
if (typeof resources === "number")
|
|
289
|
+
return resources;
|
|
290
|
+
return "size" in resources ? resources.size : resources.length;
|
|
291
|
+
};
|
|
292
|
+
/** Account immutable objects and metadata bytes without reading object contents. */
|
|
293
|
+
export const storageReport = Effect.fn("storageReport")(function* (storage, resources = 0) {
|
|
294
|
+
const values = {
|
|
295
|
+
blob: yield* storage.listObjects("blob"),
|
|
296
|
+
tree: yield* storage.listObjects("tree"),
|
|
297
|
+
commit: yield* storage.listObjects("commit")
|
|
298
|
+
};
|
|
299
|
+
const metadata = yield* storage.metadataStats;
|
|
300
|
+
if (metadata.lockBytes === null)
|
|
301
|
+
return yield* corrupt("repository lock disappeared during storage reporting");
|
|
302
|
+
const allStats = [
|
|
303
|
+
metadata.transactionBytes,
|
|
304
|
+
metadata.conflictBytes,
|
|
305
|
+
metadata.idempotencyBytes,
|
|
306
|
+
metadata.publicationBytes,
|
|
307
|
+
metadata.refBytes,
|
|
308
|
+
metadata.lockBytes
|
|
309
|
+
];
|
|
310
|
+
if (allStats.some((value) => !Number.isSafeInteger(value) || value < 0)) {
|
|
311
|
+
return yield* corrupt("storage metadata contains an invalid byte count");
|
|
312
|
+
}
|
|
313
|
+
const bytes = (kind) => values[kind].reduce((total, entry) => total + entry.byteSize, 0);
|
|
314
|
+
const blobBytes = bytes("blob");
|
|
315
|
+
const treeBytes = bytes("tree");
|
|
316
|
+
const commitBytes = bytes("commit");
|
|
317
|
+
const recoveryBytes = metadata.transactionBytes + metadata.conflictBytes;
|
|
318
|
+
const metadataBytes = metadata.idempotencyBytes + metadata.publicationBytes + metadata.refBytes + metadata.lockBytes;
|
|
319
|
+
const resourceCount = countResources(resources);
|
|
320
|
+
return {
|
|
321
|
+
totalBytes: blobBytes + treeBytes + commitBytes + recoveryBytes + metadataBytes,
|
|
322
|
+
blobBytes,
|
|
323
|
+
treeBytes,
|
|
324
|
+
commitBytes,
|
|
325
|
+
recoveryBytes,
|
|
326
|
+
metadataBytes,
|
|
327
|
+
resourceCount,
|
|
328
|
+
commitCount: values.commit.length,
|
|
329
|
+
objectCount: objectKinds.reduce((total, kind) => total + values[kind].length, 0)
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
const collectionRoots = Effect.fn("collectionRoots")(function* (storage) {
|
|
333
|
+
const published = yield* storage.listPublished;
|
|
334
|
+
const publishedIds = new Set();
|
|
335
|
+
for (const marker of published) {
|
|
336
|
+
if (!validHash(marker.commitId))
|
|
337
|
+
return yield* corrupt(`published commit marker is invalid: ${marker.commitId}`);
|
|
338
|
+
publishedIds.add(marker.commitId);
|
|
339
|
+
}
|
|
340
|
+
const current = yield* storage.readRef;
|
|
341
|
+
const commitRoots = new Set();
|
|
342
|
+
if (current !== null) {
|
|
343
|
+
if (!validHash(current))
|
|
344
|
+
return yield* corrupt("current ref has an invalid commit identifier");
|
|
345
|
+
if (!publishedIds.has(current))
|
|
346
|
+
return yield* corrupt(`current ref points to unpublished commit: ${current}`);
|
|
347
|
+
commitRoots.add(current);
|
|
348
|
+
}
|
|
349
|
+
const transactions = yield* storage.listProtectedTransactions;
|
|
350
|
+
for (const transaction of transactions) {
|
|
351
|
+
yield* validateTransaction(transaction);
|
|
352
|
+
commitRoots.add(transaction.newHead);
|
|
353
|
+
if (transaction.oldHead !== null)
|
|
354
|
+
commitRoots.add(transaction.oldHead);
|
|
355
|
+
}
|
|
356
|
+
const idempotency = yield* storage.listIdempotency;
|
|
357
|
+
for (const record of idempotency) {
|
|
358
|
+
if (!validHash(record.keyHash) ||
|
|
359
|
+
!validHash(record.requestHash) ||
|
|
360
|
+
!validHash(record.commitId)) {
|
|
361
|
+
return yield* corrupt(`idempotency record ${record.keyHash} has invalid identifiers`);
|
|
362
|
+
}
|
|
363
|
+
commitRoots.add(record.commitId);
|
|
364
|
+
}
|
|
365
|
+
const reader = makeReader(storage);
|
|
366
|
+
const commits = new Set();
|
|
367
|
+
const trees = new Set();
|
|
368
|
+
const blobs = new Set();
|
|
369
|
+
const pending = [...commitRoots];
|
|
370
|
+
for (let commitId = pending.pop(); commitId !== undefined; commitId = pending.pop()) {
|
|
371
|
+
if (commits.has(commitId))
|
|
372
|
+
continue;
|
|
373
|
+
const parsed = yield* reader.commit(commitId);
|
|
374
|
+
commits.add(commitId);
|
|
375
|
+
const closure = yield* reader.treeClosure(parsed.treeId);
|
|
376
|
+
for (const treeId of closure)
|
|
377
|
+
trees.add(treeId);
|
|
378
|
+
const resources = yield* reader.transition(parsed);
|
|
379
|
+
for (const resource of resources.values()) {
|
|
380
|
+
yield* reader.verifyBlob(resource.blobId);
|
|
381
|
+
blobs.add(resource.blobId);
|
|
382
|
+
}
|
|
383
|
+
if (parsed.parentId !== null)
|
|
384
|
+
pending.push(parsed.parentId);
|
|
385
|
+
}
|
|
386
|
+
for (const transaction of transactions) {
|
|
387
|
+
const closure = yield* reader.treeClosure(transaction.treeId);
|
|
388
|
+
for (const treeId of closure)
|
|
389
|
+
trees.add(treeId);
|
|
390
|
+
for (const row of transaction.rows) {
|
|
391
|
+
if (row.oldBlob !== null)
|
|
392
|
+
blobs.add(row.oldBlob);
|
|
393
|
+
if (row.newBlob !== null)
|
|
394
|
+
blobs.add(row.newBlob);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return { commits, trees, blobs };
|
|
398
|
+
});
|
|
399
|
+
const isCollectionRoots = (value) => "commits" in value && "trees" in value && "blobs" in value;
|
|
400
|
+
const collectEffect = Effect.fn("collect")(function* (storage, input = undefined, explicitCutoffMillis) {
|
|
401
|
+
const roots = input !== undefined && isCollectionRoots(input)
|
|
402
|
+
? input
|
|
403
|
+
: (input?.roots ?? (yield* collectionRoots(storage)));
|
|
404
|
+
const options = input !== undefined && !isCollectionRoots(input) ? input : undefined;
|
|
405
|
+
const nowMillis = options?.nowMillis ??
|
|
406
|
+
(explicitCutoffMillis !== undefined ? explicitCutoffMillis : yield* Clock.currentTimeMillis);
|
|
407
|
+
const gracePeriodMs = options?.gracePeriodMs ?? 30 * 24 * 60 * 60 * 1000;
|
|
408
|
+
const cutoffMillis = explicitCutoffMillis ?? options?.cutoffMillis ?? nowMillis - gracePeriodMs;
|
|
409
|
+
if (!Number.isFinite(nowMillis) || !Number.isFinite(cutoffMillis)) {
|
|
410
|
+
return yield* invalidInput("collection clock values must be finite");
|
|
411
|
+
}
|
|
412
|
+
if (!Number.isFinite(gracePeriodMs) || gracePeriodMs < 0) {
|
|
413
|
+
return yield* invalidInput("gracePeriodMs must not be negative");
|
|
414
|
+
}
|
|
415
|
+
let scanned = 0;
|
|
416
|
+
let removed = 0;
|
|
417
|
+
let retained = 0;
|
|
418
|
+
let bytesRemoved = 0;
|
|
419
|
+
const reachableByKind = {
|
|
420
|
+
blob: roots.blobs,
|
|
421
|
+
tree: roots.trees,
|
|
422
|
+
commit: roots.commits
|
|
423
|
+
};
|
|
424
|
+
for (const kind of objectKinds) {
|
|
425
|
+
const entries = yield* storage.listObjects(kind);
|
|
426
|
+
for (const entry of entries) {
|
|
427
|
+
const id = objectIdFromFilenameUnsafe(entry.name, kind !== "blob");
|
|
428
|
+
scanned += 1;
|
|
429
|
+
if (reachableByKind[kind].has(id) || entry.modifiedAtMillis > cutoffMillis) {
|
|
430
|
+
retained += 1;
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
const content = yield* storage.readObject(kind, id);
|
|
434
|
+
if (sha256Hex(content) !== id)
|
|
435
|
+
return yield* corrupt(`unreachable object is corrupt: ${entry.name}`);
|
|
436
|
+
yield* storage.removeObject(kind, id);
|
|
437
|
+
removed += 1;
|
|
438
|
+
bytesRemoved += entry.byteSize;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return { scanned, removed, retained, bytesRemoved };
|
|
442
|
+
});
|
|
443
|
+
/** Collect unreachable immutable objects after the configured grace period. */
|
|
444
|
+
export const collect = (storage, input, cutoffMillis) => collectEffect(storage, input, cutoffMillis);
|
|
445
|
+
//# sourceMappingURL=maintenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../../src/storage/maintenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
import { ManagedFileRepository } from "../repository/service.js";
|
|
3
|
+
import type { ManagedFileRepositoryOptions as RepositoryOptions } from "../repository/service.js";
|
|
4
|
+
import type { RepositoryError } from "../repository/service.js";
|
|
5
|
+
/** Node/Electron layer for the complete durable repository service. */
|
|
6
|
+
export declare const managedFileRepositoryNodeLayer: (options: RepositoryOptions) => Layer.Layer<ManagedFileRepository, RepositoryError>;
|
|
7
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/storage/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAA;AAKhD,OAAO,EAA8B,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAC5F,OAAO,KAAK,EAAE,4BAA4B,IAAI,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AA2D/D,uEAAuE;AACvE,eAAO,MAAM,8BAA8B,YAChC,iBAAiB,KACzB,KAAK,CAAC,KAAK,CAAC,qBAAqB,EAAE,eAAe,CAQlD,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Deferred, Effect, Layer } from "effect";
|
|
2
|
+
import { NodeFileSystem, NodePath } from "@effect/platform-node";
|
|
3
|
+
import * as properLockfile from "proper-lockfile";
|
|
4
|
+
import { RevisionLockFactory } from "./service.js";
|
|
5
|
+
import { managedFileRepositoryLayer, ManagedFileRepository } from "../repository/service.js";
|
|
6
|
+
import { RevisionConflictError, RevisionStorageError } from "../domain/errors.js";
|
|
7
|
+
import { errorMessage } from "@arden-hq/std/errors";
|
|
8
|
+
const lockFailure = (operation, cause) => {
|
|
9
|
+
const code = typeof cause === "object" && cause !== null && "code" in cause
|
|
10
|
+
? cause.code
|
|
11
|
+
: undefined;
|
|
12
|
+
if (code === "ELOCKED")
|
|
13
|
+
return new RevisionConflictError({ message: "repository is already locked" });
|
|
14
|
+
return new RevisionStorageError({
|
|
15
|
+
message: `${operation}: ${errorMessage(cause)}`,
|
|
16
|
+
cause
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const nodeLockFactory = {
|
|
20
|
+
acquire: Effect.fn("NodeRevisionLock.acquire")(function* (lockPath, staleAfterMs) {
|
|
21
|
+
const lost = Deferred.makeUnsafe();
|
|
22
|
+
const releaseNative = yield* Effect.tryPromise({
|
|
23
|
+
try: () => properLockfile.lock(lockPath, {
|
|
24
|
+
stale: staleAfterMs,
|
|
25
|
+
realpath: false,
|
|
26
|
+
onCompromised: (cause) => {
|
|
27
|
+
Effect.runSync(Deferred.fail(lost, new RevisionStorageError({
|
|
28
|
+
message: `repository lock compromised: ${cause.message}`,
|
|
29
|
+
cause
|
|
30
|
+
})));
|
|
31
|
+
}
|
|
32
|
+
}),
|
|
33
|
+
catch: (cause) => lockFailure("acquire repository lock", cause)
|
|
34
|
+
});
|
|
35
|
+
let released = false;
|
|
36
|
+
const release = Effect.gen(function* () {
|
|
37
|
+
if (released)
|
|
38
|
+
return;
|
|
39
|
+
released = true;
|
|
40
|
+
yield* Effect.tryPromise({
|
|
41
|
+
try: () => releaseNative(),
|
|
42
|
+
catch: (cause) => new RevisionStorageError({
|
|
43
|
+
message: `release repository lock: ${errorMessage(cause)}`,
|
|
44
|
+
cause
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return { release, lost: Deferred.await(lost) };
|
|
49
|
+
})
|
|
50
|
+
};
|
|
51
|
+
/** Node/Electron layer for the complete durable repository service. */
|
|
52
|
+
export const managedFileRepositoryNodeLayer = (options) => Layer.provide(managedFileRepositoryLayer(options), Layer.mergeAll(NodeFileSystem.layer, NodePath.layer, Layer.succeed(RevisionLockFactory, nodeLockFactory)));
|
|
53
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/storage/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Context, Effect, FileSystem, Layer, Path } from "effect";
|
|
2
|
+
import { RevisionConflictError, RevisionStorageError, UnsafePathError } from "../domain/errors.js";
|
|
3
|
+
/** Filesystem roots used by a repository. Both paths may be relative. */
|
|
4
|
+
export interface RevisionLockFactoryShape {
|
|
5
|
+
readonly acquire: (lockPath: string, staleAfterMs: number) => Effect.Effect<RevisionLock, RevisionStorageError | RevisionConflictError>;
|
|
6
|
+
}
|
|
7
|
+
export interface RevisionStorageOptions {
|
|
8
|
+
readonly workingRoot: string;
|
|
9
|
+
readonly historyRoot?: string;
|
|
10
|
+
/** Lock age after which a crashed process may be reclaimed. Defaults to 10 minutes. */
|
|
11
|
+
readonly lockStaleAfterMs?: number;
|
|
12
|
+
}
|
|
13
|
+
interface RevisionLock {
|
|
14
|
+
readonly release: Effect.Effect<void, RevisionStorageError>;
|
|
15
|
+
readonly lost: Effect.Effect<never, RevisionStorageError>;
|
|
16
|
+
}
|
|
17
|
+
declare const RevisionLockFactory_base: Context.ServiceClass<RevisionLockFactory, "@arden-hq/revisions/RevisionLockFactory", RevisionLockFactoryShape>;
|
|
18
|
+
/** Platform lock service. The core layer requires an implementation. */
|
|
19
|
+
export declare class RevisionLockFactory extends RevisionLockFactory_base {
|
|
20
|
+
}
|
|
21
|
+
export type StorageError = RevisionStorageError | RevisionConflictError | UnsafePathError;
|
|
22
|
+
type RevisionObjectKind = "blob" | "tree" | "commit";
|
|
23
|
+
interface RevisionMetadataStat {
|
|
24
|
+
readonly size: number;
|
|
25
|
+
readonly mtimeMillis: number | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Durable filesystem operations used by the repository.
|
|
29
|
+
*
|
|
30
|
+
* This interface depends only on Effect's `FileSystem` and `Path` services.
|
|
31
|
+
* The Node implementation is deliberately kept in `./node.ts`, so the core
|
|
32
|
+
* remains injectable in tests and can be given a desktop-specific adapter.
|
|
33
|
+
*/
|
|
34
|
+
export interface RevisionStorageShape {
|
|
35
|
+
readonly workingRoot: string;
|
|
36
|
+
readonly historyRoot: string;
|
|
37
|
+
readonly initialize: Effect.Effect<void, StorageError>;
|
|
38
|
+
/**
|
|
39
|
+
* Run `operation` holding the on-disk repository lock. Acquisition is
|
|
40
|
+
* uninterruptible and the release is registered with it, so an interrupted
|
|
41
|
+
* caller never leaves the lock held (a leaked lock keeps its heartbeat and
|
|
42
|
+
* refuses every later open in the process). Losing the lock fails `operation`.
|
|
43
|
+
*/
|
|
44
|
+
readonly withLock: <A, E>(operation: Effect.Effect<A, E>) => Effect.Effect<A, E | StorageError>;
|
|
45
|
+
readonly readBlob: (blobId: string) => Effect.Effect<Uint8Array, StorageError>;
|
|
46
|
+
readonly writeBlob: (content: Uint8Array) => Effect.Effect<string, StorageError>;
|
|
47
|
+
readonly readTree: (treeId: string) => Effect.Effect<Uint8Array, StorageError>;
|
|
48
|
+
readonly writeTree: (content: Uint8Array) => Effect.Effect<string, StorageError>;
|
|
49
|
+
readonly readCommit: (commitId: string) => Effect.Effect<Uint8Array, StorageError>;
|
|
50
|
+
readonly writeCommit: (content: Uint8Array) => Effect.Effect<string, StorageError>;
|
|
51
|
+
readonly blobSize: (blobId: string) => Effect.Effect<number, StorageError>;
|
|
52
|
+
readonly commitSize: (commitId: string) => Effect.Effect<number, StorageError>;
|
|
53
|
+
readonly listObjectIds: (kind: RevisionObjectKind) => Effect.Effect<ReadonlyArray<string>, StorageError>;
|
|
54
|
+
readonly removeObject: (kind: RevisionObjectKind, id: string, missingOk?: boolean) => Effect.Effect<void, StorageError>;
|
|
55
|
+
readonly listPublished: Effect.Effect<ReadonlyArray<string>, StorageError>;
|
|
56
|
+
readonly removePublished: (commitId: string, missingOk?: boolean) => Effect.Effect<void, StorageError>;
|
|
57
|
+
readonly metadataStat: (relativePath: string) => Effect.Effect<RevisionMetadataStat | null, StorageError>;
|
|
58
|
+
readonly removeMetadataFile: (relativePath: string, missingOk?: boolean) => Effect.Effect<void, StorageError>;
|
|
59
|
+
/** Remove crash-orphaned atomic-write temporaries under one metadata
|
|
60
|
+
* directory (`"."` for the whole history root). A missing directory has none. */
|
|
61
|
+
readonly cleanupMetadataTemps: (relativeDirectory: string) => Effect.Effect<void, StorageError>;
|
|
62
|
+
readonly readRef: Effect.Effect<string | null, StorageError>;
|
|
63
|
+
readonly compareAndSwapRef: (expected: string | null, replacement: string | null) => Effect.Effect<void, StorageError>;
|
|
64
|
+
readonly compensateRef: (expected: string, replacement: string | null) => Effect.Effect<void, StorageError>;
|
|
65
|
+
readonly readIdempotency: (keyHash: string) => Effect.Effect<Uint8Array | null, StorageError>;
|
|
66
|
+
readonly writeIdempotency: (keyHash: string, content: Uint8Array) => Effect.Effect<void, StorageError>;
|
|
67
|
+
readonly isPublished: (commitId: string) => Effect.Effect<boolean, StorageError>;
|
|
68
|
+
readonly publish: (commitId: string) => Effect.Effect<void, StorageError>;
|
|
69
|
+
readonly listMetadata: (relativePath: string) => Effect.Effect<ReadonlyArray<string>, StorageError>;
|
|
70
|
+
readonly metadataExists: (relativePath: string) => Effect.Effect<boolean, StorageError>;
|
|
71
|
+
readonly readMetadata: (relativePath: string, allowMissing?: boolean) => Effect.Effect<Uint8Array | null, StorageError>;
|
|
72
|
+
readonly writeMetadata: (relativePath: string, content: Uint8Array, noReplace?: boolean) => Effect.Effect<void, StorageError>;
|
|
73
|
+
readonly ensureMetadataDirectory: (relativePath: string) => Effect.Effect<void, StorageError>;
|
|
74
|
+
readonly removeMetadataTree: (relativePath: string) => Effect.Effect<void, StorageError>;
|
|
75
|
+
readonly renameMetadataDirectory: (source: string, target: string) => Effect.Effect<void, StorageError>;
|
|
76
|
+
readonly readWorking: (relativePath: string, allowMissing?: boolean, requireStandalone?: boolean) => Effect.Effect<Uint8Array | null, StorageError>;
|
|
77
|
+
readonly writeWorking: (relativePath: string, content: Uint8Array, noReplace?: boolean) => Effect.Effect<void, StorageError>;
|
|
78
|
+
readonly removeWorking: (relativePath: string, missingOk?: boolean) => Effect.Effect<void, StorageError>;
|
|
79
|
+
readonly moveWorkingToMetadata: (workingPath: string, metadataPath: string) => Effect.Effect<void, StorageError>;
|
|
80
|
+
readonly syncMetadataDirectory: (relativePath: string) => Effect.Effect<void, StorageError>;
|
|
81
|
+
}
|
|
82
|
+
declare const RevisionStorage_base: Context.ServiceClass<RevisionStorage, "@arden-hq/revisions/RevisionStorage", RevisionStorageShape>;
|
|
83
|
+
export declare class RevisionStorage extends RevisionStorage_base {
|
|
84
|
+
}
|
|
85
|
+
/** Core layer: requires Effect `FileSystem`, `Path`, and an explicit lock factory; it has no Node imports. */
|
|
86
|
+
export declare const revisionStorageLayer: (options: RevisionStorageOptions) => Layer.Layer<RevisionStorage, StorageError, FileSystem.FileSystem | Path.Path | RevisionLockFactory>;
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/storage/service.ts"],"names":[],"mappings":"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"}
|