@cyanmycelium/mcp-persistence 0.0.0-stage → 0.1.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/LICENSE +201 -0
- package/README.md +183 -2
- package/contracts/persistence.v1.json +9606 -0
- package/dist/conformance/persistence.conformance.d.ts +4 -0
- package/dist/conformance/persistence.conformance.js +56 -0
- package/dist/conformance/persistence.conformance.js.map +1 -0
- package/dist/contract/errors.d.ts +5 -0
- package/dist/contract/errors.js +9 -0
- package/dist/contract/errors.js.map +1 -0
- package/dist/contract/persistence.protocol.d.ts +83 -0
- package/dist/contract/persistence.protocol.js +75 -0
- package/dist/contract/persistence.protocol.js.map +1 -0
- package/dist/contract/persistence.store.d.ts +29 -0
- package/dist/contract/persistence.store.js +2 -0
- package/dist/contract/persistence.store.js.map +1 -0
- package/dist/contract/persistence.types.d.ts +115 -0
- package/dist/contract/persistence.types.js +2 -0
- package/dist/contract/persistence.types.js.map +1 -0
- package/dist/contract/validation.d.ts +7 -0
- package/dist/contract/validation.js +43 -0
- package/dist/contract/validation.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/provider/artifact.http.d.ts +8 -0
- package/dist/provider/artifact.http.js +69 -0
- package/dist/provider/artifact.http.js.map +1 -0
- package/dist/provider/main.d.ts +2 -0
- package/dist/provider/main.js +82 -0
- package/dist/provider/main.js.map +1 -0
- package/dist/server/declaration.d.ts +18 -0
- package/dist/server/declaration.js +23 -0
- package/dist/server/declaration.js.map +1 -0
- package/dist/server/persistence.behavior.d.ts +16 -0
- package/dist/server/persistence.behavior.js +173 -0
- package/dist/server/persistence.behavior.js.map +1 -0
- package/dist/server/persistence.slot.store.d.ts +45 -0
- package/dist/server/persistence.slot.store.js +94 -0
- package/dist/server/persistence.slot.store.js.map +1 -0
- package/dist/sqlite/sqlite.persistence.store.d.ts +72 -0
- package/dist/sqlite/sqlite.persistence.store.js +561 -0
- package/dist/sqlite/sqlite.persistence.store.js.map +1 -0
- package/docs/assets/logo.png +0 -0
- package/docs/assets/mcp-broker-family.png +0 -0
- package/docs/mcp-contract.md +189 -0
- package/package.json +81 -6
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { createCipheriv, createDecipheriv, createHash, randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
4
|
+
import { createReadStream } from "node:fs";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { canonical, digest, fail, integer, segment, text } from "../contract/validation.js";
|
|
7
|
+
import { PersistenceError } from "../contract/errors.js";
|
|
8
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
9
|
+
const DAY = 86_400_000;
|
|
10
|
+
const DEFAULTS = { maxDocumentBytes: 1_048_576, maxArtifactBytes: 10 * 1024 ** 3, maxReferences: 256, maxPageSize: 200, maxNamespaceBytes: 100 * 1024 ** 3, idempotencyRetentionSeconds: 7 * 86400 };
|
|
11
|
+
/** One provider process owns one local data root. SQLite serializes all metadata mutations. */
|
|
12
|
+
export class SqlitePersistenceStore {
|
|
13
|
+
id = "sqlite-files";
|
|
14
|
+
directory;
|
|
15
|
+
db;
|
|
16
|
+
limits;
|
|
17
|
+
cursorKey;
|
|
18
|
+
retentionMs;
|
|
19
|
+
fileSyncOnly;
|
|
20
|
+
active = new Set();
|
|
21
|
+
readers = new Map();
|
|
22
|
+
closed = false;
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.limits = { ...DEFAULTS, ...options.limits };
|
|
25
|
+
for (const value of Object.values(this.limits))
|
|
26
|
+
integer(value, 1);
|
|
27
|
+
if (this.limits.maxPageSize > 200 || this.limits.maxReferences > 256)
|
|
28
|
+
fail("invalid_request", "Page and reference limits exceed persistence.v1 protocol ceilings");
|
|
29
|
+
if (this.limits.idempotencyRetentionSeconds < 7 * 86400)
|
|
30
|
+
fail("invalid_request", "Idempotency retention must be at least seven days");
|
|
31
|
+
this.retentionMs = options.retentionMs === undefined ? Infinity : integer(options.retentionMs);
|
|
32
|
+
this.fileSyncOnly = options.allowFileSyncOnly === true;
|
|
33
|
+
if (process.platform === "win32" && !this.fileSyncOnly)
|
|
34
|
+
fail("unsupported_format", "Windows requires explicit allowFileSyncOnly; directory synchronization is unavailable");
|
|
35
|
+
const dir = resolve(options.directory);
|
|
36
|
+
mkdirSync(dir, { recursive: true });
|
|
37
|
+
if (lstatSync(dir).isSymbolicLink() || realpathSync(dir).toLowerCase() !== dir.toLowerCase())
|
|
38
|
+
fail("invalid_request", "Storage root must be a canonical local directory");
|
|
39
|
+
this.directory = dir;
|
|
40
|
+
for (const sub of ["staging", "artifacts"]) {
|
|
41
|
+
mkdirSync(join(dir, sub), { recursive: true });
|
|
42
|
+
this.safe(sub);
|
|
43
|
+
}
|
|
44
|
+
for (const f of ["store.sqlite", "store.sqlite-wal", "store.sqlite-shm", "cursor.key", "writer.lock"])
|
|
45
|
+
if (existsSync(join(dir, f)))
|
|
46
|
+
this.safe(f);
|
|
47
|
+
const lock = join(dir, "writer.lock");
|
|
48
|
+
if (existsSync(lock)) {
|
|
49
|
+
const pid = Number(readFileSync(lock, "utf8"));
|
|
50
|
+
if (!Number.isSafeInteger(pid) || pid < 1)
|
|
51
|
+
fail("busy", "Storage lock needs operator inspection");
|
|
52
|
+
try {
|
|
53
|
+
process.kill(pid, 0);
|
|
54
|
+
fail("busy", "Data root already has a writer");
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error.code !== "ESRCH")
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
unlinkSync(lock);
|
|
61
|
+
}
|
|
62
|
+
writeFileSync(lock, String(process.pid), { flag: "wx", mode: 0o600 });
|
|
63
|
+
let opened;
|
|
64
|
+
try {
|
|
65
|
+
opened = new DatabaseSync(join(dir, "store.sqlite"));
|
|
66
|
+
this.db = opened;
|
|
67
|
+
this.db.exec("PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA foreign_keys=ON; PRAGMA busy_timeout=5000;");
|
|
68
|
+
const version = Number(this.db.prepare("PRAGMA user_version").get().user_version);
|
|
69
|
+
if (version > 2)
|
|
70
|
+
fail("unsupported_format", "Database schema is newer than this service");
|
|
71
|
+
this.db.exec(`BEGIN IMMEDIATE;
|
|
72
|
+
CREATE TABLE IF NOT EXISTS revisions(ns TEXT NOT NULL,id TEXT NOT NULL,rev INTEGER NOT NULL,json TEXT NOT NULL,bytes INTEGER NOT NULL,PRIMARY KEY(ns,id,rev));
|
|
73
|
+
CREATE TABLE IF NOT EXISTS heads(ns TEXT NOT NULL,id TEXT NOT NULL,rev INTEGER NOT NULL,PRIMARY KEY(ns,id),FOREIGN KEY(ns,id,rev) REFERENCES revisions(ns,id,rev));
|
|
74
|
+
CREATE TABLE IF NOT EXISTS refs(ns TEXT NOT NULL,id TEXT NOT NULL,rev INTEGER NOT NULL,type TEXT NOT NULL,targetNs TEXT NOT NULL,targetId TEXT NOT NULL,targetRev INTEGER NOT NULL,FOREIGN KEY(ns,id,rev) REFERENCES revisions(ns,id,rev) ON DELETE CASCADE);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS ref_target ON refs(type,targetNs,targetId,targetRev);
|
|
76
|
+
CREATE TABLE IF NOT EXISTS artifacts(ns TEXT NOT NULL,id TEXT NOT NULL,json TEXT NOT NULL,size INTEGER NOT NULL,PRIMARY KEY(ns,id));
|
|
77
|
+
CREATE TABLE IF NOT EXISTS uploads(ns TEXT NOT NULL,id TEXT NOT NULL,artifact TEXT NOT NULL,subject TEXT NOT NULL,json TEXT NOT NULL,size INTEGER NOT NULL,expires INTEGER NOT NULL,state TEXT NOT NULL,PRIMARY KEY(ns,id));
|
|
78
|
+
CREATE TABLE IF NOT EXISTS idem(ns TEXT NOT NULL,subject TEXT NOT NULL,key TEXT NOT NULL,fingerprint TEXT NOT NULL,result TEXT NOT NULL,expires INTEGER NOT NULL,PRIMARY KEY(ns,subject,key));
|
|
79
|
+
CREATE TABLE IF NOT EXISTS garbage(ns TEXT NOT NULL,path TEXT PRIMARY KEY,size INTEGER NOT NULL);
|
|
80
|
+
PRAGMA user_version=2; COMMIT;`);
|
|
81
|
+
if (!existsSync(join(dir, "cursor.key")))
|
|
82
|
+
this.writeDurable(join(dir, "cursor.key"), randomBytes(32));
|
|
83
|
+
this.cursorKey = readFileSync(this.safe("cursor.key"));
|
|
84
|
+
if (this.cursorKey.length !== 32)
|
|
85
|
+
fail("integrity_error", "Invalid cursor signing key");
|
|
86
|
+
this.recover();
|
|
87
|
+
this.syncDirectory(dir);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
opened?.close();
|
|
91
|
+
unlinkSync(lock);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
safe(relative) {
|
|
96
|
+
const parts = relative.split("/");
|
|
97
|
+
let path = this.directory;
|
|
98
|
+
for (const part of parts) {
|
|
99
|
+
if (!/^[A-Za-z0-9._-]+$/.test(part) || part === "." || part === "..")
|
|
100
|
+
fail("invalid_request", "Invalid internal path");
|
|
101
|
+
path = join(path, part);
|
|
102
|
+
if (existsSync(path) && lstatSync(path).isSymbolicLink())
|
|
103
|
+
fail("integrity_error", "Storage contains a symbolic link");
|
|
104
|
+
}
|
|
105
|
+
return path;
|
|
106
|
+
}
|
|
107
|
+
syncDirectory(dir) {
|
|
108
|
+
if (process.platform === "win32" && this.fileSyncOnly)
|
|
109
|
+
return;
|
|
110
|
+
const fd = openSync(dir, "r");
|
|
111
|
+
try {
|
|
112
|
+
fsyncSync(fd);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
closeSync(fd);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
writeDurable(path, data) {
|
|
119
|
+
const fd = openSync(path, "wx", 0o600);
|
|
120
|
+
try {
|
|
121
|
+
let offset = 0;
|
|
122
|
+
while (offset < data.length)
|
|
123
|
+
offset += writeSync(fd, data, offset);
|
|
124
|
+
fsyncSync(fd);
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
closeSync(fd);
|
|
128
|
+
}
|
|
129
|
+
this.syncDirectory(this.directory);
|
|
130
|
+
}
|
|
131
|
+
check(context) {
|
|
132
|
+
if (this.closed)
|
|
133
|
+
fail("busy", "Store is closed");
|
|
134
|
+
text(context.subject, 512);
|
|
135
|
+
context.signal?.throwIfAborted();
|
|
136
|
+
}
|
|
137
|
+
key(key) { segment(key.namespace); segment(key.id); }
|
|
138
|
+
quota(namespace) {
|
|
139
|
+
const row = this.db.prepare(`SELECT
|
|
140
|
+
COALESCE((SELECT SUM(bytes) FROM revisions WHERE ns=?),0)+
|
|
141
|
+
COALESCE((SELECT SUM(size+length(json)+128) FROM artifacts WHERE ns=?),0)+
|
|
142
|
+
COALESCE((SELECT SUM(size+length(json)+128) FROM uploads WHERE ns=?),0)+
|
|
143
|
+
COALESCE((SELECT SUM(length(result)*4+length(key)*4+length(subject)*4+256) FROM idem WHERE ns=?),0)+
|
|
144
|
+
COALESCE((SELECT SUM(size) FROM garbage WHERE ns=?),0) AS total`).get(namespace, namespace, namespace, namespace, namespace);
|
|
145
|
+
if (Number(row.total) > this.limits.maxNamespaceBytes)
|
|
146
|
+
fail("quota_exceeded", "Namespace storage quota exceeded");
|
|
147
|
+
}
|
|
148
|
+
mutation(method, request, context, action) {
|
|
149
|
+
this.check(context);
|
|
150
|
+
segment(request.namespace);
|
|
151
|
+
text(request.idempotencyKey, 128);
|
|
152
|
+
const fingerprint = digest({ method, request });
|
|
153
|
+
this.expireUploads();
|
|
154
|
+
this.collectGarbage();
|
|
155
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
156
|
+
try {
|
|
157
|
+
this.db.prepare("DELETE FROM idem WHERE expires<=?").run(Date.now());
|
|
158
|
+
const old = this.db.prepare("SELECT fingerprint,result FROM idem WHERE ns=? AND subject=? AND key=?").get(request.namespace, context.subject, request.idempotencyKey);
|
|
159
|
+
if (old) {
|
|
160
|
+
if (old.fingerprint !== fingerprint)
|
|
161
|
+
fail("idempotency_conflict", "Idempotency key already identifies another mutation");
|
|
162
|
+
this.db.exec("COMMIT");
|
|
163
|
+
return JSON.parse(String(old.result));
|
|
164
|
+
}
|
|
165
|
+
const count = Number(this.db.prepare("SELECT COUNT(*) AS n FROM idem WHERE ns=?").get(request.namespace).n);
|
|
166
|
+
if (count >= 100_000)
|
|
167
|
+
fail("quota_exceeded", "Idempotency quota exceeded");
|
|
168
|
+
const result = action();
|
|
169
|
+
this.db.prepare("INSERT INTO idem VALUES(?,?,?,?,?,?)").run(request.namespace, context.subject, request.idempotencyKey, fingerprint, JSON.stringify(result ?? null), Date.now() + this.limits.idempotencyRetentionSeconds * 1000);
|
|
170
|
+
this.quota(request.namespace);
|
|
171
|
+
this.db.exec("COMMIT");
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
this.db.exec("ROLLBACK");
|
|
176
|
+
if (error.code === "SQLITE_BUSY")
|
|
177
|
+
fail("busy", "Storage is busy");
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async getCapabilitiesAsync() {
|
|
182
|
+
return { contract: "persistence.v1", limits: { ...this.limits }, durability: this.fileSyncOnly ? "file-sync" : "file-and-directory-sync" };
|
|
183
|
+
}
|
|
184
|
+
document(key, revision) {
|
|
185
|
+
this.key(key);
|
|
186
|
+
if (revision !== undefined)
|
|
187
|
+
integer(revision, 1);
|
|
188
|
+
const row = revision === undefined
|
|
189
|
+
? this.db.prepare("SELECT r.json FROM heads h JOIN revisions r ON r.ns=h.ns AND r.id=h.id AND r.rev=h.rev WHERE h.ns=? AND h.id=?").get(key.namespace, key.id)
|
|
190
|
+
: this.db.prepare("SELECT json FROM revisions WHERE ns=? AND id=? AND rev=?").get(key.namespace, key.id, revision);
|
|
191
|
+
if (!row)
|
|
192
|
+
fail("not_found", "Document revision not found");
|
|
193
|
+
return JSON.parse(String(row.json));
|
|
194
|
+
}
|
|
195
|
+
async getAsync(request, context) {
|
|
196
|
+
this.check(context);
|
|
197
|
+
const doc = this.document(request, request.revision);
|
|
198
|
+
if (request.revision === undefined && doc.deleted)
|
|
199
|
+
fail("not_found", "Document is deleted");
|
|
200
|
+
return doc;
|
|
201
|
+
}
|
|
202
|
+
insert(doc) {
|
|
203
|
+
const json = canonical(doc);
|
|
204
|
+
this.db.prepare("INSERT INTO revisions VALUES(?,?,?,?,?)").run(doc.namespace, doc.id, doc.revision, json, Buffer.byteLength(json) + doc.references.length * 512 + 128);
|
|
205
|
+
this.db.prepare("INSERT INTO heads VALUES(?,?,?) ON CONFLICT(ns,id) DO UPDATE SET rev=excluded.rev").run(doc.namespace, doc.id, doc.revision);
|
|
206
|
+
for (const ref of doc.references)
|
|
207
|
+
this.db.prepare("INSERT INTO refs VALUES(?,?,?,?,?,?,?)").run(doc.namespace, doc.id, doc.revision, ref.type, ref.namespace, ref.id, ref.type === "document" ? ref.revision : 0);
|
|
208
|
+
return doc;
|
|
209
|
+
}
|
|
210
|
+
async putAsync(request, context) {
|
|
211
|
+
this.key(request);
|
|
212
|
+
integer(request.expectedRevision);
|
|
213
|
+
text(request.kind);
|
|
214
|
+
text(request.schemaVersion);
|
|
215
|
+
if (!Array.isArray(request.references) || request.references.length > this.limits.maxReferences)
|
|
216
|
+
fail("invalid_request", "Invalid reference list");
|
|
217
|
+
if (Buffer.byteLength(canonical(request)) > this.limits.maxDocumentBytes)
|
|
218
|
+
fail("quota_exceeded", "Document exceeds byte limit");
|
|
219
|
+
return this.mutation("put", request, context, () => {
|
|
220
|
+
let old;
|
|
221
|
+
try {
|
|
222
|
+
old = this.document(request);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
if (!(error instanceof PersistenceError) || error.code !== "not_found")
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
if ((old?.revision ?? 0) !== request.expectedRevision)
|
|
229
|
+
fail("revision_conflict", "Expected revision does not match");
|
|
230
|
+
for (const ref of request.references) {
|
|
231
|
+
this.key(ref);
|
|
232
|
+
if (ref.type === "document") {
|
|
233
|
+
if (this.document(ref, integer(ref.revision, 1)).deleted)
|
|
234
|
+
fail("not_found", "Referenced revision is deleted");
|
|
235
|
+
}
|
|
236
|
+
else if (ref.type === "artifact")
|
|
237
|
+
this.artifact(ref);
|
|
238
|
+
else
|
|
239
|
+
fail("invalid_request", "Unsupported reference type");
|
|
240
|
+
}
|
|
241
|
+
const now = new Date().toISOString();
|
|
242
|
+
return this.insert({ namespace: request.namespace, id: request.id, revision: (old?.revision ?? 0) + 1, createdAt: old?.createdAt ?? now, updatedAt: now, kind: request.kind, schemaVersion: request.schemaVersion, payload: request.payload, references: request.references, deleted: false });
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
page(request, binding, rows) {
|
|
246
|
+
const limit = request.limit === undefined ? Math.min(50, this.limits.maxPageSize) : integer(request.limit, 1, this.limits.maxPageSize);
|
|
247
|
+
let after = "";
|
|
248
|
+
if (request.cursor !== undefined) {
|
|
249
|
+
text(request.cursor, 4096);
|
|
250
|
+
try {
|
|
251
|
+
const raw = Buffer.from(request.cursor, "base64url");
|
|
252
|
+
const cipher = createDecipheriv("aes-256-gcm", this.cursorKey, raw.subarray(0, 12));
|
|
253
|
+
cipher.setAuthTag(raw.subarray(12, 28));
|
|
254
|
+
const cursor = JSON.parse(Buffer.concat([cipher.update(raw.subarray(28)), cipher.final()]).toString());
|
|
255
|
+
if (cursor.binding !== digest(binding) || cursor.expires <= Date.now())
|
|
256
|
+
fail("invalid_request", "Expired or mismatched cursor");
|
|
257
|
+
after = cursor.after;
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
fail("invalid_request", "Invalid cursor");
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// SQL queries below are keyset queries with a bounded LIMIT, including an extra row.
|
|
264
|
+
this.pageAfter = after;
|
|
265
|
+
this.pageLimit = limit;
|
|
266
|
+
const found = rows();
|
|
267
|
+
const items = found.slice(0, limit).map(r => JSON.parse(String(r.json)));
|
|
268
|
+
if (found.length <= limit)
|
|
269
|
+
return { items };
|
|
270
|
+
const iv = randomBytes(12), cipher = createCipheriv("aes-256-gcm", this.cursorKey, iv);
|
|
271
|
+
const encoded = Buffer.concat([cipher.update(JSON.stringify({ binding: digest(binding), after: found[limit - 1].key, expires: Date.now() + 900_000 })), cipher.final()]);
|
|
272
|
+
return { items, nextCursor: Buffer.concat([iv, cipher.getAuthTag(), encoded]).toString("base64url") };
|
|
273
|
+
}
|
|
274
|
+
pageAfter = "";
|
|
275
|
+
pageLimit = 50;
|
|
276
|
+
async listAsync(request, context) {
|
|
277
|
+
this.check(context);
|
|
278
|
+
segment(request.namespace);
|
|
279
|
+
if (request.kind !== undefined)
|
|
280
|
+
text(request.kind);
|
|
281
|
+
if (request.includeDeleted !== undefined && typeof request.includeDeleted !== "boolean")
|
|
282
|
+
fail("invalid_request", "Invalid deleted filter");
|
|
283
|
+
return this.page(request, { method: "list", ns: request.namespace, kind: request.kind ?? null, deleted: request.includeDeleted ?? false, subject: context.subject }, () => this.db.prepare(`SELECT h.id AS key,r.json FROM heads h JOIN revisions r ON r.ns=h.ns AND r.id=h.id AND r.rev=h.rev
|
|
284
|
+
WHERE h.ns=? AND h.id>? AND (? IS NULL OR json_extract(r.json,'$.kind')=?) AND (?=1 OR json_extract(r.json,'$.deleted')=0) ORDER BY h.id LIMIT ?`)
|
|
285
|
+
.all(request.namespace, String(this.pageAfter), request.kind ?? null, request.kind ?? null, request.includeDeleted ? 1 : 0, this.pageLimit + 1));
|
|
286
|
+
}
|
|
287
|
+
async listRevisionsAsync(request, context) {
|
|
288
|
+
this.check(context);
|
|
289
|
+
this.key(request);
|
|
290
|
+
this.document(request);
|
|
291
|
+
return this.page(request, { method: "revisions", ns: request.namespace, id: request.id, subject: context.subject }, () => this.db.prepare("SELECT rev AS key,json FROM revisions WHERE ns=? AND id=? AND rev>? ORDER BY rev LIMIT ?").all(request.namespace, request.id, Number(this.pageAfter) || 0, this.pageLimit + 1));
|
|
292
|
+
}
|
|
293
|
+
async deleteAsync(request, context) {
|
|
294
|
+
this.key(request);
|
|
295
|
+
integer(request.expectedRevision, 1);
|
|
296
|
+
return this.mutation("delete", request, context, () => {
|
|
297
|
+
const old = this.document(request);
|
|
298
|
+
if (old.revision !== request.expectedRevision)
|
|
299
|
+
fail("revision_conflict", "Expected revision does not match");
|
|
300
|
+
return this.insert({ ...old, revision: old.revision + 1, updatedAt: new Date().toISOString(), deleted: true, payload: null, references: [] });
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
async beginArtifactAsync(request, context) {
|
|
304
|
+
integer(request.size, 0, this.limits.maxArtifactBytes);
|
|
305
|
+
text(request.mimeType, 128);
|
|
306
|
+
if (!/^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/.test(request.mimeType))
|
|
307
|
+
fail("invalid_request", "Invalid MIME type");
|
|
308
|
+
if (request.hash?.algorithm !== "sha256" || !/^[a-f0-9]{64}$/.test(request.hash.value))
|
|
309
|
+
fail("invalid_request", "Expected SHA-256 hash");
|
|
310
|
+
if (Buffer.byteLength(canonical(request.provenance)) > this.limits.maxDocumentBytes)
|
|
311
|
+
fail("quota_exceeded", "Provenance exceeds limit");
|
|
312
|
+
return this.mutation("beginArtifact", request, context, () => {
|
|
313
|
+
if (Number(this.db.prepare("SELECT COUNT(*) AS n FROM uploads WHERE subject=? AND state IN ('pending','complete')").get(context.subject).n) >= 4)
|
|
314
|
+
fail("quota_exceeded", "Too many active uploads");
|
|
315
|
+
const upload = { namespace: request.namespace, artifactId: randomUUID(), uploadId: randomUUID(), expiresAt: new Date(Date.now() + DAY).toISOString() };
|
|
316
|
+
const metadata = { namespace: request.namespace, id: upload.artifactId, mimeType: request.mimeType, size: request.size, hash: request.hash, provenance: request.provenance, createdAt: new Date().toISOString() };
|
|
317
|
+
this.db.prepare("INSERT INTO uploads VALUES(?,?,?,?,?,?,?,?)").run(request.namespace, upload.uploadId, upload.artifactId, context.subject, canonical(metadata), request.size, Date.parse(upload.expiresAt), "pending");
|
|
318
|
+
return upload;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
upload(namespace, id, context) {
|
|
322
|
+
this.check(context);
|
|
323
|
+
segment(namespace);
|
|
324
|
+
segment(id);
|
|
325
|
+
const row = this.db.prepare("SELECT * FROM uploads WHERE ns=? AND id=? AND subject=?").get(namespace, id, context.subject);
|
|
326
|
+
if (!row || Number(row.expires) <= Date.now())
|
|
327
|
+
fail("not_found", "Upload not found or expired");
|
|
328
|
+
return row;
|
|
329
|
+
}
|
|
330
|
+
async inspectUploadAsync(namespace, uploadId, context) {
|
|
331
|
+
const row = this.upload(namespace, uploadId, context);
|
|
332
|
+
return { namespace, uploadId, artifactId: String(row.artifact), expiresAt: new Date(Number(row.expires)).toISOString() };
|
|
333
|
+
}
|
|
334
|
+
async writeArtifactAsync(request, context) {
|
|
335
|
+
const row = this.upload(request.namespace, request.uploadId, context);
|
|
336
|
+
if (this.active.has(request.uploadId) || row.state !== "pending")
|
|
337
|
+
fail("busy", "Upload is already writing or complete");
|
|
338
|
+
this.active.add(request.uploadId);
|
|
339
|
+
const path = this.safe(`staging/${request.uploadId}`);
|
|
340
|
+
let fd;
|
|
341
|
+
try {
|
|
342
|
+
rmSync(path, { force: true });
|
|
343
|
+
fd = openSync(path, "wx", 0o600);
|
|
344
|
+
const hash = createHash("sha256");
|
|
345
|
+
let size = 0;
|
|
346
|
+
for await (const bytes of request.bytes) {
|
|
347
|
+
context.signal?.throwIfAborted();
|
|
348
|
+
if (Date.now() > Number(row.expires))
|
|
349
|
+
fail("transfer_incomplete", "Upload expired");
|
|
350
|
+
if (!(bytes instanceof Uint8Array))
|
|
351
|
+
fail("invalid_request", "Expected binary chunks");
|
|
352
|
+
size += bytes.byteLength;
|
|
353
|
+
if (size > Number(row.size))
|
|
354
|
+
fail("quota_exceeded", "Upload exceeds reserved size");
|
|
355
|
+
hash.update(bytes);
|
|
356
|
+
let offset = 0;
|
|
357
|
+
while (offset < bytes.length)
|
|
358
|
+
offset += writeSync(fd, bytes, offset);
|
|
359
|
+
}
|
|
360
|
+
const expected = JSON.parse(String(row.json));
|
|
361
|
+
if (size !== expected.size)
|
|
362
|
+
fail("transfer_incomplete", "Upload is incomplete");
|
|
363
|
+
if (hash.digest("hex") !== expected.hash.value)
|
|
364
|
+
fail("integrity_error", "Artifact hash does not match");
|
|
365
|
+
fsyncSync(fd);
|
|
366
|
+
closeSync(fd);
|
|
367
|
+
fd = undefined;
|
|
368
|
+
this.syncDirectory(this.safe("staging"));
|
|
369
|
+
this.db.prepare("UPDATE uploads SET state='complete' WHERE ns=? AND id=?").run(request.namespace, request.uploadId);
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
if (fd !== undefined)
|
|
373
|
+
closeSync(fd);
|
|
374
|
+
rmSync(path, { force: true });
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
this.active.delete(request.uploadId);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async commitArtifactAsync(request, context) {
|
|
382
|
+
return this.mutation("commitArtifact", request, context, () => {
|
|
383
|
+
const row = this.upload(request.namespace, request.uploadId, context);
|
|
384
|
+
if (row.state !== "complete" || this.active.has(request.uploadId))
|
|
385
|
+
fail("transfer_incomplete", "Upload has not completed");
|
|
386
|
+
const metadata = JSON.parse(String(row.json));
|
|
387
|
+
const stage = this.safe(`staging/${request.uploadId}`), final = this.safe(`artifacts/${metadata.id}`);
|
|
388
|
+
// A previous rolled-back commit can leave the verified file at its final path.
|
|
389
|
+
const source = existsSync(stage) ? stage : final;
|
|
390
|
+
this.verifyFile(source, metadata);
|
|
391
|
+
if (source === stage)
|
|
392
|
+
renameSync(stage, final);
|
|
393
|
+
this.syncDirectory(this.safe("artifacts"));
|
|
394
|
+
this.syncDirectory(this.safe("staging"));
|
|
395
|
+
this.db.prepare("INSERT INTO artifacts VALUES(?,?,?,?)").run(metadata.namespace, metadata.id, canonical(metadata), metadata.size);
|
|
396
|
+
this.db.prepare("UPDATE uploads SET state='committed',size=0,expires=? WHERE ns=? AND id=?").run(Date.now() + this.limits.idempotencyRetentionSeconds * 1000, request.namespace, request.uploadId);
|
|
397
|
+
return metadata;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
async abortArtifactAsync(request, context) {
|
|
401
|
+
this.mutation("abortArtifact", request, context, () => {
|
|
402
|
+
const row = this.upload(request.namespace, request.uploadId, context);
|
|
403
|
+
if (this.active.has(request.uploadId))
|
|
404
|
+
fail("busy", "Upload is active");
|
|
405
|
+
if (row.state === 'committed')
|
|
406
|
+
fail("revision_conflict", "Committed artifacts cannot be aborted");
|
|
407
|
+
for (const path of [`staging/${request.uploadId}`, `artifacts/${row.artifact}`]) {
|
|
408
|
+
const full = this.safe(path);
|
|
409
|
+
if (existsSync(full))
|
|
410
|
+
this.db.prepare("INSERT OR IGNORE INTO garbage VALUES(?,?,?)").run(request.namespace, path, statSync(full).size);
|
|
411
|
+
}
|
|
412
|
+
this.db.prepare("UPDATE uploads SET state='aborted',size=0,expires=? WHERE ns=? AND id=?").run(Date.now() + this.limits.idempotencyRetentionSeconds * 1000, request.namespace, request.uploadId);
|
|
413
|
+
// Files are collected after commit so rollback never destroys a live upload.
|
|
414
|
+
return { artifact: String(row.artifact) };
|
|
415
|
+
});
|
|
416
|
+
this.collectGarbage();
|
|
417
|
+
this.collectOrphans();
|
|
418
|
+
}
|
|
419
|
+
artifact(key) {
|
|
420
|
+
this.key(key);
|
|
421
|
+
const row = this.db.prepare("SELECT json FROM artifacts WHERE ns=? AND id=?").get(key.namespace, key.id);
|
|
422
|
+
if (!row)
|
|
423
|
+
fail("not_found", "Artifact not found");
|
|
424
|
+
return JSON.parse(String(row.json));
|
|
425
|
+
}
|
|
426
|
+
async getArtifactAsync(request, context) { this.check(context); return this.artifact(request); }
|
|
427
|
+
async readArtifactAsync(request, context) {
|
|
428
|
+
this.check(context);
|
|
429
|
+
const metadata = this.artifact(request), path = this.safe(`artifacts/${metadata.id}`);
|
|
430
|
+
this.verifyFile(path, metadata);
|
|
431
|
+
const fd = openSync(path, "r");
|
|
432
|
+
const stream = createReadStream(path, { fd, autoClose: true, signal: context.signal });
|
|
433
|
+
const readKey = `read-${randomUUID()}`;
|
|
434
|
+
this.active.add(readKey);
|
|
435
|
+
this.readers.set(metadata.id, (this.readers.get(metadata.id) ?? 0) + 1);
|
|
436
|
+
stream.once("close", () => {
|
|
437
|
+
this.active.delete(readKey);
|
|
438
|
+
const n = this.readers.get(metadata.id) - 1;
|
|
439
|
+
if (n)
|
|
440
|
+
this.readers.set(metadata.id, n);
|
|
441
|
+
else
|
|
442
|
+
this.readers.delete(metadata.id);
|
|
443
|
+
if (!this.closed)
|
|
444
|
+
this.collectGarbage();
|
|
445
|
+
});
|
|
446
|
+
return stream;
|
|
447
|
+
}
|
|
448
|
+
verifyFile(path, metadata) {
|
|
449
|
+
if (!existsSync(path) || !lstatSync(path).isFile() || statSync(path).size !== metadata.size)
|
|
450
|
+
fail("integrity_error", "Artifact file missing or wrong size");
|
|
451
|
+
const fd = openSync(path, "r");
|
|
452
|
+
try {
|
|
453
|
+
const hash = createHash("sha256"), buffer = Buffer.alloc(128 * 1024);
|
|
454
|
+
// Synchronous verification is bounded in memory and runs before publishing/serving bytes.
|
|
455
|
+
let n;
|
|
456
|
+
while ((n = readSync(fd, buffer, 0, buffer.length, null)) > 0)
|
|
457
|
+
hash.update(buffer.subarray(0, n));
|
|
458
|
+
if (hash.digest("hex") !== metadata.hash.value)
|
|
459
|
+
fail("integrity_error", "Artifact hash does not match");
|
|
460
|
+
}
|
|
461
|
+
finally {
|
|
462
|
+
closeSync(fd);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async purgeAsync(request, context) {
|
|
466
|
+
segment(request.target.id);
|
|
467
|
+
this.mutation("purge", request, context, () => {
|
|
468
|
+
const t = request.target;
|
|
469
|
+
if (t.type !== "document" && t.type !== "artifact")
|
|
470
|
+
fail("invalid_request", "Invalid purge target");
|
|
471
|
+
const revision = t.type === "document" ? integer(t.revision, 1) : 0;
|
|
472
|
+
const created = t.type === "document" ? this.document({ namespace: request.namespace, id: t.id }, revision).updatedAt : this.artifact({ namespace: request.namespace, id: t.id }).createdAt;
|
|
473
|
+
if (Date.now() - Date.parse(created) < this.retentionMs)
|
|
474
|
+
fail("retention_blocked", "Minimum retention has not elapsed");
|
|
475
|
+
if (this.db.prepare("SELECT 1 FROM refs WHERE type=? AND targetNs=? AND targetId=? AND targetRev=? LIMIT 1").get(t.type, request.namespace, t.id, revision))
|
|
476
|
+
fail("retention_blocked", "Target is referenced by an immutable revision");
|
|
477
|
+
if (t.type === "artifact") {
|
|
478
|
+
const metadata = this.artifact({ namespace: request.namespace, id: t.id });
|
|
479
|
+
this.db.prepare("INSERT INTO garbage VALUES(?,?,?)").run(request.namespace, `artifacts/${t.id}`, metadata.size);
|
|
480
|
+
this.db.prepare("DELETE FROM artifacts WHERE ns=? AND id=?").run(request.namespace, t.id);
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
if (this.db.prepare("SELECT 1 FROM heads WHERE ns=? AND id=? AND rev=?").get(request.namespace, t.id, revision))
|
|
484
|
+
fail("retention_blocked", "Current head cannot be purged");
|
|
485
|
+
this.db.prepare("DELETE FROM revisions WHERE ns=? AND id=? AND rev=?").run(request.namespace, t.id, revision);
|
|
486
|
+
}
|
|
487
|
+
return null;
|
|
488
|
+
});
|
|
489
|
+
this.collectGarbage();
|
|
490
|
+
this.collectOrphans();
|
|
491
|
+
}
|
|
492
|
+
collectGarbage() {
|
|
493
|
+
for (const row of this.db.prepare("SELECT * FROM garbage").all()) {
|
|
494
|
+
const path = String(row.path), id = path.split("/")[1];
|
|
495
|
+
if (this.readers.has(id))
|
|
496
|
+
continue;
|
|
497
|
+
const held = path.startsWith("staging/") ? this.db.prepare("SELECT 1 FROM uploads WHERE id=? AND state IN ('pending','complete')").get(id)
|
|
498
|
+
: this.db.prepare("SELECT 1 FROM artifacts WHERE id=? UNION ALL SELECT 1 FROM uploads WHERE artifact=? AND state IN ('pending','complete')").get(id, id);
|
|
499
|
+
if (held)
|
|
500
|
+
continue;
|
|
501
|
+
try {
|
|
502
|
+
rmSync(this.safe(path), { force: true });
|
|
503
|
+
this.syncDirectory(this.safe(path.split("/")[0]));
|
|
504
|
+
this.db.prepare("DELETE FROM garbage WHERE path=?").run(path);
|
|
505
|
+
}
|
|
506
|
+
catch { /* Keep accounting reserved and retry at recovery or the next collection. */ }
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
expireUploads() {
|
|
510
|
+
for (const row of this.db.prepare("SELECT * FROM uploads WHERE expires<=?").all(Date.now())) {
|
|
511
|
+
if (this.active.has(String(row.id)))
|
|
512
|
+
continue;
|
|
513
|
+
for (const path of [`staging/${row.id}`, `artifacts/${row.artifact}`]) {
|
|
514
|
+
const file = this.safe(path);
|
|
515
|
+
if (existsSync(file) && !this.db.prepare("SELECT 1 FROM artifacts WHERE id=?").get(String(row.artifact)))
|
|
516
|
+
this.db.prepare("INSERT OR IGNORE INTO garbage VALUES(?,?,?)").run(String(row.ns), path, statSync(file).size);
|
|
517
|
+
}
|
|
518
|
+
this.db.prepare("DELETE FROM uploads WHERE ns=? AND id=?").run(String(row.ns), String(row.id));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
collectOrphans() {
|
|
522
|
+
for (const sub of ["staging", "artifacts"])
|
|
523
|
+
for (const name of readdirSync(this.safe(sub))) {
|
|
524
|
+
const path = this.safe(`${sub}/${name}`);
|
|
525
|
+
const held = sub === "staging" ? this.db.prepare("SELECT 1 FROM uploads WHERE id=? AND state IN ('pending','complete')").get(name)
|
|
526
|
+
: this.db.prepare("SELECT 1 FROM artifacts WHERE id=? UNION ALL SELECT 1 FROM uploads WHERE artifact=? AND state IN ('pending','complete')").get(name, name);
|
|
527
|
+
if (!held && !this.active.has(name) && Date.now() - statSync(path).mtimeMs > DAY)
|
|
528
|
+
rmSync(path, { force: true });
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
recover() {
|
|
532
|
+
this.collectGarbage();
|
|
533
|
+
this.expireUploads();
|
|
534
|
+
for (const row of this.db.prepare("SELECT * FROM uploads").all()) {
|
|
535
|
+
const stage = this.safe(`staging/${row.id}`), final = this.safe(`artifacts/${row.artifact}`);
|
|
536
|
+
if (row.state === "complete")
|
|
537
|
+
this.verifyFile(existsSync(stage) ? stage : final, JSON.parse(String(row.json)));
|
|
538
|
+
else {
|
|
539
|
+
rmSync(stage, { force: true });
|
|
540
|
+
if (row.state === "aborted" && !this.db.prepare("SELECT 1 FROM artifacts WHERE id=?").get(String(row.artifact)))
|
|
541
|
+
rmSync(final, { force: true });
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
for (const row of this.db.prepare("SELECT json FROM artifacts").all()) {
|
|
545
|
+
const metadata = JSON.parse(String(row.json));
|
|
546
|
+
this.verifyFile(this.safe(`artifacts/${metadata.id}`), metadata);
|
|
547
|
+
}
|
|
548
|
+
this.collectOrphans();
|
|
549
|
+
}
|
|
550
|
+
async closeAsync() {
|
|
551
|
+
if (this.closed)
|
|
552
|
+
return;
|
|
553
|
+
if (this.active.size)
|
|
554
|
+
fail("busy", "Transfers are still active");
|
|
555
|
+
this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
556
|
+
this.db.close();
|
|
557
|
+
this.closed = true;
|
|
558
|
+
unlinkSync(this.safe("writer.lock"));
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
//# sourceMappingURL=sqlite.persistence.store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.persistence.store.js","sourceRoot":"","sources":["../../src/sqlite/sqlite.persistence.store.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|