@de-otio/chaoskb-client 0.3.0 → 0.3.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/dist/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +20 -27
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/commands/devices.d.ts.map +1 -1
- package/dist/cli/commands/devices.js +7 -70
- package/dist/cli/commands/devices.js.map +1 -1
- package/dist/cli/commands/notifications.d.ts.map +1 -1
- package/dist/cli/commands/notifications.js +1 -39
- package/dist/cli/commands/notifications.js.map +1 -1
- package/dist/cli/commands/projects.d.ts.map +1 -1
- package/dist/cli/commands/projects.js +9 -44
- package/dist/cli/commands/projects.js.map +1 -1
- package/dist/cli/commands/rotate-key.d.ts.map +1 -1
- package/dist/cli/commands/rotate-key.js +14 -32
- package/dist/cli/commands/rotate-key.js.map +1 -1
- package/dist/cli/commands/setup-sync.js +7 -15
- package/dist/cli/commands/setup-sync.js.map +1 -1
- package/dist/cli/mcp-server.d.ts +3 -0
- package/dist/cli/mcp-server.d.ts.map +1 -1
- package/dist/cli/mcp-server.js +21 -2
- package/dist/cli/mcp-server.js.map +1 -1
- package/dist/cli/tools/kb-delete.d.ts.map +1 -1
- package/dist/cli/tools/kb-delete.js +4 -6
- package/dist/cli/tools/kb-delete.js.map +1 -1
- package/dist/cli/tools/kb-ingest.d.ts.map +1 -1
- package/dist/cli/tools/kb-ingest.js +8 -5
- package/dist/cli/tools/kb-ingest.js.map +1 -1
- package/dist/cli/tools/sync-client.d.ts +3 -1
- package/dist/cli/tools/sync-client.d.ts.map +1 -1
- package/dist/cli/tools/sync-client.js +10 -30
- package/dist/cli/tools/sync-client.js.map +1 -1
- package/dist/storage/kb-database.d.ts +6 -1
- package/dist/storage/kb-database.d.ts.map +1 -1
- package/dist/storage/kb-database.js +18 -0
- package/dist/storage/kb-database.js.map +1 -1
- package/dist/storage/schema.d.ts +1 -1
- package/dist/storage/schema.d.ts.map +1 -1
- package/dist/storage/schema.js +153 -1
- package/dist/storage/schema.js.map +1 -1
- package/dist/storage/sync-queue-repo.d.ts +28 -0
- package/dist/storage/sync-queue-repo.d.ts.map +1 -0
- package/dist/storage/sync-queue-repo.js +107 -0
- package/dist/storage/sync-queue-repo.js.map +1 -0
- package/dist/storage/sync-sequence-repo.d.ts +17 -0
- package/dist/storage/sync-sequence-repo.d.ts.map +1 -0
- package/dist/storage/sync-sequence-repo.js +24 -0
- package/dist/storage/sync-sequence-repo.js.map +1 -0
- package/dist/storage/sync-state-repo.d.ts +16 -0
- package/dist/storage/sync-state-repo.d.ts.map +1 -0
- package/dist/storage/sync-state-repo.js +25 -0
- package/dist/storage/sync-state-repo.js.map +1 -0
- package/dist/storage/types.d.ts +51 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/sync/client-factory.d.ts +21 -0
- package/dist/sync/client-factory.d.ts.map +1 -0
- package/dist/sync/client-factory.js +36 -0
- package/dist/sync/client-factory.js.map +1 -0
- package/dist/sync/http-client.d.ts +2 -2
- package/dist/sync/http-client.d.ts.map +1 -1
- package/dist/sync/http-client.js +9 -3
- package/dist/sync/http-client.js.map +1 -1
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +2 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/queue-processor.d.ts +38 -0
- package/dist/sync/queue-processor.d.ts.map +1 -0
- package/dist/sync/queue-processor.js +96 -0
- package/dist/sync/queue-processor.js.map +1 -0
- package/dist/sync/ssh-signer.d.ts +6 -1
- package/dist/sync/ssh-signer.d.ts.map +1 -1
- package/dist/sync/ssh-signer.js +9 -2
- package/dist/sync/ssh-signer.js.map +1 -1
- package/dist/sync/sync-service.d.ts +18 -8
- package/dist/sync/sync-service.d.ts.map +1 -1
- package/dist/sync/sync-service.js +55 -43
- package/dist/sync/sync-service.js.map +1 -1
- package/dist/sync/types.d.ts +4 -0
- package/dist/sync/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/storage/schema.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { existsSync, readFileSync, renameSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
export const SCHEMA_VERSION = 4;
|
|
2
5
|
export const CREATE_TABLES_SQL = [
|
|
3
6
|
`CREATE TABLE IF NOT EXISTS sources (
|
|
4
7
|
id TEXT PRIMARY KEY,
|
|
@@ -54,6 +57,34 @@ export const CREATE_TABLES_SQL = [
|
|
|
54
57
|
INSERT INTO chunks_fts(rowid, content, source_id, chunk_index)
|
|
55
58
|
VALUES (new.rowid, new.content, new.source_id, new.chunk_index);
|
|
56
59
|
END`,
|
|
60
|
+
// --- v3: Sync infrastructure tables ---
|
|
61
|
+
`CREATE TABLE IF NOT EXISTS sync_sequence (
|
|
62
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
63
|
+
value INTEGER NOT NULL DEFAULT 0
|
|
64
|
+
)`,
|
|
65
|
+
`INSERT OR IGNORE INTO sync_sequence (id, value) VALUES (1, 0)`,
|
|
66
|
+
`CREATE TABLE IF NOT EXISTS sync_queue (
|
|
67
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
68
|
+
blob_id TEXT NOT NULL,
|
|
69
|
+
operation TEXT NOT NULL CHECK (operation IN ('upload', 'delete')),
|
|
70
|
+
data BLOB,
|
|
71
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
72
|
+
max_retries INTEGER NOT NULL DEFAULT 5,
|
|
73
|
+
last_attempt TEXT,
|
|
74
|
+
next_attempt TEXT,
|
|
75
|
+
error_message TEXT,
|
|
76
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
77
|
+
CHECK (status IN ('pending', 'processing', 'failed', 'completed')),
|
|
78
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
79
|
+
)`,
|
|
80
|
+
`CREATE INDEX IF NOT EXISTS idx_sync_queue_status
|
|
81
|
+
ON sync_queue(status, next_attempt)`,
|
|
82
|
+
`CREATE INDEX IF NOT EXISTS idx_sync_queue_blob
|
|
83
|
+
ON sync_queue(blob_id)`,
|
|
84
|
+
`CREATE TABLE IF NOT EXISTS sync_state (
|
|
85
|
+
key TEXT PRIMARY KEY,
|
|
86
|
+
value TEXT NOT NULL
|
|
87
|
+
)`,
|
|
57
88
|
];
|
|
58
89
|
export function initializeSchema(db) {
|
|
59
90
|
const existing = db
|
|
@@ -88,6 +119,12 @@ export function migrateSchema(db) {
|
|
|
88
119
|
if (currentVersion < 2) {
|
|
89
120
|
runMigrationV2(db);
|
|
90
121
|
}
|
|
122
|
+
if (currentVersion < 3) {
|
|
123
|
+
runMigrationV3(db);
|
|
124
|
+
}
|
|
125
|
+
if (currentVersion < 4) {
|
|
126
|
+
runMigrationV4(db);
|
|
127
|
+
}
|
|
91
128
|
db.prepare('UPDATE schema_version SET version = ?').run(SCHEMA_VERSION);
|
|
92
129
|
}
|
|
93
130
|
/**
|
|
@@ -119,4 +156,119 @@ function runMigrationV2(db) {
|
|
|
119
156
|
db.exec(`INSERT INTO chunks_fts(rowid, content, source_id, chunk_index)
|
|
120
157
|
SELECT rowid, content, source_id, chunk_index FROM chunks`);
|
|
121
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Migration v3: Add sync infrastructure tables.
|
|
161
|
+
*
|
|
162
|
+
* Moves sequence counter, upload queue, and sync state from flat files
|
|
163
|
+
* into SQLite for safe multi-process concurrent access.
|
|
164
|
+
*/
|
|
165
|
+
function runMigrationV3(db) {
|
|
166
|
+
db.exec(`CREATE TABLE IF NOT EXISTS sync_sequence (
|
|
167
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
168
|
+
value INTEGER NOT NULL DEFAULT 0
|
|
169
|
+
)`);
|
|
170
|
+
db.exec(`INSERT OR IGNORE INTO sync_sequence (id, value) VALUES (1, 0)`);
|
|
171
|
+
db.exec(`CREATE TABLE IF NOT EXISTS sync_queue (
|
|
172
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
173
|
+
blob_id TEXT NOT NULL,
|
|
174
|
+
operation TEXT NOT NULL CHECK (operation IN ('upload', 'delete')),
|
|
175
|
+
data BLOB,
|
|
176
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
177
|
+
max_retries INTEGER NOT NULL DEFAULT 5,
|
|
178
|
+
last_attempt TEXT,
|
|
179
|
+
next_attempt TEXT,
|
|
180
|
+
error_message TEXT,
|
|
181
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
182
|
+
CHECK (status IN ('pending', 'processing', 'failed', 'completed')),
|
|
183
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
184
|
+
)`);
|
|
185
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_sync_queue_status
|
|
186
|
+
ON sync_queue(status, next_attempt)`);
|
|
187
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_sync_queue_blob
|
|
188
|
+
ON sync_queue(blob_id)`);
|
|
189
|
+
db.exec(`CREATE TABLE IF NOT EXISTS sync_state (
|
|
190
|
+
key TEXT PRIMARY KEY,
|
|
191
|
+
value TEXT NOT NULL
|
|
192
|
+
)`);
|
|
193
|
+
// Import existing flat-file data if present
|
|
194
|
+
importFlatFileData(db);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Import data from legacy flat files into SQLite tables.
|
|
198
|
+
* Reads ~/.chaoskb/sequence, upload-queue.json, and sync-state.json.
|
|
199
|
+
* Files are left on disk as rollback backups.
|
|
200
|
+
*/
|
|
201
|
+
function importFlatFileData(db) {
|
|
202
|
+
const chaoskbDir = join(homedir(), '.chaoskb');
|
|
203
|
+
// Import sequence counter
|
|
204
|
+
const seqPath = join(chaoskbDir, 'sequence');
|
|
205
|
+
if (existsSync(seqPath)) {
|
|
206
|
+
try {
|
|
207
|
+
const value = parseInt(readFileSync(seqPath, 'utf-8').trim(), 10);
|
|
208
|
+
if (!isNaN(value) && value > 0) {
|
|
209
|
+
db.prepare('UPDATE sync_sequence SET value = ? WHERE id = 1').run(value);
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
renameSync(seqPath, seqPath + '.migrated');
|
|
213
|
+
}
|
|
214
|
+
catch { /* already renamed */ }
|
|
215
|
+
}
|
|
216
|
+
catch { /* ignore read errors */ }
|
|
217
|
+
}
|
|
218
|
+
// Import upload queue
|
|
219
|
+
const queuePath = join(chaoskbDir, 'upload-queue.json');
|
|
220
|
+
if (existsSync(queuePath)) {
|
|
221
|
+
try {
|
|
222
|
+
const items = JSON.parse(readFileSync(queuePath, 'utf-8'));
|
|
223
|
+
const insertStmt = db.prepare(`
|
|
224
|
+
INSERT OR IGNORE INTO sync_queue (blob_id, operation, data, retry_count, error_message, status)
|
|
225
|
+
VALUES (?, 'upload', ?, ?, ?, 'pending')
|
|
226
|
+
`);
|
|
227
|
+
for (const item of items) {
|
|
228
|
+
const data = item.data ? Buffer.from(item.data, 'base64') : null;
|
|
229
|
+
insertStmt.run(item.blobId, data, item.retryCount, item.error ?? null);
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
renameSync(queuePath, queuePath + '.migrated');
|
|
233
|
+
}
|
|
234
|
+
catch { /* already renamed */ }
|
|
235
|
+
}
|
|
236
|
+
catch { /* ignore parse errors */ }
|
|
237
|
+
}
|
|
238
|
+
// Import sync state
|
|
239
|
+
const statePath = join(chaoskbDir, 'sync-state.json');
|
|
240
|
+
if (existsSync(statePath)) {
|
|
241
|
+
try {
|
|
242
|
+
const state = JSON.parse(readFileSync(statePath, 'utf-8'));
|
|
243
|
+
const insertStmt = db.prepare('INSERT OR IGNORE INTO sync_state (key, value) VALUES (?, ?)');
|
|
244
|
+
for (const [key, value] of Object.entries(state)) {
|
|
245
|
+
if (value !== undefined && value !== null) {
|
|
246
|
+
insertStmt.run(key, String(value));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
renameSync(statePath, statePath + '.migrated');
|
|
251
|
+
}
|
|
252
|
+
catch { /* already renamed */ }
|
|
253
|
+
}
|
|
254
|
+
catch { /* ignore parse errors */ }
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Migration v4: Reset stale sync queue items.
|
|
259
|
+
*
|
|
260
|
+
* After fixing WAF body size blocking and sequence counter drift,
|
|
261
|
+
* previously failed/retried items need a fresh attempt.
|
|
262
|
+
*/
|
|
263
|
+
function runMigrationV4(db) {
|
|
264
|
+
db.exec(`
|
|
265
|
+
UPDATE sync_queue
|
|
266
|
+
SET status = 'pending',
|
|
267
|
+
retry_count = 0,
|
|
268
|
+
error_message = NULL,
|
|
269
|
+
next_attempt = NULL
|
|
270
|
+
WHERE status IN ('pending', 'failed')
|
|
271
|
+
AND retry_count > 0
|
|
272
|
+
`);
|
|
273
|
+
}
|
|
122
274
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../storage/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../storage/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
import type { ISyncQueueRepository, SyncQueueItem } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite-backed sync queue for uploads and deletes.
|
|
5
|
+
*
|
|
6
|
+
* Multi-process safe: uses atomic UPDATE...RETURNING for claim,
|
|
7
|
+
* so concurrent processes never double-process an item.
|
|
8
|
+
*/
|
|
9
|
+
export declare class SyncQueueRepository implements ISyncQueueRepository {
|
|
10
|
+
private readonly db;
|
|
11
|
+
private readonly enqueueStmt;
|
|
12
|
+
private readonly deleteExistingPendingStmt;
|
|
13
|
+
private readonly claimStmt;
|
|
14
|
+
private readonly completeStmt;
|
|
15
|
+
private readonly failStmt;
|
|
16
|
+
private readonly permanentFailStmt;
|
|
17
|
+
private readonly releaseStaleStmt;
|
|
18
|
+
private readonly pendingCountStmt;
|
|
19
|
+
constructor(db: BetterSqlite3.Database);
|
|
20
|
+
enqueue(blobId: string, operation: 'upload' | 'delete', data?: Uint8Array): void;
|
|
21
|
+
claimBatch(limit: number): SyncQueueItem[];
|
|
22
|
+
complete(id: number): void;
|
|
23
|
+
fail(id: number, error: string): void;
|
|
24
|
+
permanentFail(id: number, error: string): void;
|
|
25
|
+
releaseStale(olderThanSeconds: number): number;
|
|
26
|
+
pendingCount(): number;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=sync-queue-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-queue-repo.d.ts","sourceRoot":"","sources":["../../storage/sync-queue-repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgCtE;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA0B;IACpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0B;IAC5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;gBAE/C,EAAE,EAAE,aAAa,CAAC,QAAQ;IAwDtC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI;IAOhF,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE;IAK1C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI1B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI9C,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM;IAK9C,YAAY,IAAI,MAAM;CAIvB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
function rowToItem(row) {
|
|
2
|
+
return {
|
|
3
|
+
id: row.id,
|
|
4
|
+
blobId: row.blob_id,
|
|
5
|
+
operation: row.operation,
|
|
6
|
+
data: row.data ? new Uint8Array(row.data) : null,
|
|
7
|
+
retryCount: row.retry_count,
|
|
8
|
+
maxRetries: row.max_retries,
|
|
9
|
+
lastAttempt: row.last_attempt ?? undefined,
|
|
10
|
+
nextAttempt: row.next_attempt ?? undefined,
|
|
11
|
+
errorMessage: row.error_message ?? undefined,
|
|
12
|
+
status: row.status,
|
|
13
|
+
createdAt: row.created_at,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* SQLite-backed sync queue for uploads and deletes.
|
|
18
|
+
*
|
|
19
|
+
* Multi-process safe: uses atomic UPDATE...RETURNING for claim,
|
|
20
|
+
* so concurrent processes never double-process an item.
|
|
21
|
+
*/
|
|
22
|
+
export class SyncQueueRepository {
|
|
23
|
+
db;
|
|
24
|
+
enqueueStmt;
|
|
25
|
+
deleteExistingPendingStmt;
|
|
26
|
+
claimStmt;
|
|
27
|
+
completeStmt;
|
|
28
|
+
failStmt;
|
|
29
|
+
permanentFailStmt;
|
|
30
|
+
releaseStaleStmt;
|
|
31
|
+
pendingCountStmt;
|
|
32
|
+
constructor(db) {
|
|
33
|
+
this.db = db;
|
|
34
|
+
this.enqueueStmt = db.prepare(`
|
|
35
|
+
INSERT INTO sync_queue (blob_id, operation, data, status)
|
|
36
|
+
VALUES (?, ?, ?, 'pending')
|
|
37
|
+
`);
|
|
38
|
+
this.deleteExistingPendingStmt = db.prepare(`
|
|
39
|
+
DELETE FROM sync_queue
|
|
40
|
+
WHERE blob_id = ? AND operation = ? AND status = 'pending'
|
|
41
|
+
`);
|
|
42
|
+
this.claimStmt = db.prepare(`
|
|
43
|
+
UPDATE sync_queue
|
|
44
|
+
SET status = 'processing', last_attempt = datetime('now')
|
|
45
|
+
WHERE id IN (
|
|
46
|
+
SELECT id FROM sync_queue
|
|
47
|
+
WHERE status = 'pending'
|
|
48
|
+
AND (next_attempt IS NULL OR next_attempt <= datetime('now'))
|
|
49
|
+
ORDER BY created_at ASC
|
|
50
|
+
LIMIT ?
|
|
51
|
+
)
|
|
52
|
+
RETURNING *
|
|
53
|
+
`);
|
|
54
|
+
this.completeStmt = db.prepare('DELETE FROM sync_queue WHERE id = ?');
|
|
55
|
+
this.failStmt = db.prepare(`
|
|
56
|
+
UPDATE sync_queue
|
|
57
|
+
SET status = 'pending',
|
|
58
|
+
retry_count = retry_count + 1,
|
|
59
|
+
error_message = ?,
|
|
60
|
+
next_attempt = datetime('now', '+' || (1 << MIN(retry_count, 10)) || ' seconds')
|
|
61
|
+
WHERE id = ?
|
|
62
|
+
`);
|
|
63
|
+
this.permanentFailStmt = db.prepare(`
|
|
64
|
+
UPDATE sync_queue
|
|
65
|
+
SET status = 'failed', error_message = ?
|
|
66
|
+
WHERE id = ?
|
|
67
|
+
`);
|
|
68
|
+
this.releaseStaleStmt = db.prepare(`
|
|
69
|
+
UPDATE sync_queue
|
|
70
|
+
SET status = 'pending', next_attempt = NULL
|
|
71
|
+
WHERE status = 'processing'
|
|
72
|
+
AND last_attempt < datetime('now', '-' || ? || ' seconds')
|
|
73
|
+
`);
|
|
74
|
+
this.pendingCountStmt = db.prepare(`
|
|
75
|
+
SELECT COUNT(*) as count FROM sync_queue
|
|
76
|
+
WHERE status IN ('pending', 'processing')
|
|
77
|
+
`);
|
|
78
|
+
}
|
|
79
|
+
enqueue(blobId, operation, data) {
|
|
80
|
+
this.db.transaction(() => {
|
|
81
|
+
this.deleteExistingPendingStmt.run(blobId, operation);
|
|
82
|
+
this.enqueueStmt.run(blobId, operation, data ? Buffer.from(data) : null);
|
|
83
|
+
})();
|
|
84
|
+
}
|
|
85
|
+
claimBatch(limit) {
|
|
86
|
+
const rows = this.claimStmt.all(limit);
|
|
87
|
+
return rows.map(rowToItem);
|
|
88
|
+
}
|
|
89
|
+
complete(id) {
|
|
90
|
+
this.completeStmt.run(id);
|
|
91
|
+
}
|
|
92
|
+
fail(id, error) {
|
|
93
|
+
this.failStmt.run(error, id);
|
|
94
|
+
}
|
|
95
|
+
permanentFail(id, error) {
|
|
96
|
+
this.permanentFailStmt.run(error, id);
|
|
97
|
+
}
|
|
98
|
+
releaseStale(olderThanSeconds) {
|
|
99
|
+
const result = this.releaseStaleStmt.run(olderThanSeconds);
|
|
100
|
+
return result.changes;
|
|
101
|
+
}
|
|
102
|
+
pendingCount() {
|
|
103
|
+
const row = this.pendingCountStmt.get();
|
|
104
|
+
return row.count;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=sync-queue-repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-queue-repo.js","sourceRoot":"","sources":["../../storage/sync-queue-repo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
import type { ISyncSequenceRepository } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite-backed atomic sequence counter.
|
|
5
|
+
*
|
|
6
|
+
* Uses UPDATE...RETURNING for atomic increment. SQLite's write
|
|
7
|
+
* serialization (WAL mode + busy_timeout) ensures that concurrent
|
|
8
|
+
* processes never produce duplicate sequence numbers.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SyncSequenceRepository implements ISyncSequenceRepository {
|
|
11
|
+
private readonly nextStmt;
|
|
12
|
+
private readonly peekStmt;
|
|
13
|
+
constructor(db: BetterSqlite3.Database);
|
|
14
|
+
next(): number;
|
|
15
|
+
peek(): number;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=sync-sequence-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-sequence-repo.d.ts","sourceRoot":"","sources":["../../storage/sync-sequence-repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,uBAAuB;IACpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;gBAEvC,EAAE,EAAE,aAAa,CAAC,QAAQ;IAOtC,IAAI,IAAI,MAAM;IAKd,IAAI,IAAI,MAAM;CAIf"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed atomic sequence counter.
|
|
3
|
+
*
|
|
4
|
+
* Uses UPDATE...RETURNING for atomic increment. SQLite's write
|
|
5
|
+
* serialization (WAL mode + busy_timeout) ensures that concurrent
|
|
6
|
+
* processes never produce duplicate sequence numbers.
|
|
7
|
+
*/
|
|
8
|
+
export class SyncSequenceRepository {
|
|
9
|
+
nextStmt;
|
|
10
|
+
peekStmt;
|
|
11
|
+
constructor(db) {
|
|
12
|
+
this.nextStmt = db.prepare('UPDATE sync_sequence SET value = value + 1 WHERE id = 1 RETURNING value');
|
|
13
|
+
this.peekStmt = db.prepare('SELECT value FROM sync_sequence WHERE id = 1');
|
|
14
|
+
}
|
|
15
|
+
next() {
|
|
16
|
+
const row = this.nextStmt.get();
|
|
17
|
+
return row.value;
|
|
18
|
+
}
|
|
19
|
+
peek() {
|
|
20
|
+
const row = this.peekStmt.get();
|
|
21
|
+
return row.value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=sync-sequence-repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-sequence-repo.js","sourceRoot":"","sources":["../../storage/sync-sequence-repo.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,OAAO,sBAAsB;IAChB,QAAQ,CAA0B;IAClC,QAAQ,CAA0B;IAEnD,YAAY,EAA0B;QACpC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CACxB,yEAAyE,CAC1E,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAuB,CAAC;QACrD,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAuB,CAAC;QACrD,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
import type { ISyncStateRepository } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite-backed key-value store for sync state.
|
|
5
|
+
* Replaces ~/.chaoskb/sync-state.json with multi-process safe storage.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SyncStateRepository implements ISyncStateRepository {
|
|
8
|
+
private readonly getStmt;
|
|
9
|
+
private readonly setStmt;
|
|
10
|
+
private readonly deleteStmt;
|
|
11
|
+
constructor(db: BetterSqlite3.Database);
|
|
12
|
+
get(key: string): string | undefined;
|
|
13
|
+
set(key: string, value: string): void;
|
|
14
|
+
delete(key: string): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=sync-state-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-state-repo.d.ts","sourceRoot":"","sources":["../../storage/sync-state-repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0B;gBAEzC,EAAE,EAAE,aAAa,CAAC,QAAQ;IAMtC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed key-value store for sync state.
|
|
3
|
+
* Replaces ~/.chaoskb/sync-state.json with multi-process safe storage.
|
|
4
|
+
*/
|
|
5
|
+
export class SyncStateRepository {
|
|
6
|
+
getStmt;
|
|
7
|
+
setStmt;
|
|
8
|
+
deleteStmt;
|
|
9
|
+
constructor(db) {
|
|
10
|
+
this.getStmt = db.prepare('SELECT value FROM sync_state WHERE key = ?');
|
|
11
|
+
this.setStmt = db.prepare('INSERT OR REPLACE INTO sync_state (key, value) VALUES (?, ?)');
|
|
12
|
+
this.deleteStmt = db.prepare('DELETE FROM sync_state WHERE key = ?');
|
|
13
|
+
}
|
|
14
|
+
get(key) {
|
|
15
|
+
const row = this.getStmt.get(key);
|
|
16
|
+
return row?.value;
|
|
17
|
+
}
|
|
18
|
+
set(key, value) {
|
|
19
|
+
this.setStmt.run(key, value);
|
|
20
|
+
}
|
|
21
|
+
delete(key) {
|
|
22
|
+
this.deleteStmt.run(key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=sync-state-repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-state-repo.js","sourceRoot":"","sources":["../../storage/sync-state-repo.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACb,OAAO,CAA0B;IACjC,OAAO,CAA0B;IACjC,UAAU,CAA0B;IAErD,YAAY,EAA0B;QACpC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC;QAC1F,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IACvE,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAkC,CAAC;QACnE,OAAO,GAAG,EAAE,KAAK,CAAC;IACpB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/storage/types.d.ts
CHANGED
|
@@ -130,12 +130,63 @@ export interface IDatabaseManager {
|
|
|
130
130
|
/** Close all open databases */
|
|
131
131
|
closeAll(): void;
|
|
132
132
|
}
|
|
133
|
+
/** Sync queue item */
|
|
134
|
+
export interface SyncQueueItem {
|
|
135
|
+
id: number;
|
|
136
|
+
blobId: string;
|
|
137
|
+
operation: 'upload' | 'delete';
|
|
138
|
+
data: Uint8Array | null;
|
|
139
|
+
retryCount: number;
|
|
140
|
+
maxRetries: number;
|
|
141
|
+
lastAttempt?: string;
|
|
142
|
+
nextAttempt?: string;
|
|
143
|
+
errorMessage?: string;
|
|
144
|
+
status: 'pending' | 'processing' | 'failed' | 'completed';
|
|
145
|
+
createdAt: string;
|
|
146
|
+
}
|
|
147
|
+
/** Sync queue repository — SQLite-backed, multi-process safe */
|
|
148
|
+
export interface ISyncQueueRepository {
|
|
149
|
+
/** Enqueue an upload or delete. Replaces existing pending entry for same blob+operation. */
|
|
150
|
+
enqueue(blobId: string, operation: 'upload' | 'delete', data?: Uint8Array): void;
|
|
151
|
+
/** Atomically claim pending items for processing. Each item is claimed by exactly one process. */
|
|
152
|
+
claimBatch(limit: number): SyncQueueItem[];
|
|
153
|
+
/** Mark an item as completed (deletes from queue). */
|
|
154
|
+
complete(id: number): void;
|
|
155
|
+
/** Mark an item as failed with error, increment retry count, set exponential backoff. */
|
|
156
|
+
fail(id: number, error: string): void;
|
|
157
|
+
/** Mark an item as permanently failed (exceeded max retries). */
|
|
158
|
+
permanentFail(id: number, error: string): void;
|
|
159
|
+
/** Release stale 'processing' items back to 'pending' (crash recovery). */
|
|
160
|
+
releaseStale(olderThanSeconds: number): number;
|
|
161
|
+
/** Count of pending + processing items. */
|
|
162
|
+
pendingCount(): number;
|
|
163
|
+
}
|
|
164
|
+
/** Atomic sequence counter — SQLite-backed, multi-process safe */
|
|
165
|
+
export interface ISyncSequenceRepository {
|
|
166
|
+
/** Atomically increment and return the new value. */
|
|
167
|
+
next(): number;
|
|
168
|
+
/** Get current value without incrementing. */
|
|
169
|
+
peek(): number;
|
|
170
|
+
}
|
|
171
|
+
/** Key-value sync state store — SQLite-backed */
|
|
172
|
+
export interface ISyncStateRepository {
|
|
173
|
+
get(key: string): string | undefined;
|
|
174
|
+
set(key: string, value: string): void;
|
|
175
|
+
delete(key: string): void;
|
|
176
|
+
}
|
|
133
177
|
/** Combined database interface */
|
|
134
178
|
export interface IDatabase {
|
|
135
179
|
readonly sources: ISourceRepository;
|
|
136
180
|
readonly chunks: IChunkRepository;
|
|
137
181
|
readonly syncStatus: ISyncStatusRepository;
|
|
138
182
|
readonly embeddingIndex: IEmbeddingIndex;
|
|
183
|
+
readonly syncQueue: ISyncQueueRepository;
|
|
184
|
+
readonly syncSequence: ISyncSequenceRepository;
|
|
185
|
+
readonly syncState: ISyncStateRepository;
|
|
186
|
+
/** Enqueue an encrypted blob for upload. Sets sync status to local_only. */
|
|
187
|
+
storeAndEnqueueUpload(blobId: string, encryptedBytes: Uint8Array): void;
|
|
188
|
+
/** Enqueue a blob for deletion from the sync server. Sets sync status to pending_delete. */
|
|
189
|
+
enqueueDelete(blobId: string): void;
|
|
139
190
|
close(): void;
|
|
140
191
|
}
|
|
141
192
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../storage/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../storage/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SyncConfig } from './types.js';
|
|
2
|
+
import type { ISyncSequenceRepository } from '../storage/types.js';
|
|
3
|
+
import { SyncHttpClient } from './http-client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create a SyncHttpClient from explicit config.
|
|
6
|
+
*
|
|
7
|
+
* Requires a DB-backed ISyncSequenceRepository to prevent
|
|
8
|
+
* sequence counter drift between SQLite and legacy flat files.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createSyncHttpClientFromConfig(config: SyncConfig, sequence: ISyncSequenceRepository): SyncHttpClient;
|
|
11
|
+
/**
|
|
12
|
+
* Create a SyncHttpClient by loading config from disk.
|
|
13
|
+
*
|
|
14
|
+
* Opens the personal database to use the SQLite-backed sequence counter,
|
|
15
|
+
* ensuring all code paths share the same counter and avoiding drift.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createSyncHttpClient(): Promise<{
|
|
18
|
+
client: SyncHttpClient;
|
|
19
|
+
config: SyncConfig;
|
|
20
|
+
}>;
|
|
21
|
+
//# sourceMappingURL=client-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-factory.d.ts","sourceRoot":"","sources":["../../sync/client-factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,uBAAuB,GAChC,cAAc,CAGhB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC;IACpD,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC,CAkBD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { SSHSigner } from './ssh-signer.js';
|
|
4
|
+
import { SyncHttpClient } from './http-client.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a SyncHttpClient from explicit config.
|
|
7
|
+
*
|
|
8
|
+
* Requires a DB-backed ISyncSequenceRepository to prevent
|
|
9
|
+
* sequence counter drift between SQLite and legacy flat files.
|
|
10
|
+
*/
|
|
11
|
+
export function createSyncHttpClientFromConfig(config, sequence) {
|
|
12
|
+
const signer = new SSHSigner(config.sshKeyPath);
|
|
13
|
+
return new SyncHttpClient(config, signer, sequence);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a SyncHttpClient by loading config from disk.
|
|
17
|
+
*
|
|
18
|
+
* Opens the personal database to use the SQLite-backed sequence counter,
|
|
19
|
+
* ensuring all code paths share the same counter and avoiding drift.
|
|
20
|
+
*/
|
|
21
|
+
export async function createSyncHttpClient() {
|
|
22
|
+
const { loadConfig } = await import('../cli/commands/setup.js');
|
|
23
|
+
const config = await loadConfig();
|
|
24
|
+
if (!config?.endpoint) {
|
|
25
|
+
throw new Error('Sync is not configured. Run `chaoskb-mcp setup-sync` first.');
|
|
26
|
+
}
|
|
27
|
+
const endpoint = config.endpoint;
|
|
28
|
+
const sshKeyPath = config.sshKeyPath ?? join(homedir(), '.ssh', 'id_ed25519');
|
|
29
|
+
const syncConfig = { endpoint, sshKeyPath };
|
|
30
|
+
const { DatabaseManager } = await import('../storage/database-manager.js');
|
|
31
|
+
const dbManager = new DatabaseManager();
|
|
32
|
+
const db = dbManager.getPersonalDb();
|
|
33
|
+
const client = createSyncHttpClientFromConfig(syncConfig, db.syncSequence);
|
|
34
|
+
return { client, config: syncConfig };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=client-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-factory.js","sourceRoot":"","sources":["../../sync/client-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAkB,EAClB,QAAiC;IAEjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IAIxC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAExD,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;IACxC,MAAM,EAAE,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,8BAA8B,CAAC,UAAU,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC;IAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ISyncHttpClient } from './types.js';
|
|
2
2
|
import type { SyncConfig } from './types.js';
|
|
3
3
|
import type { SSHSigner } from './ssh-signer.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { ISyncSequenceRepository } from '../storage/types.js';
|
|
5
5
|
/** Error that indicates the request can be retried after a delay. */
|
|
6
6
|
export declare class RetryableError extends Error {
|
|
7
7
|
/** Seconds to wait before retrying */
|
|
@@ -18,7 +18,7 @@ export declare class SyncHttpClient implements ISyncHttpClient {
|
|
|
18
18
|
private readonly baseUrl;
|
|
19
19
|
private readonly signer;
|
|
20
20
|
private readonly sequence;
|
|
21
|
-
constructor(config: SyncConfig, signer: SSHSigner, sequence
|
|
21
|
+
constructor(config: SyncConfig, signer: SSHSigner, sequence: ISyncSequenceRepository);
|
|
22
22
|
get(path: string): Promise<Response>;
|
|
23
23
|
put(path: string, body: Uint8Array): Promise<Response>;
|
|
24
24
|
delete(path: string): Promise<Response>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../sync/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../sync/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,qEAAqE;AACrE,qBAAa,cAAe,SAAQ,KAAK;IACvC,sCAAsC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;CAKvD;AAKD;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;gBAEvC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,uBAAuB;IAY9E,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIpC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAItD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIvC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;YAIhD,OAAO;CAiEtB"}
|